Skip to main content

A clean, simple retry decorator for Python — sync, async, backoff, jitter.

Project description

🔁 retrykit

A clean, simple retry decorator for Python — sync, async, backoff, jitter, and custom exceptions.

PyPI version Python 3.8+ License: MIT


🤔 Why retrykit?

Network calls fail. APIs go down. Databases time out.

Instead of writing manual retry loops every time, just add @retry and it handles everything for you.

# Without retrykit — ugly, repetitive
for attempt in range(3):
    try:
        result = requests.get(url)
        break
    except Exception:
        if attempt == 2:
            raise
        time.sleep(1)

# With retrykit — clean and simple
@retry(times=3, delay=1)
def fetch():
    return requests.get(url)

📦 Installation

pip install retrykit

🚀 Quick Start

from retrykit import retry

@retry(times=3, delay=1)
def fetch_data():
    return requests.get("https://api.example.com").json()

That's it. If fetch_data() fails, it retries up to 3 times, waiting 1 second between attempts.


⚙️ All Options

@retry(
    times=3,           # Total attempts (default: 3)
    delay=1.0,         # Seconds to wait between retries (default: 1.0)
    backoff=1.0,       # Multiply delay by this after each retry (default: 1.0)
    jitter=False,      # Add small random delay to avoid thundering herd (default: False)
    on=None,           # List of exceptions to retry on (default: any Exception)
    on_retry=None,     # Callback called before each retry
)

📖 Examples

Basic Retry

from retrykit import retry

@retry(times=3, delay=2)
def connect_to_server():
    return requests.get("https://api.example.com")

Exponential Backoff

Delays grow: 1s → 2s → 4s → 8s

@retry(times=4, delay=1, backoff=2)
def fetch_with_backoff():
    return requests.get("https://api.example.com")

Retry Only on Specific Exceptions

@retry(times=3, delay=1, on=[ConnectionError, TimeoutError])
def connect_db():
    return db.connect()

# TypeError or ValueError won't be retried — they raise immediately

Jitter (Avoid Thundering Herd)

Adds a small random delay so multiple clients don't hammer a server at the same time.

@retry(times=3, delay=2, jitter=True)
def api_call():
    return requests.post("https://api.example.com/data", json=payload)

on_retry Callback

Run custom logic before each retry (logging, alerting, etc.)

def log_retry(attempt, exception, next_delay):
    print(f"Attempt {attempt} failed: {exception}. Retrying in {next_delay}s...")

@retry(times=3, delay=1, on_retry=log_retry)
def risky_operation():
    return do_something_risky()

Async Support

Works with async def functions automatically — no extra config needed.

@retry(times=3, delay=1)
async def async_fetch():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://api.example.com") as resp:
            return await resp.json()

Real-World Example

import requests
from retrykit import retry

def log_retry(attempt, exc, delay):
    print(f"[Warning] Attempt {attempt} failed: {exc}. Retrying in {delay}s...")

@retry(
    times=5,
    delay=1,
    backoff=2,
    jitter=True,
    on=[requests.ConnectionError, requests.Timeout],
    on_retry=log_retry,
)
def fetch_weather(city: str):
    response = requests.get(
        f"https://api.openweathermap.org/data/2.5/weather?q={city}",
        timeout=5
    )
    response.raise_for_status()
    return response.json()

data = fetch_weather("Chennai")

🆚 retrykit vs tenacity

Feature retrykit tenacity
Simple decorator API ✅ Clean ⚠️ Verbose
Async support ✅ Auto-detected ✅ Manual
Exponential backoff backoff=2 wait_exponential()
Jitter jitter=True wait_random()
Zero dependencies ✅ Pure stdlib
Learning curve ✅ Beginner-friendly ⚠️ Complex

🧪 Running Tests

pip install pytest
pytest tests/ -v

📄 License

MIT — free to use in personal and commercial projects.


🤝 Contributing

Pull requests are welcome! Please open an issue first to discuss changes.

  1. Fork the repo
  2. Create a branch: git checkout -b feature/my-feature
  3. Make your changes + add tests
  4. Open a Pull Request

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

retrykit_simple-0.1.1.tar.gz (6.8 kB view details)

Uploaded Source

Built Distribution

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

retrykit_simple-0.1.1-py3-none-any.whl (5.9 kB view details)

Uploaded Python 3

File details

Details for the file retrykit_simple-0.1.1.tar.gz.

File metadata

  • Download URL: retrykit_simple-0.1.1.tar.gz
  • Upload date:
  • Size: 6.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.5

File hashes

Hashes for retrykit_simple-0.1.1.tar.gz
Algorithm Hash digest
SHA256 fae23b7d4aed6cb39e2578d53fdde9f4c079b79f9bb9a5186fdf6eaa8ab5585f
MD5 74e6f1f309c7105f90b9749eb7e7e6c4
BLAKE2b-256 aab803a770a93fdb83d35b95640f2727fc6dcc9b96f44ca4f5dcc1b674a40f23

See more details on using hashes here.

File details

Details for the file retrykit_simple-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for retrykit_simple-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 35989bfb0c9637d44eb0b440ee9aba1ad8282ab21a3a63cee96acbcded5023de
MD5 c547497428f1972e06c096f1e92c5bdd
BLAKE2b-256 0852b69ee16c89fac19eea56fd073509991c10ea96ece841bce50cd4a9271812

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