Skip to main content

🔁 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

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.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page