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.0.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.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b710ceabf91cbfaf81e84f542cf35bc5d35ed3589eb4bc56cc2b4d52f0b14ddd
|
|
| MD5 |
a7895c25cbf7275fb83a3ac851a4c4c2
|
|
| BLAKE2b-256 |
efb5d53e39029dc4ad0177f3810c349169fae1ec08d4aea562f0cbf6d8157e14
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a7166002fd342baccf0d72275c66b3d6334e0fdd6be4b9e2c81adf4e6330d53c
|
|
| MD5 |
682c7d1578921bd66a0ab73b89f42ee3
|
|
| BLAKE2b-256 |
7ce1313e48639b1bb0a9c8e57248bed824eed2c37283751f54989682314eae55
|