"""Shared httpx.AsyncClient for connection reuse and consistent outbound behavior.""" from __future__ import annotations import threading import httpx _DEFAULT_TIMEOUT = 30.0 _client: httpx.AsyncClient | None = None _client_lock = threading.Lock() def get_shared_httpx_client() -> httpx.AsyncClient: """Return a process-wide async HTTP client (lazy singleton).""" global _client # noqa: PLW0603 client = _client if client is not None and not client.is_closed: return client with _client_lock: client = _client if client is None or client.is_closed: client = httpx.AsyncClient(timeout=_DEFAULT_TIMEOUT) _client = client return client async def aclose_shared_httpx_client() -> None: """Close the shared client (call from ASGI shutdown).""" global _client # noqa: PLW0603 with _client_lock: client = _client _client = None if client is not None and not client.is_closed: await client.aclose()