from collections.abc import Mapping from typing import Any from ..api_config import APIConfigError, APIEndpointRegistry from ..request import APIClient from .base import EndpointAdapter from .jx3api import JX3ApiAdapter from .jx3box import JX3BoxAdapter class APIAdapterRouter: """依据服务配置把端点请求路由到对应 Adapter。""" def __init__( self, client: APIClient, registry: APIEndpointRegistry, *, jx3api_token: str = "", jx3api_ticket: str = "", ): self._registry = registry self._adapters: dict[str, EndpointAdapter] = { "generic": EndpointAdapter(client, registry), "jx3api": JX3ApiAdapter( client, registry, token=jx3api_token, ticket=jx3api_ticket, ), "jx3box": JX3BoxAdapter(client, registry), } def get_adapter(self, endpoint_name: str) -> EndpointAdapter: adapter_name = self._resolve_adapter_name(endpoint_name) try: return self._adapters[adapter_name] except KeyError as exc: raise APIConfigError( f"端点引用了不支持的 Adapter: {endpoint_name} -> {adapter_name}" ) from exc async def request( self, endpoint_name: str, *, params: Mapping[str, Any] | None = None, out_key: str | None = "data", path_params: Mapping[str, Any] | None = None, ) -> Any: adapter = self.get_adapter(endpoint_name) return await adapter.request( endpoint_name, params=params, out_key=out_key, path_params=path_params, ) async def request_all_pages( self, endpoint_name: str, **kwargs, ) -> list[Any]: adapter = self.get_adapter(endpoint_name) if not isinstance(adapter, JX3BoxAdapter): raise APIConfigError( f"端点不属于 JX3BOX,不能使用 JX3BOX 分页规则: {endpoint_name}" ) return await adapter.request_all_pages(endpoint_name, **kwargs) def _resolve_adapter_name(self, endpoint_name: str) -> str: endpoint = self._registry.get(endpoint_name) service = self._registry.get_service(str(endpoint["service"])) return str(service.get("adapter", "generic")).lower()