from __future__ import annotations import httpx _client: httpx.AsyncClient | None = None async def init_http_client() -> None: global _client _client = httpx.AsyncClient( timeout=httpx.Timeout(20.0, connect=5.0), follow_redirects=True, limits=httpx.Limits(max_connections=40, max_keepalive_connections=20), ) async def close_http_client() -> None: global _client if _client is not None: await _client.aclose() _client = None def get_client() -> httpx.AsyncClient: if _client is None: raise RuntimeError("HTTP client not initialized") return _client async def fetch_json(url: str, params: dict | None = None, timeout: float | None = None) -> dict: client = get_client() response = await client.get(url, params=params, timeout=timeout) response.raise_for_status() return response.json() async def fetch_text(url: str, timeout: float | None = None) -> str: client = get_client() response = await client.get(url, timeout=timeout) response.raise_for_status() return response.text