Skip to main content

A composable retry policy framework with classification, jitter strategies, and observability hooks.

Project description

reflexio

CI codecov

Composable, low-overhead retry policies with pluggable classification, per-class backoff strategies, and structured observability hooks.
Designed for services that need predictable retry behavior and clean integration with metrics/logging.

Installation

Not published yet. Install locally:

uv pip install .

Quick Start

from reflexio.policy import RetryPolicy
from reflexio.classify import default_classifier
from reflexio.strategies import decorrelated_jitter

policy = RetryPolicy(
    classifier=default_classifier,
    strategy=decorrelated_jitter(max_s=10.0),
)

def flaky():
    # your operation that may fail
    ...

result = policy.call(flaky)

Async quick start

import asyncio
from reflexio import AsyncRetryPolicy, default_classifier
from reflexio.strategies import decorrelated_jitter

async_policy = AsyncRetryPolicy(
    classifier=default_classifier,
    strategy=decorrelated_jitter(max_s=5.0),
)

async def flaky_async():
    ...

asyncio.run(async_policy.call(flaky_async))

Why reflexio?

Most retry libraries give you either:

  • decorators with a fixed backoff model, or
  • one global strategy for all errors.

reflexio gives you something different:

✔ Exception → coarse error class mapping

Provided via default_classifier.

✔ Per-class strategy dispatch

Each ErrorClass can use its own backoff logic.

✔ Dependency-free strategies with jitter

decorrelated_jitter, equal_jitter, token_backoff.

✔ Deadlines, max attempts, and separate caps for UNKNOWN

Deterministic retry envelopes.

✔ Clean observability hook

Single callback for:
success, retry, permanent_fail, deadline_exceeded, max_attempts_exceeded, max_unknown_attempts_exceeded.

Error Classes & Classification

PERMANENT
CONCURRENCY
RATE_LIMIT
SERVER_ERROR
TRANSIENT
UNKNOWN

Classification rules:

  • Explicit reflexio error types
  • Numeric codes (err.status or err.code)
  • Name heuristics
  • Fallback to UNKNOWN

Metrics & Observability

def metric_hook(event, attempt, sleep_s, tags):
    print(event, attempt, sleep_s, tags)

policy.call(my_op, on_metric=metric_hook)

Backoff Strategies

Strategy signature:

(attempt: int, klass: ErrorClass, prev_sleep: Optional[float]) -> float

Built‑ins:

  • decorrelated_jitter()
  • equal_jitter()
  • token_backoff()

Per-Class Example

policy = RetryPolicy(
    classifier=default_classifier,
    strategy=decorrelated_jitter(max_s=10.0),  # default
    strategies={
        ErrorClass.CONCURRENCY: decorrelated_jitter(max_s=1.0),
        ErrorClass.RATE_LIMIT: decorrelated_jitter(max_s=60.0),
        ErrorClass.SERVER_ERROR: equal_jitter(max_s=30.0),
    },
)

Deadline & Attempt Controls

policy = RetryPolicy(
    classifier=default_classifier,
    strategy=decorrelated_jitter(),
    deadline_s=60,
    max_attempts=8,
    max_unknown_attempts=2,
)

Development

uv run pytest

Examples

  • Sync httpx demo: uv pip install httpx then uv run python examples/httpx_sync_retry.py
  • Async httpx demo using AsyncRetryPolicy: uv pip install httpx then uv run python examples/httpx_async_retry.py
  • Async worker loop with retries: uv run python examples/async_worker_retry.py
  • FastAPI proxy with metrics counter: uv pip install "fastapi[standard]" httpx then uv run uvicorn examples.fastapi_downstream:app --reload

Versioning

Semantic Versioning.

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

reflexio-0.1.0.tar.gz (32.4 kB view details)

Uploaded Source

Built Distribution

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

reflexio-0.1.0-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file reflexio-0.1.0.tar.gz.

File metadata

  • Download URL: reflexio-0.1.0.tar.gz
  • Upload date:
  • Size: 32.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for reflexio-0.1.0.tar.gz
Algorithm Hash digest
SHA256 278ae7ba23821a285c9904c8ebdc1b9d1966aa05fb245b25b242cc303cac96e9
MD5 6a91024d1917c9e9e1818cb7dbe39b34
BLAKE2b-256 8b420339030c9dd3d0a2bb8d7e937fa5fd9a7c094a3116f1de3123026ba7eec3

See more details on using hashes here.

File details

Details for the file reflexio-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: reflexio-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for reflexio-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c87f7fa20346de0b6978a016cbb8313b68c5bc5a267a9ef3453b5fea4c014885
MD5 5e8b3dec9dbc2005d33c8928edf7d1f0
BLAKE2b-256 7e161ec92c2575fb649542322fa5149640d5cbb921eb211732afa2905db26411

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