Source code for veupath_chatbot.transport.http.routers.sites.catalog
"""Site listing, record types, and search catalog endpoints."""
from typing import Annotated
from fastapi import APIRouter, Query
from veupath_chatbot.platform.types import JSONValue
from veupath_chatbot.services import catalog
from veupath_chatbot.services.wdk import get_discovery_service
from veupath_chatbot.transport.http.schemas import (
RecordTypeResponse,
SearchResponse,
SiteResponse,
)
router = APIRouter(prefix="/api/v1/sites", tags=["sites"])
[docs]
@router.get("", response_model=list[SiteResponse])
async def list_sites() -> list[SiteResponse]:
"""List all available VEuPathDB sites."""
sites = await catalog.list_sites()
return [SiteResponse.model_validate(s) for s in sites if isinstance(s, dict)]
[docs]
@router.get("/{siteId}/record-types", response_model=list[RecordTypeResponse])
async def get_record_types(siteId: str) -> list[RecordTypeResponse]:
"""Get record types available on a site."""
record_types = await catalog.get_record_types(siteId)
return [
RecordTypeResponse.model_validate(rt)
for rt in record_types
if isinstance(rt, dict)
]
[docs]
@router.get("/{siteId}/searches", response_model=list[SearchResponse])
async def get_searches(
siteId: str,
record_type: Annotated[str | None, Query(alias="recordType")] = None,
) -> list[SearchResponse]:
"""Get searches available on a site, optionally filtered by record type."""
if record_type:
searches = await catalog.list_searches(siteId, record_type)
return [
SearchResponse.model_validate({**s, "recordType": record_type})
for s in searches
if isinstance(s, dict)
]
discovery = get_discovery_service()
record_types = await discovery.get_record_types(siteId)
all_searches: list[SearchResponse] = []
for rt in record_types:
if not isinstance(rt, dict):
continue
rt_url_seg_raw: JSONValue | None = rt.get("urlSegment")
rt_name_raw: JSONValue | None = rt.get("name")
url_seg = rt_url_seg_raw if isinstance(rt_url_seg_raw, str) else None
name = rt_name_raw if isinstance(rt_name_raw, str) else None
rt_name = url_seg or name or ""
if rt_name:
searches = await catalog.list_searches(siteId, rt_name)
all_searches.extend(
SearchResponse.model_validate({**s, "recordType": rt_name})
for s in searches
if isinstance(s, dict)
)
return all_searches