"""Shared `httpx.Client` helper. Creating short-lived httpx clients disables connection pooling and costs extra CPU. This module provides a small singleton client for callers that just need basic GETs without the full HTTPClient wrapper. """ from __future__ import annotations import threading from typing import Dict, Optional import httpx from API.ssl_certs import resolve_verify_value _DEFAULT_USER_AGENT = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0 Safari/537.36" ) _lock = threading.Lock() _shared_client: Optional[httpx.Client] = None def get_shared_httpx_client( *, timeout: float = 30.0, verify_ssl: bool = True, headers: Optional[Dict[str, str]] = None, ) -> httpx.Client: """Return a process-wide shared synchronous httpx.Client.""" global _shared_client if _shared_client is None: with _lock: if _shared_client is None: base_headers = {"User-Agent": _DEFAULT_USER_AGENT} if headers: base_headers.update({str(k): str(v) for k, v in headers.items()}) _shared_client = httpx.Client( timeout=timeout, verify=resolve_verify_value(verify_ssl), headers=base_headers, ) return _shared_client def close_shared_httpx_client() -> None: global _shared_client client = _shared_client _shared_client = None if client is not None: try: client.close() except Exception: pass