httpx
raw JSON → 0.28.1 verified Tue May 12 auth: no python install: verified quickstart: verified
Fully featured next-generation HTTP client for Python 3. Provides both synchronous and asynchronous APIs with HTTP/1.1 and HTTP/2 support. Current version is 0.28.1 (December 2024). Pre-1.0: minor version bumps may introduce breaking changes.
pip install httpx Common errors
error ModuleNotFoundError: No module named 'httpx' ↓
cause The 'httpx' library is not installed in your current Python environment.
fix
Install the library using pip:
pip install httpx error TypeError: AsyncClient.__init__() got an unexpected keyword argument 'proxies' ↓
cause In `httpx` versions 0.28.0 and later, the `proxies` argument was removed from `AsyncClient`'s constructor, leading to this error if older code or dependent libraries (e.g., `openai`) still try to pass it.
fix
Upgrade the dependent library to a version compatible with
httpx 0.28.x, or configure proxies using environment variables (HTTP_PROXY, HTTPS_PROXY), or downgrade httpx to a version prior to 0.28.0, such as pip install httpx==0.27.2. error RuntimeError: Attempted to send an sync request with an AsyncClient instance. ↓
cause You are trying to call a synchronous request method (e.g., `client.get()`) on an `httpx.AsyncClient` instance without awaiting it, or within a synchronous context.
fix
Ensure that all calls to
AsyncClient methods are awaited and that the code runs within an async function and an asyncio event loop: async with httpx.AsyncClient() as client: await client.get('https://example.com') error httpx.TimeoutException ↓
cause A network operation (connection, read, or write) took longer than the configured timeout duration.
fix
Increase the timeout value when making the request or initializing the client:
httpx.get('https://example.com', timeout=10.0) or client = httpx.Client(timeout=httpx.Timeout(5.0, connect=10.0, read=20.0)). error httpx.UnsupportedProtocol ↓
cause The URL provided is missing a protocol scheme (like 'http://' or 'https://') or uses a scheme not supported by `httpx`.
fix
Ensure the URL includes a valid scheme:
httpx.get('https://www.example.com/') instead of httpx.get('www.example.com/'). Warnings
breaking proxies= argument was removed in 0.28.0. Using it raises TypeError. ↓
fix Use proxy='http://...' for a single proxy, or mounts={'https://': httpx.HTTPTransport(proxy='...')} for per-scheme configuration.
breaking app= shortcut argument was removed in 0.28.0. It was deprecated in 0.27.0. ↓
fix Use transport=httpx.WSGITransport(app=app) or transport=httpx.ASGITransport(app=app) explicitly.
breaking Redirects are NOT followed by default (changed in 0.20.0). Requests that previously auto-redirected now return the 3xx response directly. ↓
fix Pass follow_redirects=True per-request or at the Client level: httpx.Client(follow_redirects=True).
deprecated verify='path/to/ca-bundle' (string) and cert=('cert', 'key') arguments are deprecated in 0.28.0 and will raise DeprecationWarning. ↓
fix Build an ssl.SSLContext manually and pass it via verify=ssl_context. See https://www.python-httpx.org/advanced/ssl/
gotcha httpx is pre-1.0. Minor version bumps (e.g. 0.27 → 0.28) can and do introduce breaking changes. The maintainers recommend pinning the minor version. ↓
fix Pin with httpx>=0.28.1,<0.29 in requirements. Review the CHANGELOG before upgrading.
gotcha HTTP/2 is disabled by default. Installing httpx alone does not enable it. ↓
fix pip install 'httpx[http2]' then pass http2=True: httpx.Client(http2=True)
gotcha Top-level functions (httpx.get, httpx.post, etc.) open a new TCP connection on every call. For more than one request to the same host this is inefficient. ↓
fix Use httpx.Client() or httpx.AsyncClient() as a context manager for connection pooling, keep-alive, and shared configuration.
Install
pip install 'httpx[http2]' pip install 'httpx[cli]' pip install 'httpx[brotli]' pip install 'httpx[zstd]' Install compatibility verified last tested: 2026-05-12
python os / libc variant status wheel install import disk
3.10 alpine (musl) brotli - - 0.18s 25.7M
3.10 alpine (musl) cli - - 0.46s 34.4M
3.10 alpine (musl) http2 - - 0.18s 23.2M
3.10 alpine (musl) zstd - - 0.19s 36.6M
3.10 alpine (musl) httpx - - 0.18s 21.9M
3.10 slim (glibc) brotli - - 0.14s 27M
3.10 slim (glibc) cli - - 0.40s 35M
3.10 slim (glibc) http2 - - 0.14s 24M
3.10 slim (glibc) zstd - - 0.15s 45M
3.10 slim (glibc) httpx - - 0.14s 22M
3.11 alpine (musl) brotli - - 0.29s 27.9M
3.11 alpine (musl) cli - - 0.56s 37.9M
3.11 alpine (musl) http2 - - 0.30s 25.3M
3.11 alpine (musl) zstd - - 0.31s 38.9M
3.11 alpine (musl) httpx - - 0.30s 24.1M
3.11 slim (glibc) brotli - - 0.25s 30M
3.11 slim (glibc) cli - - 0.47s 38M
3.11 slim (glibc) http2 - - 0.24s 26M
3.11 slim (glibc) zstd - - 0.26s 48M
3.11 slim (glibc) httpx - - 0.26s 25M
3.12 alpine (musl) brotli - - 0.23s 19.6M
3.12 alpine (musl) cli - - 0.46s 29.4M
3.12 alpine (musl) http2 - - 0.23s 17.0M
3.12 alpine (musl) zstd - - 0.23s 30.6M
3.12 alpine (musl) httpx - - 0.23s 15.8M
3.12 slim (glibc) brotli - - 0.25s 21M
3.12 slim (glibc) cli - - 0.50s 30M
3.12 slim (glibc) http2 - - 0.27s 17M
3.12 slim (glibc) zstd - - 0.26s 39M
3.12 slim (glibc) httpx - - 0.24s 16M
3.13 alpine (musl) brotli - - 0.23s 18.9M
3.13 alpine (musl) cli - - 0.45s 28.7M
3.13 alpine (musl) http2 - - 0.22s 16.3M
3.13 alpine (musl) zstd - - 0.23s 29.9M
3.13 alpine (musl) httpx - - 0.23s 15.2M
3.13 slim (glibc) brotli - - 0.23s 21M
3.13 slim (glibc) cli - - 0.48s 29M
3.13 slim (glibc) http2 - - 0.23s 17M
3.13 slim (glibc) zstd - - 0.23s 39M
3.13 slim (glibc) httpx - - 0.23s 16M
3.9 alpine (musl) brotli - - 0.16s 25.0M
3.9 alpine (musl) cli - - 0.33s 33.3M
3.9 alpine (musl) http2 - - 0.16s 22.2M
3.9 alpine (musl) zstd - - 0.18s 35.9M
3.9 alpine (musl) httpx - - 0.16s 21.2M
3.9 slim (glibc) brotli - - 0.14s 27M
3.9 slim (glibc) cli - - 0.30s 34M
3.9 slim (glibc) http2 - - 0.15s 23M
3.9 slim (glibc) zstd - - 0.16s 45M
3.9 slim (glibc) httpx - - 0.16s 22M
Imports
- httpx
import httpx - httpx.Client wrong
client = httpx.Client() r = client.get('https://example.com') # never call client.close() manually forgottencorrectwith httpx.Client() as client: r = client.get('https://example.com') - httpx.AsyncClient wrong
client = httpx.AsyncClient() r = await client.get('https://example.com')correctasync with httpx.AsyncClient() as client: r = await client.get('https://example.com') - httpx.Timeout wrong
httpx.Client(timeout=5)correcthttpx.Client(timeout=httpx.Timeout(5.0, connect=2.0)) - httpx.BasicAuth / httpx.Auth
httpx.Client(auth=('user', 'pass')) # or httpx.Client(auth=httpx.BasicAuth('user', 'pass'))
Quickstart verified last tested: 2026-04-23
import httpx
# One-off request (new connection each time — fine for scripts)
r = httpx.get('https://httpbin.org/get', timeout=10.0)
r.raise_for_status()
print(r.status_code) # 200
print(r.json()) # parsed JSON body
# Recommended: reuse a Client for multiple requests (connection pooling)
with httpx.Client(base_url='https://httpbin.org', timeout=10.0) as client:
resp = client.get('/get', params={'key': 'value'})
resp.raise_for_status()
print(resp.json())
# Async variant
import asyncio
async def main():
async with httpx.AsyncClient(base_url='https://httpbin.org', timeout=10.0) as client:
resp = await client.get('/get')
resp.raise_for_status()
print(resp.json())
asyncio.run(main())