httpx-defaults
Production-ready httpx client with secure defaults: timeouts, retries, connection limits.
The Problem
httpx is great, but it requires you to configure timeouts, connection limits, and other production settings manually. Most developers skip this, leading to hanging requests and resource exhaustion in production.
import httpx
# This can hang forever! 😱
response = httpx.get("https://slow-api.example.com")
# You need to remember all this boilerplate 😤
client = httpx.Client(
timeout=httpx.Timeout(connect=5.0, read=30.0, write=30.0, pool=10.0),
limits=httpx.Limits(max_connections=100, max_keepalive_connections=20),
follow_redirects=True,
verify=True
)
The Solution
from httpx_defaults import Client, AsyncClient
# Production-ready defaults out of the box! 🎉
with Client() as client:
response = client.get("https://api.example.com") # Safe timeouts included
# Async version
async with AsyncClient() as client:
response = await client.get("https://api.example.com")
Installation
pip install httpx-defaults
Features
- Production-ready timeouts: 5s connect, 30s read/write, 10s pool
- Connection limits: 100 max connections, 20 keepalive connections
- Security warnings: Alerts when using HTTP for non-localhost URLs
- Secure by default: HTTPS preferred, redirects followed, certificates verified
- Drop-in replacement: Same API as httpx.Client and httpx.AsyncClient
Quick Start
Basic Usage
from httpx_defaults import Client, AsyncClient
# Synchronous client
with Client() as client:
response = client.get("https://api.example.com/users")
users = response.json()
# Asynchronous client
async with AsyncClient() as client:
response = await client.get("https://api.example.com/users")
users = response.json()
With Base URL and Headers
from httpx_defaults import Client
with Client(
base_url="https://api.example.com",
headers={"Authorization": "Bearer your-token"}
) as client:
# All requests use the base URL and headers
response = client.get("/users") # → https://api.example.com/users
response = client.post("/users", json={"name": "Alice"})
Convenience Functions
from httpx_defaults import safe_get, safe_post
# One-shot requests with secure defaults
response = safe_get("https://api.example.com/status")
response = safe_post("https://api.example.com/webhook", json={"event": "test"})
Configuration
Custom Timeouts
import httpx
from httpx_defaults import Client
# Override default timeouts
custom_timeout = httpx.Timeout(connect=2.0, read=60.0)
with Client(timeout=custom_timeout) as client:
response = client.get("https://slow-api.example.com")
Custom Connection Limits
import httpx
from httpx_defaults import Client
# Override default limits
custom_limits = httpx.Limits(max_connections=50, max_keepalive_connections=10)
with Client(limits=custom_limits) as client:
response = client.get("https://api.example.com")
HTTP/2 Support
from httpx_defaults import Client
# Enable HTTP/2 (requires h2 package)
with Client(http2=True) as client:
response = client.get("https://api.example.com")
Default Configuration
| Setting | Value | Reason |
|---|---|---|
| Connect timeout | 5 seconds | Prevents hanging on slow DNS/connection |
| Read timeout | 30 seconds | Reasonable for most API responses |
| Write timeout | 30 seconds | Reasonable for most API requests |
| Pool timeout | 10 seconds | Prevents connection pool exhaustion |
| Max connections | 100 | Good balance for most applications |
| Keepalive connections | 20 | Efficient connection reuse |
| Follow redirects | True | Handle redirects automatically |
| Verify certificates | True | Security by default |
| HTTP/2 | False | Avoid h2 dependency by default |
Security Features
HTTPS Enforcement
httpx-defaults warns when you use HTTP for non-localhost URLs:
from httpx_defaults import Client
with Client() as client:
# This will show a warning ⚠️
response = client.get("http://api.example.com")
# This is fine ✅
response = client.get("http://localhost:8000")
response = client.get("https://api.example.com")
Certificate Verification
Certificate verification is enabled by default and cannot be accidentally disabled:
from httpx_defaults import Client
# Certificates are always verified ✅
with Client() as client:
response = client.get("https://api.example.com")
# To disable verification, you must be explicit
with Client(verify=False) as client: # Not recommended!
response = client.get("https://self-signed.example.com")
Comparison with httpx
| Feature | httpx | httpx-defaults |
|---|---|---|
| Timeouts | Manual configuration | ✅ Secure defaults |
| Connection limits | Manual configuration | ✅ Production-ready limits |
| Security warnings | None | ✅ HTTP usage warnings |
| Certificate verification | Default on | ✅ Always on by default |
| Redirect handling | Manual | ✅ Automatic |
| Dependencies | httpx only | httpx only |
Migration from httpx
httpx-defaults is a drop-in replacement for httpx:
# Before
import httpx
client = httpx.Client()
# After
from httpx_defaults import Client
client = Client() # Now with secure defaults!
All httpx.Client and httpx.AsyncClient methods work exactly the same.
Requirements
- Python 3.10+
- httpx >= 0.25.0
License
MIT License - Free for commercial use
Contributing
Contributions welcome! Please see our Contributing Guide.
Related Projects
- httpx - The underlying HTTP client
- asyncbridge - Async/sync conversion utilities
- devkitx - Security-first Python utilities
Metadata
Release files for httpx-defaults 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| httpx_defaults-1.0.0.tar.gz | 5.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| httpx_defaults-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 9.8 kB
Release files / httpx_defaults-1.0.0.tar.gz
| Download URL | httpx_defaults-1.0.0.tar.gz |
|---|---|
| Size | 5.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
cbd2c1d78b0466da580f421b01c3312a7dc56eb7c6ccfb3c61d3fd3954a43c72
|
|
BLAKE2b-256 checksum How to use checksums |
f6f0e2f255dfe674bf324dc6fd666a1371c55d9926839db2909613e01e541719
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Release files / httpx_defaults-1.0.0-py3-none-any.whl
| Download URL | httpx_defaults-1.0.0-py3-none-any.whl |
|---|---|
| Size | 4.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
6be9b91329780a6fee3bba72a0e926b0afbf4ee2cf7ddd4c6d12e805484ef270
|
|
BLAKE2b-256 checksum How to use checksums |
0bb8c11fed6e73f0334a2437e8d5935f76797217dc8c16e790b0fe20310e39b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.0
|
Security for httpx-defaults 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.