🚀 Resilient HTTP — Smart, Fault-Tolerant HTTP Client for Python
A modern, production-grade HTTP client wrapper with automatic retries, circuit breakers, jittered backoff, and metrics integration — all built for reliability under failure.
✨ Features
| ⚙️ Capability | 💡 Description |
|---|---|
| 🔁 Automatic Retries | Configurable retry logic for transient errors and specific HTTP status codes. |
| ⛔ Circuit Breaker | Opens and closes circuits based on failures to prevent cascading service outages. |
| ⏱ Exponential Backoff + Jitter | Prevents thundering-herd retry storms under heavy load. |
| 📈 Metrics Hooks | Customizable metrics sinks for Prometheus, OpenTelemetry, or custom tracking. |
| ⚡ Async + Sync Clients | Full support for both requests and httpx async workflows. |
| 🧠 Configurable Policies | Fine-grained control of retry rules, idempotency, and exception handling. |
| 🧪 100% Tested | Comprehensive pytest suite with CI and coverage reports. |
📦 Installation
pip install resilient-http
or for the latest development version:
pip install git+https://github.com/pgnikolov/resilient-http.git
🚀 Quickstart Examples
🧩 Synchronous (Requests)
from resilient_http.resilient_session import ResilientRequestsSession
from resilient_http.retry_policy import RetryPolicy
from resilient_http.circuit_breaker import CircuitBreaker
retry_policy = RetryPolicy(max_attempts=3)
cb = CircuitBreaker(max_failures=2, reset_timeout=10)
session = ResilientRequestsSession(retry_policy=retry_policy, circuit_breaker=cb)
response = session.get("https://httpbin.org/status/503")
print(response.status_code)
Output example:
503 (retrying...)
200
⚙️ Asynchronous (HTTPX)
import asyncio
from resilient_http.resilient_async_client import ResilientAsyncClient
from resilient_http.retry_policy import RetryPolicy
async def main():
client = ResilientAsyncClient(retry_policy=RetryPolicy(max_attempts=3))
resp = await client.get("https://httpbin.org/status/503")
print(resp.status_code)
asyncio.run(main())
🔄 Configuration
All retry and circuit breaker parameters are configurable:
| Parameter | Type | Default | Description |
|---|---|---|---|
max_attempts |
int |
3 |
Maximum retry attempts per request |
retry_on_status |
tuple[int] |
(500, 502, 503, 504) |
Status codes that trigger retries |
backoff_strategy |
callable |
exponential_backoff |
Backoff function controlling retry delay |
max_failures |
int |
5 |
Failures before circuit breaker opens |
reset_timeout |
float |
30.0 |
Time before circuit transitions to half-open |
Backoff functions can be customized via:
from resilient_http.backoff import exponential_backoff, full_jitter
exp = exponential_backoff(base=2, factor=0.5, max_delay=8)
jittered = full_jitter(exp)
🧩 Metrics Integration
You can attach a metrics sink to collect circuit and retry events:
from resilient_http.metrics import MetricsSink
class PrintMetrics(MetricsSink):
def record_event(self, event: str, **data):
print(f"[metrics] {event}: {data}")
session = ResilientRequestsSession(metrics_sink=PrintMetrics())
Output:
[metrics] retry: {'url': 'https://api.service', 'attempt': 1, 'reason': '503'}
[metrics] cb_open: {'key': 'GET https://api.service', 'failures': 5}
🧱 Project Structure
resilient-http/
├── resilient_http/
│ ├── __init__.py
│ ├── backoff.py
│ ├── circuit_breaker.py
│ ├── exceptions.py
│ ├── metrics.py
│ ├── resilient_async_client.py
│ ├── resilient_session.py
│ └── retry_policy.py
├── tests/
├── pyproject.toml
├── .coveragerc
└── README.md
🧪 Running Tests Locally
pytest --cov=resilient_http --cov-report=term-missing
Example output:
22 passed in 1.47s
TOTAL COVERAGE: 82%
🧰 Development Setup
git clone https://github.com/pgnikolov/resilient-http.git
cd resilient-http
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
pip install -e .[dev]
pytest
🧬 Continuous Integration (GitHub Actions)
The CI workflow runs tests on Linux, macOS, and Windows using multiple Python versions.
# .github/workflows/tests.yml
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install -e .[dev]
- run: pytest --cov=resilient_http --cov-report=term-missing
🧾 License
This project is licensed under the terms of the MIT License. See the LICENSE file for details.
👤 Author
Plamen Nikolov 📍 Oosterhout, Netherlands 💼 GitHub: @pgnikolov
❤️ Contributing
Contributions are welcome! Please open issues or submit PRs with improvements or additional features.
🌟 Support
If this project helps you build more resilient systems, please ⭐ the repo on GitHub!
Metadata
Release files for resilient-http 1.0.12
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| resilient_http-1.0.12.tar.gz | 15.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| resilient_http-1.0.12-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 27.3 kB
Release files / resilient_http-1.0.12.tar.gz
| Download URL | resilient_http-1.0.12.tar.gz |
|---|---|
| Size | 15.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
00dd880e5ae3099894f57c031344d4c68866034b51377defb62b8112647bccac
|
|
BLAKE2b-256 checksum How to use checksums |
9761f5791092e62ca273348c59e23b4e8c94c2a9a1ca79ddc653d39119607851
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|
Release files / resilient_http-1.0.12-py3-none-any.whl
| Download URL | resilient_http-1.0.12-py3-none-any.whl |
|---|---|
| Size | 12.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
614c7abdb9e21a9ec8902b044990ea6ee87771b4f571d300a94aae22b75371b5
|
|
BLAKE2b-256 checksum How to use checksums |
39be99300ac546df48aeeac6dd9efa4732c93c16cccd70e96579512f900738fc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.12
|