HTTPX
Use when work is primarily outbound HTTP in Python.
Boundary
Use this skill for:
- sync and async HTTP clients
- shared client config
- timeouts, limits, redirects, and connection reuse
- uploads, downloads, and streaming
- auth headers and custom auth flows
- testing HTTP integrations without real network calls
Pair with:
python for general Python conventions and project workflow
security when requests touch auth, secrets, SSRF risk, or untrusted URLs
quality when flaky integrations or retry behavior need tighter guards
Reference Map
references/clients.md -- client lifetime, shared config, auth, limits, transports, and async boundaries
references/requests-and-streaming.md -- request shapes, file transfer, pagination, and streaming patterns
references/testing.md -- MockTransport, dependency injection, fake responses, and integration test boundaries
Assets
assets/client.py -- typed crudcrud.com client example with shared config and explicit CRUD methods
assets/testing.py -- test of same crudcrud.com adapter using MockTransport over real network calls
What Stays Here
Keep this file focused on defaults and guardrails.
- keep here: client lifetime rules, timeout defaults, error handling stance, review cues
- move to refs: long examples, auth variants, streaming details, transports, testing patterns
- use assets when runnable example clearer than another code block
Core Defaults
- prefer shared
httpx.Client or httpx.AsyncClient over top-level helpers when making more than one request
- set explicit timeouts; do not rely on vague defaults
- use
base_url for service clients -- paths stay short, consistent
- one style per call path: sync code with
Client, async code with AsyncClient
- call
raise_for_status() when non-2xx should fail fast
- deserialize at boundary into typed objects, not raw JSON dicts spread through codebase
- keep retry logic outside business code; centralize in one wrapper or adapter
- do not build URLs or query strings with unsafe string concatenation
- do not create new client per request in hot paths
Quick Start
from collections.abc import AsyncIterator
import httpx
def build_client() -> httpx.Client:
return httpx.Client(
base_url="https://api.example.com",
timeout=httpx.Timeout(10.0, connect=3.0),
headers={"User-Agent": "myapp/1.0"},
follow_redirects=True,
)
async def build_async_client() -> AsyncIterator[httpx.AsyncClient]:
async with httpx.AsyncClient(
base_url="https://api.example.com",
timeout=httpx.Timeout(10.0, connect=3.0),
) as client:
yield client
Timeout and Transport Rules
- use
httpx.Timeout(...) when connect, read, or write behavior matters
- use connection limits for high-concurrency clients, not unconstrained fan-out
- custom transports only for testing, in-process apps, or specific integration need
- keep proxy, SSL, and certificate config explicit in one place
For deeper client setup patterns, load references/clients.md.
Error Handling Rules
- catch
httpx.TimeoutException for timeouts
- catch
httpx.HTTPStatusError when server responded with failing status
- catch
httpx.RequestError for network and transport failures
- convert library exceptions into domain-relevant errors at boundary if rest of app should not know about HTTPX
- log request context helpful for debugging; do not log secrets or full sensitive payloads
Guardrails
- validate or normalize untrusted URLs before requesting
- never forward user-supplied headers blindly to upstream
- do not bury
raise_for_status() inside low-level helpers if callers need to branch on specific status codes
- do not mix retry loops, parsing, and domain logic in same function
- do not read large responses fully into memory when streaming more appropriate
- do not patch
httpx.get or httpx.post all over tests; inject clients or transports instead
Review Focus
- check client lifetime clear and reused where appropriate
- check timeouts and redirects explicit enough for use case
- check status handling consistent and intentional
- check auth and headers centralized, not repeated
- check request construction safe from URL or header injection
- check tests isolate network behavior with mock transports or injected clients
1---2name: httpx3description: HTTPX client patterns for Python services, scripts, and applications. Covers client lifetime, sync and async usage, timeouts, streaming, auth, retries, error handling, and testing with mock transports. Load when working with outbound HTTP in Python.4---56# HTTPX78Use when work is primarily outbound HTTP in Python.910## Boundary1112Use this skill for:1314- sync and async HTTP clients15- shared client config16- timeouts, limits, redirects, and connection reuse17- uploads, downloads, and streaming18- auth headers and custom auth flows19- testing HTTP integrations without real network calls2021Pair with:2223- `python` for general Python conventions and project workflow24- `security` when requests touch auth, secrets, SSRF risk, or untrusted URLs25- `quality` when flaky integrations or retry behavior need tighter guards2627## Reference Map2829- `references/clients.md` -- client lifetime, shared config, auth, limits, transports, and async boundaries30- `references/requests-and-streaming.md` -- request shapes, file transfer, pagination, and streaming patterns31- `references/testing.md` -- `MockTransport`, dependency injection, fake responses, and integration test boundaries3233## Assets3435- `assets/client.py` -- typed `crudcrud.com` client example with shared config and explicit CRUD methods36- `assets/testing.py` -- test of same `crudcrud.com` adapter using `MockTransport` over real network calls3738## What Stays Here3940Keep this file focused on defaults and guardrails.4142- keep here: client lifetime rules, timeout defaults, error handling stance, review cues43- move to refs: long examples, auth variants, streaming details, transports, testing patterns44- use assets when runnable example clearer than another code block4546## Core Defaults4748- prefer shared `httpx.Client` or `httpx.AsyncClient` over top-level helpers when making more than one request49- set explicit timeouts; do not rely on vague defaults50- use `base_url` for service clients -- paths stay short, consistent51- one style per call path: sync code with `Client`, async code with `AsyncClient`52- call `raise_for_status()` when non-2xx should fail fast53- deserialize at boundary into typed objects, not raw JSON dicts spread through codebase54- keep retry logic outside business code; centralize in one wrapper or adapter55- do not build URLs or query strings with unsafe string concatenation56- do not create new client per request in hot paths5758## Quick Start5960```python61from collections.abc import AsyncIterator6263import httpx646566def build_client() -> httpx.Client:67 return httpx.Client(68 base_url="https://api.example.com",69 timeout=httpx.Timeout(10.0, connect=3.0),70 headers={"User-Agent": "myapp/1.0"},71 follow_redirects=True,72 )737475async def build_async_client() -> AsyncIterator[httpx.AsyncClient]:76 async with httpx.AsyncClient(77 base_url="https://api.example.com",78 timeout=httpx.Timeout(10.0, connect=3.0),79 ) as client:80 yield client81```8283## Timeout and Transport Rules8485- use `httpx.Timeout(...)` when connect, read, or write behavior matters86- use connection limits for high-concurrency clients, not unconstrained fan-out87- custom transports only for testing, in-process apps, or specific integration need88- keep proxy, SSL, and certificate config explicit in one place8990For deeper client setup patterns, load `references/clients.md`.9192## Error Handling Rules9394- catch `httpx.TimeoutException` for timeouts95- catch `httpx.HTTPStatusError` when server responded with failing status96- catch `httpx.RequestError` for network and transport failures97- convert library exceptions into domain-relevant errors at boundary if rest of app should not know about HTTPX98- log request context helpful for debugging; do not log secrets or full sensitive payloads99100## Guardrails101102- validate or normalize untrusted URLs before requesting103- never forward user-supplied headers blindly to upstream104- do not bury `raise_for_status()` inside low-level helpers if callers need to branch on specific status codes105- do not mix retry loops, parsing, and domain logic in same function106- do not read large responses fully into memory when streaming more appropriate107- do not patch `httpx.get` or `httpx.post` all over tests; inject clients or transports instead108109## Review Focus110111- check client lifetime clear and reused where appropriate112- check timeouts and redirects explicit enough for use case113- check status handling consistent and intentional114- check auth and headers centralized, not repeated115- check request construction safe from URL or header injection116- check tests isolate network behavior with mock transports or injected clients