Spaces:
Running
Running
| from time import perf_counter | |
| import httpx | |
| from app.config import ApiSettings | |
| from app.model_health import get_provider_unavailable | |
| from app.models import ServiceStatus | |
| class ModelClient: | |
| def __init__(self, http: httpx.AsyncClient, settings: ApiSettings): | |
| self.http = http | |
| self.settings = settings | |
| async def status(self) -> ServiceStatus: | |
| primary_unavailable = get_provider_unavailable("primary") | |
| primary = None | |
| if primary_unavailable is None: | |
| primary = await self._provider_status( | |
| base_url=self.settings.primary_model_base_url, | |
| model_name=self.settings.primary_model_name, | |
| api_key=self.settings.primary_model_api_key, | |
| ) | |
| if primary.ok: | |
| return primary | |
| if self.settings.model_fallback_enabled: | |
| fallback = await self._provider_status( | |
| base_url=self.settings.fallback_model_base_url, | |
| model_name=self.settings.fallback_model_name, | |
| api_key=self.settings.fallback_model_api_key, | |
| ) | |
| if fallback.ok: | |
| return fallback | |
| return ServiceStatus( | |
| ok=False, | |
| service="model", | |
| url=self.settings.primary_model_base_url, | |
| error=primary_unavailable.reason | |
| if primary_unavailable is not None | |
| else primary.error | |
| if primary is not None | |
| else "Primary model is unavailable.", | |
| ) | |
| async def is_ready(self) -> bool: | |
| return (await self.status()).ok | |
| async def _provider_status( | |
| self, | |
| *, | |
| base_url: str, | |
| model_name: str, | |
| api_key: str | None, | |
| ) -> ServiceStatus: | |
| started = perf_counter() | |
| if not api_key: | |
| return ServiceStatus( | |
| ok=False, | |
| service="model", | |
| url=base_url, | |
| model=model_name, | |
| error="API key is not configured.", | |
| ) | |
| try: | |
| response = await self.http.get( | |
| f"{base_url}/models", | |
| timeout=20, | |
| headers={"Authorization": f"Bearer {api_key}"}, | |
| ) | |
| response.raise_for_status() | |
| self._verify_model_available(response.json(), model_name) | |
| except Exception as exc: | |
| return ServiceStatus( | |
| ok=False, | |
| service="model", | |
| url=base_url, | |
| model=model_name, | |
| error=str(exc), | |
| ) | |
| return ServiceStatus( | |
| ok=True, | |
| service="model", | |
| url=base_url, | |
| model=model_name, | |
| latency_ms=int((perf_counter() - started) * 1000), | |
| ) | |
| def _verify_model_available(self, payload: object, model_name: str) -> None: | |
| if not isinstance(payload, dict): | |
| return | |
| models = payload.get("data") | |
| if not isinstance(models, list): | |
| return | |
| ids = { | |
| model.get("id") | |
| for model in models | |
| if isinstance(model, dict) and isinstance(model.get("id"), str) | |
| } | |
| if ids and model_name not in ids: | |
| raise ValueError(f"Model {model_name!r} is not listed by provider.") | |