Source code for iiisight.search

"""IIIF Content Search: discover a resource's search service and parse results.

A manifest (or canvas) advertises a Content Search service in its ``service``
block; :func:`find_search_service` locates it. :func:`search_url` builds the
query URL, and :func:`parse_search_response` normalizes the response — a v3
``AnnotationPage`` or a v2 ``sc:AnnotationList`` — into an
:class:`~iiisight.model.AnnotationPage` of hit annotations. ``client.search()``
ties these together.
"""

from collections.abc import Mapping
from typing import Any
from urllib.parse import urlencode

from .errors import UnexpectedDocumentError
from .model import AnnotationPage, Described, Service
from .normalize import parse_annotation_page

_SEARCH_TYPES = {"SearchService2", "SearchService1", "SearchService"}
_SEARCH_PROFILE_HINTS = ("search/2/search", "search/1/search")


[docs] def find_search_service(resource: Described) -> Service | None: """Return the Content Search service on a resource, or ``None``.""" for service in resource.services: if service.type in _SEARCH_TYPES: return service if service.profile and any(hint in service.profile for hint in _SEARCH_PROFILE_HINTS): return service return None
[docs] def search_url( target: Described | Service | str, query: str, params: Mapping[str, Any] | None = None ) -> str: """Build a Content Search query URL for a resource, service, or base URL.""" base = _base_url(target) query_params = {"q": query} if params: query_params.update(params) separator = "&" if "?" in base else "?" return f"{base}{separator}{urlencode(query_params)}"
[docs] def parse_search_response(document: Mapping[str, Any]) -> AnnotationPage: """Parse a Content Search response into an :class:`AnnotationPage` of hits.""" return parse_annotation_page(document)
def _base_url(target: Described | Service | str) -> str: if isinstance(target, str): return target if isinstance(target, Service): return target.id service = find_search_service(target) if service is None: raise UnexpectedDocumentError("no Content Search service found on the resource") return service.id