Skip to content

HTTPX — Modern Python HTTP Client

Async-capable HTTP client with full sync support. Drop-in requests replacement with HTTP/2, type hints, and granular timeouts.

Installation

uv add httpx
uv add httpx[http2]   # enable HTTP/2 support

When to Use What

Library Best for
requests Scripts, CLI tools, simple sync calls
httpx FastAPI test clients, async apps, HTTP/2, high-concurrency
aiohttp WebSocket clients, custom event loops, async-first legacy

Section Map

File Topics
01 Fundamentals Client, methods, params, headers, cookies, response, errors
02 Async Patterns AsyncClient, concurrency, streaming, event hooks
03 Advanced Config Timeouts, retries, proxy, auth, HTTP/2, SSL, pool limits, FastAPI testing

Cheat Sheet

HTTP Methods

import httpx

# one-off requests (new connection each time — prefer Client for multiple)
r = httpx.get(url, params={"q": "test"}, timeout=10)
r = httpx.post(url, json={"name": "Alice"}, timeout=10)
r = httpx.put(url, json=data, timeout=10)
r = httpx.patch(url, json=partial, timeout=10)
r = httpx.delete(url, timeout=10)

Client (Connection Pooling)

import httpx

# sync client — reuses TCP connections, shares headers
with httpx.Client(base_url="https://api.example.com", timeout=10) as client:
    client.headers["Authorization"] = f"Bearer {token}"
    users = client.get("/users").raise_for_status().json()
    client.post("/users", json={"name": "Bob"}).raise_for_status()

Async Client

import httpx

async with httpx.AsyncClient(base_url="https://api.example.com", timeout=10) as client:
    resp = await client.get("/users")
    resp.raise_for_status()
    users = resp.json()

Response Object

Attribute Returns
r.status_code 200, 404, 500
r.json() Parsed JSON
r.text Body as str
r.content Body as bytes
r.headers Case-insensitive dict
r.cookies Response cookies
r.url Final URL after redirects
r.elapsed Round-trip timedelta
r.http_version "HTTP/1.1" or "HTTP/2"
r.raise_for_status() Raises HTTPStatusError on 4xx/5xx
r.is_success True if 2xx
r.is_redirect True if 3xx

Timeout (Granular)

# separate connect / read / write / pool timeouts
timeout = httpx.Timeout(10.0, connect=5.0)
client = httpx.Client(timeout=timeout)

Quick Rules

  1. Use Client / AsyncClient — connection pooling, shared config.
  2. Always set timeout — httpx defaults to 5s, but be explicit.
  3. Use json= instead of manual serialization.
  4. Call raise_for_status() — fail fast on errors.
  5. Prefer async for I/O-bound workloadsAsyncClient + asyncio.gather.
  6. Enable HTTP/2 where supported — httpx.Client(http2=True).
  7. Use event hooks for logging/metrics — not manual wrappers.

See also