Async HTTP client with retry, backoff, and proxy rotation
Project description
resilient-httpx
HTTP client with retry, backoff, and proxy rotation. Sync and async. Built on top of httpx, tenacity, and structlog.
Installation
pip install resilient-httpx
Usage
Sync client
from resilient_httpx import ProxyHttpClient, RetryPolicy
with ProxyHttpClient(retry=RetryPolicy(max_attempts=5), timeout=15.0) as client:
response = client.get("https://api.example.com/data")
Async client
from resilient_httpx import AsyncProxyHttpClient, RetryPolicy
async with AsyncProxyHttpClient(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,
)
with client:
response = client.get("https://api.example.com/data")
data = response.json()
AsyncProxyHttpClient accepts the same parameters:
from resilient_httpx import AsyncProxyHttpClient, RetryPolicy
async with AsyncProxyHttpClient(
proxies=["http://proxy1:8080", "http://proxy2:8080"],
retry=RetryPolicy(max_attempts=5, backoff="exponential"),
) as client:
response = await client.get("https://api.example.com/data")
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
with ProxyHttpClient(proxies=proxy_list) as client:
try:
response = 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
Both ProxyHttpClient and AsyncProxyHttpClient accept the same parameters:
| 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
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.4.0.tar.gz.
File metadata
- Download URL: resilient_httpx-0.4.0.tar.gz
- Upload date:
- Size: 13.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0e18dfacdc1a283c13fea947d13c9e0ce7f92a3de258555c1fee55268cba510
|
|
| MD5 |
13c99d0c7bc7a82e1a59e693d31c88af
|
|
| BLAKE2b-256 |
1fb5d3f63d25b31ec64603bf8850aa1ceb7e03df3fb924675e90d88a44f969ee
|
Provenance
The following attestation bundles were made for resilient_httpx-0.4.0.tar.gz:
Publisher:
publish.yml on galthran-wq/resilient-httpx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
resilient_httpx-0.4.0.tar.gz -
Subject digest:
c0e18dfacdc1a283c13fea947d13c9e0ce7f92a3de258555c1fee55268cba510 - Sigstore transparency entry: 1574140798
- Sigstore integration time:
-
Permalink:
galthran-wq/resilient-httpx@f25e506cee90565a38c16d0b259020c50eac151d -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/galthran-wq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f25e506cee90565a38c16d0b259020c50eac151d -
Trigger Event:
push
-
Statement type:
File details
Details for the file resilient_httpx-0.4.0-py3-none-any.whl.
File metadata
- Download URL: resilient_httpx-0.4.0-py3-none-any.whl
- Upload date:
- Size: 14.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67a78f8427e5c65acb24ff6f32040409867d70aef1464c063317034bed0168a6
|
|
| MD5 |
c1557faa8d5e1a971ca9517327e35ee2
|
|
| BLAKE2b-256 |
a6f42994dd81f0a8228a21cea76a1b0f63b3ceba78bbfc94522c6a6f08e7f765
|
Provenance
The following attestation bundles were made for resilient_httpx-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on galthran-wq/resilient-httpx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
resilient_httpx-0.4.0-py3-none-any.whl -
Subject digest:
67a78f8427e5c65acb24ff6f32040409867d70aef1464c063317034bed0168a6 - Sigstore transparency entry: 1574140837
- Sigstore integration time:
-
Permalink:
galthran-wq/resilient-httpx@f25e506cee90565a38c16d0b259020c50eac151d -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/galthran-wq
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f25e506cee90565a38c16d0b259020c50eac151d -
Trigger Event:
push
-
Statement type: