Skip to main content

In-memory URL backoff registry with sliding window thresholds.

Project description

url-backoff-registry

PyPI version CI

In-memory URL backoff registry with sliding window thresholds.

Track failing endpoints and back off when failures exceed a threshold within a time window. Useful for avoiding repeated requests to flaky or overloaded services.

Install

pip install url-backoff-registry

Usage

Basic usage

from url_backoff_registry import BackoffRegistry

# Back off for 120s after 3 failures within 30s
registry = BackoffRegistry(window_seconds=30, threshold=3, backoff_seconds=120)

def fetch(url):
    if registry.should_backoff(url):
        raise Exception(f"Backing off from {url}")

    try:
        response = requests.get(url)
        response.raise_for_status()
        return response
    except Exception:
        registry.record_failure(url)
        raise

Decorator

Use the @track decorator to automatically record failures and clear on success:

from url_backoff_registry import BackoffError, BackoffRegistry

registry = BackoffRegistry()

@registry.track("https://api.example.com")
def fetch_data():
    response = requests.get("https://api.example.com/data")
    response.raise_for_status()
    return response.json()

try:
    data = fetch_data()
except BackoffError as e:
    print(f"Backing off until {e.until}")
except requests.RequestException:
    print("Request failed, failure recorded")

Per-key rules

Set different thresholds for different endpoints:

registry = BackoffRegistry(threshold=3)  # Default: 3 failures

# Flaky API: back off after just 1 failure, for 5 minutes
registry.set_rule("https://flaky-api.com", threshold=1, backoff_seconds=300)

# Critical API: more lenient, 5 failures before backing off
registry.set_rule("https://critical-api.com", threshold=5)

Stats and introspection

stats = registry.stats("https://api.example.com")
# {'failures_in_window': 2, 'in_backoff': False, 'backoff_until': None}

all_keys = registry.keys()
# ['https://api.example.com', 'https://other-api.com']

API

BackoffRegistry

Parameter Type Default Description
window_seconds int 30 Time window for counting failures
threshold int 3 Number of failures to trigger backoff
backoff_seconds int 120 How long to back off
clock callable datetime.utcnow Clock function (for testing)

Methods

  • record_failure(key) - Record a failure for the given key
  • should_backoff(key) - Returns True if currently in backoff
  • next_retry_at(key) - Returns datetime when backoff ends, or None
  • clear(key) - Clear backoff and failure history for the key
  • set_rule(key, ...) - Set custom thresholds for a specific key
  • clear_rule(key) - Remove custom rule, revert to defaults
  • stats(key) - Get failure count, backoff status, and backoff end time
  • keys() - List all keys with recorded failures or in backoff
  • track(key, clear_on_success=True) - Decorator for automatic tracking

BackoffError

Raised by @track when a call is attempted while in backoff.

  • key - The key that is in backoff
  • until - Datetime when backoff ends

FAQ

How is this different from the backoff package?

The backoff package provides decorators for retrying a single function call with exponential backoff. It's great for "retry this request up to 3 times with increasing delays."

This package solves a different problem: tracking failures across multiple calls to decide whether to attempt a request at all. It answers "should I even try this URL right now, given its recent failure history?"

backoff url-backoff-registry
Scope Single function call Cross-call state
Mechanism Retry decorator Failure registry
Question answered "How many times should I retry?" "Should I try at all?"

They're complementary - you can use both together.

Why not just use a circuit breaker?

Circuit breakers (like pybreaker) are similar but typically operate per-function. This registry is keyed by URL/endpoint, so you can track failures for many endpoints with a single registry instance. It's lighter weight and doesn't require decorating each call site.

Development

git clone https://github.com/larsderidder/url-backoff-registry.git
cd url-backoff-registry
python -m venv .venv
. .venv/bin/activate
pip install -e ".[dev]"
pytest

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

url_backoff_registry-1.1.0.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

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

url_backoff_registry-1.1.0-py3-none-any.whl (6.2 kB view details)

Uploaded Python 3

File details

Details for the file url_backoff_registry-1.1.0.tar.gz.

File metadata

  • Download URL: url_backoff_registry-1.1.0.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for url_backoff_registry-1.1.0.tar.gz
Algorithm Hash digest
SHA256 9ccd0b3fe7c533626d23af6165dc6b0881131f161a22216b127eab90b5785b6b
MD5 4da8fe0c85f347d82d352b86f4ae4615
BLAKE2b-256 a48e670c91be8973abeee537a410482199c36459278f6287ca7246006325283e

See more details on using hashes here.

Provenance

The following attestation bundles were made for url_backoff_registry-1.1.0.tar.gz:

Publisher: publish.yml on larsderidder/url-backoff-registry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file url_backoff_registry-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for url_backoff_registry-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8e1d7caac8709108828d6042e41d595461d7bff9d49b58242f9ca6ecb15bcbd6
MD5 82a4d5f45d654f333eeb4d2cbd862d94
BLAKE2b-256 d6c07009c346bbb026b1bdf4d8694d20d341327b27f03e808afdcda236db33ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for url_backoff_registry-1.1.0-py3-none-any.whl:

Publisher: publish.yml on larsderidder/url-backoff-registry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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