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.2.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.2-py3-none-any.whl (6.7 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: retrylite-0.1.2.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.2.tar.gz
Algorithm Hash digest
SHA256 38bde0700cdbed3d3aa945e052664e643deadc550bbbd0117a4450ef8fd85ea6
MD5 3026db15ff86514509ba382404b3644e
BLAKE2b-256 6257259c7002b621014ad23af7cd60abd125b48b774788807fee445fcdc5d620

See more details on using hashes here.

File details

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

File metadata

  • Download URL: retrylite-0.1.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 70d49b59bf88fe77b3b7f17fd96740ed06d3debe0996daab098ea9c0e3a87754
MD5 077e53d0de66254afc8e27dd5a5dd0e0
BLAKE2b-256 91c747953755d13f632bc0830edf65db306d369c04ecced057a98343634bcccf

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