Exponential backoff, respect Retry-After headers, and circuit breakers for resilient API clients.
Retry and Resilience
from tenacity import retry, stop_after_attempt, wait_exponential
import httpx, time
@retry(stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1,min=1,max=10))
def call_api(url: str) -> dict:
response = httpx.get(url, timeout=5.0)
response.raise_for_status()
return response.json()
# Manual retry with Retry-After
def resilient_get(url, max_retries=3):
for i in range(max_retries):
resp = httpx.get(url, timeout=5.0)
if resp.status_code == 429:
time.sleep(int(resp.headers.get("Retry-After",60)))
continue
resp.raise_for_status()
return resp.json()
# Always use jitter to avoid thundering herd