Skip to main content

Resilient HTTP client with automatic retries and backoff.

Project description

philiprehberger-http-retry

Tests PyPI version Last updated

Resilient HTTP client with automatic retries and configurable backoff.

Installation

pip install philiprehberger-http-retry

Usage

from philiprehberger_http_retry import resilient_get, resilient_post, Session

Simple Requests

# GET request with default retries (3 attempts, exponential backoff)
response = resilient_get("https://api.example.com/data")
print(response.read().decode())

# POST with JSON body
response = resilient_post(
    "https://api.example.com/items",
    json_data={"name": "widget", "count": 5},
)

Backoff Strategies

from philiprehberger_http_retry import resilient_request

# Exponential backoff (default): 0.5s, 1s, 2s, ...
resilient_request("GET", url, backoff="exponential")

# Linear backoff: 0.5s, 1s, 1.5s, ...
resilient_request("GET", url, backoff="linear")

# Constant backoff: 0.5s, 0.5s, 0.5s, ...
resilient_request("GET", url, backoff="constant")

# Custom callable: receives attempt number, returns delay in seconds
resilient_request("GET", url, backoff=lambda attempt: 0.1 * (attempt + 1))

Retry Hook

import logging

def log_retry(attempt: int, error: Exception) -> None:
    logging.warning(f"Retry {attempt}: {error}")

response = resilient_get(
    "https://api.example.com/data",
    on_retry=log_retry,
)

Circuit breaker

from philiprehberger_http_retry import (
    CircuitBreaker,
    CircuitBreakerOpen,
    resilient_get,
)

breaker = CircuitBreaker(failure_threshold=5, reset_timeout=30.0)

try:
    response = resilient_get(
        "https://flaky-api.example.com/data",
        circuit_breaker=breaker,
    )
except CircuitBreakerOpen as err:
    print(f"Breaker tripped, retry after unix time {err.next_retry_at:.0f}")

The breaker counts request outcomes (not retry attempts). After failure_threshold consecutive failures it trips to open and rejects calls until reset_timeout elapses, then probes one request in half_open before returning to closed.

Session with Defaults

session = Session(
    base_url="https://api.example.com",
    default_headers={"Authorization": "Bearer token123"},
    retries=5,
    backoff="linear",
    timeout=15,
    on_retry=log_retry,
)

response = session.get("/users")
response = session.post("/users", json_data={"name": "Alice"})

Error Handling

from philiprehberger_http_retry import resilient_get, RetryExhaustedError

try:
    response = resilient_get("https://unreliable-api.example.com/data")
except RetryExhaustedError as err:
    print(f"Failed after {err.attempts} attempts: {err.last_error}")

API

Function / Class Description
resilient_request(method, url, **kwargs) Core retry function. Supports data, headers, retries, backoff, timeout, retry_on, on_retry.
resilient_get(url, **kwargs) GET convenience wrapper around resilient_request.
resilient_post(url, data=None, json_data=None, **kwargs) POST wrapper. Auto-serializes json_data and sets Content-Type.
Session(base_url, default_headers, retries, backoff, timeout, retry_on, on_retry, circuit_breaker) Stores defaults. Methods: get(path), post(path).
CircuitBreaker(failure_threshold, reset_timeout, half_open_max_calls) Trips to open after consecutive failures, probes via half_open. Methods: allow_request(), record_success(), record_failure().
CircuitBreakerOpen Raised when the breaker rejects a request. Attribute: .next_retry_at (unix timestamp).
RetryExhaustedError Raised after all retries fail. Attributes: .attempts, .last_error.

Development

pip install -e .
python -m pytest tests/ -v

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

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

philiprehberger_http_retry-0.3.0.tar.gz (9.7 kB view details)

Uploaded Source

Built Distribution

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

philiprehberger_http_retry-0.3.0-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file philiprehberger_http_retry-0.3.0.tar.gz.

File metadata

File hashes

Hashes for philiprehberger_http_retry-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b17c28b1d34d9674a4277404421f7bbf07b22a32c34492a27a512c421e8548d0
MD5 b8c800eff548da57c440373a8e2d0938
BLAKE2b-256 5be011113b9e93b460219a3997210dae26ed85649108de523cd15b41230c949f

See more details on using hashes here.

File details

Details for the file philiprehberger_http_retry-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for philiprehberger_http_retry-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 07cdfef0493d4f643d4299ac98fd6eff2e4169e52650e8602a05658bbe4fee05
MD5 b2be08636309243c013b03c086b0aa19
BLAKE2b-256 34c3a23c335d0e7ee2b94c89da9458a35157a00ec5e45ac705085c851b968996

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