Skip to main content

Resilience layer for Python HTTP clients (smart retries, jitter backoff, circuit breaker)

Project description

๐Ÿš€ Resilient HTTP โ€” Smart, Fault-Tolerant HTTP Client for Python

CI codecov PyPI version Python License

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!

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_http-1.0.12.tar.gz (15.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

resilient_http-1.0.12-py3-none-any.whl (12.1 kB view details)

Uploaded Python 3

File details

Details for the file resilient_http-1.0.12.tar.gz.

File metadata

  • Download URL: resilient_http-1.0.12.tar.gz
  • Upload date:
  • Size: 15.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for resilient_http-1.0.12.tar.gz
Algorithm Hash digest
SHA256 00dd880e5ae3099894f57c031344d4c68866034b51377defb62b8112647bccac
MD5 6c88071f88b74d8bf1f6dd6b25424d39
BLAKE2b-256 9761f5791092e62ca273348c59e23b4e8c94c2a9a1ca79ddc653d39119607851

See more details on using hashes here.

File details

Details for the file resilient_http-1.0.12-py3-none-any.whl.

File metadata

File hashes

Hashes for resilient_http-1.0.12-py3-none-any.whl
Algorithm Hash digest
SHA256 614c7abdb9e21a9ec8902b044990ea6ee87771b4f571d300a94aae22b75371b5
MD5 bc24a08935ec3cba135e87917da04755
BLAKE2b-256 39be99300ac546df48aeeac6dd9efa4732c93c16cccd70e96579512f900738fc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page