Skip to main content

Zero-dependency retry decorator (sync & async)

Project description

retrylite

CI codecov PyPI version Python versions License: MIT Zero Dependencies

Zero-dependency retry decorator for Python (sync & async) with circuit-breaker, retry-after, and full type safety.

Features

  • Zero runtime dependencies – only std-lib.
  • Sync & Async support.
  • Exponential backoff & full jitter.
  • Circuit-breaker support.
  • Respects Retry-After header.
  • Test coverage & mypy strict.
  • PyPI wheel < 10 kB.

Installation

pip install retrylite

Quick Start

Synchronous

from retrylite import retry
import requests

@retry(max_attempts=3, backoff=1.5)
def fetch(url):
    resp = requests.get(url, timeout=5)
    resp.raise_for_status()
    return resp.json()

try:
    data = fetch("https://httpbin.org/json")
except requests.HTTPError:
    print("Final failure after 3 retries")

Asynchronous

import aiohttp
from retrylite import aretry

@aretry(max_attempts=3, backoff=1.5)
async def fetch(url):
    async with aiohttp.ClientSession() as s:
        async with s.get(url) as resp:
            resp.raise_for_status()
            return await resp.text()

html = asyncio.run(fetch("https://httpbin.org/json"))

Advanced

Circuit-breaker

from retrylite import retry

@retry(break_on=(ValueError,))
def risky():
    raise ValueError("permanent")  # no retry

Retry-After header

from retrylite import retry
import requests

@retry(retry_after=True)
def api_call():
    resp = requests.get(url)
    resp.raise_for_status()  # respects 503 + Retry-After

Sample:

import time
import requests
import aiohttp
import asyncio
from retrylite import retry, aretry

# 1. Sync retry ---------------------------------
print("=== Sync Retry ===")
calls = 0

@retry(max_attempts=3, backoff=0.5, retry_after=True)
def fetch_sync(url: str) -> str:
    global calls
    calls += 1
    print(f"[Sync] attempt {calls}")
    resp = requests.get(url, timeout=3)
    resp.raise_for_status()
    return resp.text

try:
    html = fetch_sync("https://httpbin.org/status/503")
except requests.HTTPError:
    print("[Sync] Final failure (expected)")
print(f"[Sync] Total calls: {calls}\n")

# 2. Async retry --------------------------------
print("=== Async Retry ===")
calls = 0

@aretry(max_attempts=3, backoff=0.5, retry_after=True)
async def fetch_async(url: str) -> str:
    global calls
    calls += 1
    print(f"[Async] attempt {calls}")
    async with aiohttp.ClientSession() as s:
        async with s.get(url) as resp:
            resp.raise_for_status()
            return await resp.text()

try:
    html = asyncio.run(fetch_async("https://httpbin.org/status/503"))
except aiohttp.ClientResponseError:
    print("[Async] Final failure (expected)")
print(f"[Async] Total calls: {calls}\n")

# 3. Circuit-breaker demo ----------------------
print("=== Circuit-Breaker Demo ===")

@retry(max_attempts=5, break_on=(ValueError,), backoff=0.1)
def always_fail():
    raise ValueError("permanent")

try:
    always_fail()
except ValueError as e:
    print(f"[Circuit] Immediately raised: {e} (no retry)")

Development

git clone https://github.com/moehandi/retrylite.git
cd retrylite
poetry install
poetry run pre-commit install
poetry run pytest --cov
poetry build

License

MIT - see LICENSE

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

retrylite-0.1.0.tar.gz (7.1 kB view details)

Uploaded Source

Built Distribution

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

retrylite-0.1.0-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: retrylite-0.1.0.tar.gz
  • Upload date:
  • Size: 7.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for retrylite-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b710ceabf91cbfaf81e84f542cf35bc5d35ed3589eb4bc56cc2b4d52f0b14ddd
MD5 a7895c25cbf7275fb83a3ac851a4c4c2
BLAKE2b-256 efb5d53e39029dc4ad0177f3810c349169fae1ec08d4aea562f0cbf6d8157e14

See more details on using hashes here.

File details

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

File metadata

  • Download URL: retrylite-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 6.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for retrylite-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a7166002fd342baccf0d72275c66b3d6334e0fdd6be4b9e2c81adf4e6330d53c
MD5 682c7d1578921bd66a0ab73b89f42ee3
BLAKE2b-256 7ce1313e48639b1bb0a9c8e57248bed824eed2c37283751f54989682314eae55

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