Zero-dependency retry decorator (sync & async)
Project description
retrylite
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
Release history Release notifications | RSS feed
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)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
38bde0700cdbed3d3aa945e052664e643deadc550bbbd0117a4450ef8fd85ea6
|
|
| MD5 |
3026db15ff86514509ba382404b3644e
|
|
| BLAKE2b-256 |
6257259c7002b621014ad23af7cd60abd125b48b774788807fee445fcdc5d620
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70d49b59bf88fe77b3b7f17fd96740ed06d3debe0996daab098ea9c0e3a87754
|
|
| MD5 |
077e53d0de66254afc8e27dd5a5dd0e0
|
|
| BLAKE2b-256 |
91c747953755d13f632bc0830edf65db306d369c04ecced057a98343634bcccf
|