Skip to main content

retrykit (Python)

Retry logic and circuit breakers with an identical API in Python and TypeScript.

  • @retry decorator and Retrying context manager
  • ✅ Built-in circuit breaker (CLOSED → OPEN → HALF_OPEN → CLOSED)
  • ✅ Sync and async, transparently
  • ✅ Automatic OpenTelemetry spans when opentelemetry-api is installed
  • ✅ Zero required dependencies, fully typed (py.typed)

Install

pip install retrykit
# with OpenTelemetry spans:
pip install "retrykit[otel]"

Quick start

from retrykit import retry

@retry(attempts=3)
async def call_api() -> str:
    ...

Full options

@retry(
    attempts=5,
    backoff="exponential",   # "fixed" | "linear" | "exponential"
    delay=1.0,               # base delay in seconds
    max_delay=60.0,
    jitter=True,             # full jitter to avoid thundering herd
    on=["HTTPError", "TimeoutError"],  # retry only on these (class or name)
    on_retry=lambda attempt, error: print(f"Retry {attempt}: {error}"),
)
async def call_openai(prompt: str) -> str:
    ...

Circuit breaker

from retrykit import circuit_breaker, CircuitBreaker, CircuitOpenError

@circuit_breaker(threshold=5, timeout=30, on_open=lambda: print("opened!"))
async def call_stripe(): ...

# Or standalone:
breaker = CircuitBreaker(threshold=5, timeout=30)
result = breaker.call(do_work)          # sync
result = await breaker.call_async(work) # async
print(breaker.state)                    # CircuitState.CLOSED / OPEN / HALF_OPEN

Composable

@retry(attempts=3, backoff="exponential")
@circuit_breaker(threshold=5, timeout=30)
async def resilient_call(): ...

Context-manager style

from retrykit import Retrying

async with Retrying(attempts=3, backoff="exponential") as r:
    async for attempt in r:
        with attempt:
            result = await call_api()

The sync form is identical without the async keywords:

with Retrying(attempts=3) as r:
    for attempt in r:
        with attempt:
            result = call_api()

API reference

retry(attempts=3, *, backoff="exponential", delay=1.0, max_delay=60.0, jitter=False, on=None, on_retry=None)

Decorator. Retries up to attempts times. Raises RetryError (with .last_exception) when exhausted. on accepts exception classes or their string names; None retries on any Exception.

Retrying(...)

Same options as retry; usable as a sync or async context manager / iterator.

circuit_breaker(threshold=5, timeout=30, *, on_open=None, on_close=None)

Decorator. The underlying CircuitBreaker is exposed on the wrapped function as .breaker. Raises CircuitOpenError while open.

CircuitBreaker(threshold=5, timeout=30.0, *, on_open=None, on_close=None)

.call(fn, *a, **kw), await .call_async(fn, *a, **kw), .state, .failure_count, .reset().

OpenTelemetry

If opentelemetry-api is importable, every attempt is wrapped in a span named retry.attempt:<func> with attributes retry.attempt, retry.max_attempts, and retry.failed. If it is not installed, span creation is silently skipped — no configuration required.

Development

pip install -e ".[dev]"
pytest --cov=retrykit
mypy
ruff check retrykit

License

MIT

Release files for retrykit-lib 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for retrykit-lib 0.1.0
File Size Uploaded
retrykit_lib-0.1.0.tar.gz 11.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for retrykit-lib 0.1.0
File Interpreter ABI Platform
retrykit_lib-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.9 kB

Release files / retrykit_lib-0.1.0.tar.gz

Download URL retrykit_lib-0.1.0.tar.gz
Size 11.6 kB
Tags Source
SHA-256 checksum
How to use checksums
4cfc80e9a0096e188f7f4d966903f29bd72568a46e2941a5ab25315831e76dd6
BLAKE2b-256 checksum
How to use checksums
41db08389ccafc057cc587cf797ded5c9fb748b3dbe599a897af9efd55455a34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.11

Release files / retrykit_lib-0.1.0-py3-none-any.whl

Download URL retrykit_lib-0.1.0-py3-none-any.whl
Size 11.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f8ac9074609a79db62d7fa1bc6820c2cb7849b853c2929df297df57eec2f087b
BLAKE2b-256 checksum
How to use checksums
33cd57347d06397fef34afab8e9e3ceab2c08ebc503274408e2aec885d756154
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.10.11

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page