A lightweight, beginner-friendly Python retry decorator with exponential backoff.
Project description
ezretry-asik
A lightweight, beginner-friendly Python decorator to automatically retry failing operations with configurable exponential backoff and exception filtering.
Features
- Simple Decorator Syntax: Wrap any function with
@retryto instantly add resilience. - Exponential Backoff: Configurable delay multiplier to progressively wait longer between retries, giving downstream systems time to recover.
- Targeted Exception Filtering: Specify exactly which errors should trigger a retry, allowing developer bugs (like
KeyErrororNameError) to fail fast. - Signature Preservation: Retains the original function's docstring, name, and parameter signature using
functools.wraps. - Zero External Dependencies: Pure Python implementation utilizing only standard library modules (
timeandfunctools).
Installation
Install the library directly from PyPI:
pip install ezretry-asik
Or install locally for development:
pip install -e .
Usage Guide
Basic Usage
By default, the decorator retries any raised exception up to 3 times, with a constant 1-second delay between attempts.
from ezretry import retry
@retry(tries=3)
def fetch_api_data():
# This call will run up to 3 times if any exception occurs.
# It waits 1.0 second between attempts.
return request_network_resource()
Specifying Target Exceptions
To prevent retrying on syntax errors, division by zero, or logical bugs, restrict retries to specific exceptions (such as network or connection timeouts).
from ezretry import retry
@retry(exceptions=(ConnectionError, TimeoutError), tries=4)
def upload_payload():
# Only ConnectionError or TimeoutError will trigger a retry.
# A TypeError or ValueError will crash immediately.
return send_data()
Understanding Exponential Backoff
The backoff multiplier determines how the sleep interval increases after each consecutive failure.
The delay for attempt N is calculated as:
current_delay = delay * (backoff ^ (N - 1))
Here is an example setup with 5 attempts, a base delay of 1.5 seconds, and a backoff multiplier of 2.0:
from ezretry import retry
@retry(tries=5, delay=1.5, backoff=2.0)
def process_transaction():
raise ConnectionError("Server connection failed")
If the function fails continuously, the wait times between attempts behave as follows:
| Attempt | Status | Delay Before Next Attempt | Cumulative Time Waited |
|---|---|---|---|
| 1 | Failed | 1.5 seconds | 1.5 seconds |
| 2 | Failed | 3.0 seconds | 4.5 seconds |
| 3 | Failed | 6.0 seconds | 10.5 seconds |
| 4 | Failed | 12.0 seconds | 22.5 seconds |
| 5 | Failed | Raises final exception | 22.5 seconds |
Integrating a Custom Logger
Pass a standard Python logger instance to log warnings automatically before each retry sleep.
import logging
from ezretry import retry
logging.basicConfig(level=logging.WARNING)
app_logger = logging.getLogger("network")
@retry(tries=3, delay=1.0, logger=app_logger)
def database_query():
raise RuntimeError("Query timed out")
This configuration prints the following warning messages to the console:
WARNING:network:Function 'database_query' raised RuntimeError: Query timed out. Retrying in 1.00 seconds (attempts remaining: 2)...
WARNING:network:Function 'database_query' raised RuntimeError: Query timed out. Retrying in 2.00 seconds (attempts remaining: 1)...
Configuration Reference
| Parameter | Type | Default | Description |
|---|---|---|---|
exceptions |
Exception or tuple[Exception, ...] |
Exception |
The exception types to catch and retry. |
tries |
int |
3 |
Maximum number of attempts (must be greater than or equal to 1). |
delay |
float |
1.0 |
Initial delay between retries in seconds (must be greater than or equal to 0). |
backoff |
float |
2.0 |
Multiplier applied to the delay after each failure (must be greater than or equal to 1.0). |
logger |
logging.Logger |
None |
Optional logger to print warning messages. |
License
This project is licensed under the MIT 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
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 ezretry_asik-0.1.1.tar.gz.
File metadata
- Download URL: ezretry_asik-0.1.1.tar.gz
- Upload date:
- Size: 4.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87dda41c920825da7d30e6523634f4b8b0d1503335d5591227b15e5d9ebc6171
|
|
| MD5 |
15d6a48a1d14a5f9999a8d473334787e
|
|
| BLAKE2b-256 |
ac3fa4c3848d947fbc75811a307de5fdff31013d3a0f2145439cdb6220939916
|
File details
Details for the file ezretry_asik-0.1.1-py3-none-any.whl.
File metadata
- Download URL: ezretry_asik-0.1.1-py3-none-any.whl
- Upload date:
- Size: 4.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e18000c0f0125cd3f7e3845a1fbebb9843af2fa3dfa3f860d95f66eb2c1753ad
|
|
| MD5 |
a191c197fb7005804ecc85ecaeae42e4
|
|
| BLAKE2b-256 |
55a8de0fc85013db14e22e6e6a04613631470e40b5f3073c3ec3567f5995a09e
|