feat: add OpenHerbarium MCP server core
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from .http import BotanicalHTTPClient
|
||||
from .models import evidence
|
||||
|
||||
COMMONS_API = "https://commons.wikimedia.org/w/api.php"
|
||||
COMMONS_SOURCE = "Wikimedia Commons"
|
||||
|
||||
|
||||
class WikimediaClient:
|
||||
def __init__(self, http: BotanicalHTTPClient):
|
||||
self.http = http
|
||||
|
||||
async def image_sources(self, query: str, limit: int = 10) -> list[dict[str, Any]]:
|
||||
data = await self.http.get_json(
|
||||
COMMONS_API,
|
||||
{
|
||||
"action": "query",
|
||||
"format": "json",
|
||||
"generator": "search",
|
||||
"gsrsearch": query,
|
||||
"gsrnamespace": 6,
|
||||
"gsrlimit": min(max(limit, 1), 20),
|
||||
"prop": "imageinfo",
|
||||
"iiprop": "url|extmetadata|user",
|
||||
},
|
||||
)
|
||||
pages = data.get("query", {}).get("pages", {})
|
||||
records: list[dict[str, Any]] = []
|
||||
for page in pages.values() if isinstance(pages, dict) else []:
|
||||
imageinfo = (page.get("imageinfo") or [{}])[0]
|
||||
metadata = imageinfo.get("extmetadata") or {}
|
||||
image_url = imageinfo.get("url") or imageinfo.get("descriptionurl")
|
||||
source_url = imageinfo.get("descriptionurl") or f"https://commons.wikimedia.org/wiki/{page.get('title', '').replace(' ', '_')}"
|
||||
records.append(
|
||||
{
|
||||
"title": page.get("title"),
|
||||
"image_url": evidence(image_url, source=COMMONS_SOURCE, url=source_url, confidence="medium"),
|
||||
"license": evidence(_meta(metadata, "LicenseShortName") or _meta(metadata, "UsageTerms"), source=COMMONS_SOURCE, url=source_url, confidence="medium"),
|
||||
"author": evidence(_meta(metadata, "Artist") or imageinfo.get("user"), source=COMMONS_SOURCE, url=source_url, confidence="medium"),
|
||||
"source": evidence(_meta(metadata, "ObjectName") or page.get("title"), source=COMMONS_SOURCE, url=source_url, confidence="medium"),
|
||||
"raw": {"pageid": page.get("pageid"), "metadata": metadata},
|
||||
}
|
||||
)
|
||||
return records
|
||||
|
||||
|
||||
def _meta(metadata: dict[str, Any], key: str) -> Any:
|
||||
value = metadata.get(key)
|
||||
if isinstance(value, dict):
|
||||
return value.get("value")
|
||||
return value
|
||||
Reference in New Issue
Block a user