Async HTTP client with retry, backoff, and proxy rotation
Project description
resilient-httpx
Async HTTP client with retry, backoff, and proxy rotation. Built on top of httpx, tenacity, and structlog.
Installation
pip install git+https://github.com/galthran-wq/resilient-httpx.git
Usage
Basic (no proxies)
from resilient_httpx import ProxyHttpClient, RetryPolicy
async with ProxyHttpClient(retry=RetryPolicy(max_attempts=5), timeout=15.0) as client:
response = await client.get("https://api.example.com/data")
With proxy rotation
from resilient_httpx import ProxyHttpClient, RetryPolicy
client = ProxyHttpClient(
proxies=[
"http://proxy1:8080",
"http://user:pass@proxy2:8080",
"socks5://proxy3:1080",
],
proxy_strategy="round-robin", # or "random"
retry=RetryPolicy(max_attempts=5, backoff="exponential"),
timeout=15.0,
blacklist_threshold=3,
blacklist_ttl=300.0,
)
async with client:
response = await client.get("https://api.example.com/data")
data = response.json()
Custom retry policy
import httpx
from resilient_httpx import RetryPolicy
policy = RetryPolicy(
max_attempts=5,
backoff="exponential", # "exponential" | "fixed" | "random_jitter"
min_wait=1.0,
max_wait=30.0,
retry_on=[429, 500, 502, 503, 504],
retry_on_exception=[httpx.TimeoutException, httpx.ConnectError],
)
Error handling
from resilient_httpx import ProxyHttpClient, AllProxiesExhausted, MaxRetriesExceeded
async with ProxyHttpClient(proxies=proxy_list) as client:
try:
response = await client.get("https://api.example.com/data")
except AllProxiesExhausted:
... # all proxies blacklisted
except MaxRetriesExceeded as exc:
... # retries exhausted, exc.__cause__ has the last error
Configuration Reference
| Parameter | Type | Default | Description |
|---|---|---|---|
proxies |
list[str] | None |
None |
Proxy URLs |
proxy_strategy |
str |
"round-robin" |
"round-robin" or "random" |
retry |
RetryPolicy |
RetryPolicy() |
Retry configuration |
timeout |
float |
30.0 |
Request timeout in seconds |
headers |
dict[str, str] | None |
None |
Default headers |
blacklist_threshold |
int |
3 |
Consecutive failures before blacklisting |
blacklist_ttl |
float |
300.0 |
Blacklist duration in seconds |
fallback_to_direct |
bool |
False |
Request without proxy when all are blacklisted |
Development
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
pytest
Run with coverage:
pytest --cov=resilient_httpx --cov-report=term-missing
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
resilient_httpx-0.1.0.tar.gz
(7.7 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file resilient_httpx-0.1.0.tar.gz.
File metadata
- Download URL: resilient_httpx-0.1.0.tar.gz
- Upload date:
- Size: 7.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51147da5a3fcab1d17c045a863a1941c8af15d73b046436c18f3632cdb6a45b4
|
|
| MD5 |
3cf690a17ecf170e7341cfbe74cb5147
|
|
| BLAKE2b-256 |
9b64af5d3f0d1ea8e6bac5ad2dc4823e721bf78d4f81df96c5b1e4029119a070
|
File details
Details for the file resilient_httpx-0.1.0-py3-none-any.whl.
File metadata
- Download URL: resilient_httpx-0.1.0-py3-none-any.whl
- Upload date:
- Size: 7.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6f942b7b7d76b75277753bd234627539b9b0dc9bd0240ff9c1cf46ddd3932d53
|
|
| MD5 |
dfbdee64646dd9b839e1415a86f956a6
|
|
| BLAKE2b-256 |
2b8a8affe78760e0a3fc393ef6813161e6e67bf2e02f3ca4e09c8fedb5512a0f
|