from __future__ import annotations import json from pathlib import Path import httpx class OflClient: search_url = "https://open-fixture-library.org/api/v1/get-search-results" fixture_base = "https://open-fixture-library.org" async def search(self, query: str) -> list[dict[str, object]]: fallback = self._search_local(query) try: async with httpx.AsyncClient(timeout=6.0) as client: response = await client.post( self.search_url, json={ "searchQuery": query, "manufacturersQuery": [], "categoriesQuery": [], }, ) response.raise_for_status() keys = response.json() return [{"fixture_key": key, "cached": False} for key in keys] except Exception: return fallback async def fetch_fixture(self, manufacturer_key: str, fixture_key: str) -> dict[str, object]: local_path = Path("test-data/fixtures") / f"{manufacturer_key}__{fixture_key}.json" if local_path.exists(): return json.loads(local_path.read_text(encoding="utf-8")) url = f"{self.fixture_base}/{manufacturer_key}/{fixture_key}.json" async with httpx.AsyncClient(timeout=10.0) as client: response = await client.get(url) response.raise_for_status() return response.json() def _search_local(self, query: str) -> list[dict[str, object]]: results: list[dict[str, object]] = [] lowered = query.lower() for path in Path("test-data/fixtures").glob("*.json"): if lowered in path.stem.lower(): results.append({"fixture_key": path.stem.replace("__", "/"), "cached": True}) return results