File size: 1,600 Bytes
04fb378 041c1c7 04fb378 041c1c7 04fb378 041c1c7 04fb378 041c1c7 04fb378 041c1c7 04fb378 041c1c7 04fb378 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | """Shared outbound HTTP client factory.
Deliberately plain: the default dual-stack resolver and a moderate timeout.
History: v3.8.2 pinned outbound sockets to IPv4 (local_address="0.0.0.0") to
chase a suspected IPv6 routing problem. Analytics writes had been succeeding
before that change and stopped after it, so the pin is reverted. Forcing a
local address can break egress in containerised hosts, and the original
diagnosis was not supported by evidence: a 12s GET failed while an 8s POST to
the same host succeeded, which rules out plain slowness.
Set FORCE_IPV4_LOCAL_ADDRESS to "0.0.0.0" only to test that hypothesis again.
"""
import logging
from typing import Optional
import httpx
logger = logging.getLogger(__name__)
# None = let the OS choose (normal dual-stack behaviour). "0.0.0.0" forces IPv4.
FORCE_IPV4_LOCAL_ADDRESS: Optional[str] = None
DEFAULT_TIMEOUT = 10.0
def make_transport(retries: int = 1) -> httpx.AsyncHTTPTransport:
kwargs = {"retries": retries}
if FORCE_IPV4_LOCAL_ADDRESS:
kwargs["local_address"] = FORCE_IPV4_LOCAL_ADDRESS
try:
return httpx.AsyncHTTPTransport(**kwargs)
except Exception as exc:
logger.warning(f"Custom transport unavailable ({exc}); using default")
return httpx.AsyncHTTPTransport()
def make_client(timeout: float = DEFAULT_TIMEOUT, retries: int = 1) -> httpx.AsyncClient:
"""AsyncClient with a moderate timeout and one transport-level retry."""
return httpx.AsyncClient(
timeout=timeout,
transport=make_transport(retries=retries),
follow_redirects=True,
)
|