You know what's better than fries? Fries cooked twice.
What's even better than twice cooked fries is triple cooked fries!
Refry is a modern, maintained, typed easy-to-use retry decorator.
pip install refry
import refry
@refry.retry
def function_with_problem():
raise Exception('Something bad happens here')
# This will be attempted 5 times, each time with a delay increasing
# by 5 seconds.
function_with_problem()
@refry.retry(rate_limit_exception=ZeroDivisionError)
def function_with_bad_division():
1 / 0
function_with_bad_division()
@refry.retry(backoff_increment=10, retries=3)
def function_with_custom_backoff():
raise Exception('Something bad happens here')
# This will be attempted 3 times, with a delay increasing by 10 seconds each time.
function_with_custom_backoff()
import asyncio
import refry
@refry.retry
async def async_function_with_problem():
raise Exception('Something bad happens here')
# This will be attempted 5 times, each time with a delay increasing by 5 seconds.
await async_function_with_problem()
import refry
def custom_logic(exception):
# Custom logic to determine if a retry should occur
return isinstance(exception, ZeroDivisionError)
@refry.retry(rate_limit_exception=ZeroDivisionError, retries=3)
def function_with_custom_logic():
1 / 0
function_with_custom_logic()
The @retry
decorator allows you to automatically retry a function if it raises specific exceptions.
It supports different backoff strategies (sequential, logarithmic, exponential) and optional jitter to handle the thundering herd problem.
import logging
import refry
@refry.retry(rate_limit_exception=Exception, backoff_increment=2, retries=5, backoff_type="sequential", jitter=True, log_level=logging.DEBUG)
def function_with_problem():
raise Exception('Something bad happens here')
# Call the function to see the retry mechanism in action
function_with_problem()
rate_limit_exception
: Types of exception to trigger a retry. Default value is [Exception
].backoff_increment
: The delay increment in seconds between retries. Default value is5
seconds.retries
: The number of retry attempts. Default value is5
.backoff_type
: The backoff strategy to use. Can be one of"sequential"
,"logarithmic"
, or"exponential"
. Defaults to"sequential"
.jitter
: IfTrue
, adds a random amount of time to each backoff interval to prevent thundering herd problem. Defaults toFalse
.log_level
: The logging level to be used for messages generated by the decorator, allowing control over the logs' verbosity. Can be set to standard Python logging levels, such aslogging.DEBUG
,logging.INFO
,logging.WARNING
, etc. Defaults tologging.INFO
.
Refry is designed to be a modern, maintained, and typed easy-to-use retry decorator. Here are some comparisons with other popular retry libraries:
- Tenacity: Tenacity is a highly configurable retry library for Python. It provides extensive options for backoff strategies, custom retry conditions, and logging. However, Tenacity's flexibility can make it more complex to use for simple retry needs.
- Retrying: Retrying is another popular retry library that offers simplicity and ease of use. However, it is no longer actively maintained, which can be a concern for projects requiring long-term support.
- Built-in Solutions: Frameworks like Django and Flask provide built-in retry mechanisms for certain operations (e.g., database retries). These are often tightly coupled with the framework and may not be suitable for general-purpose retry needs outside of the framework's context.
For development, this project uses rye to manage dependencies, environment, and publishing to pypi.
Once you've installed the tool, clone the project and follow these instructions.
cd refry/
rye sync
The rye sync
will set up the local .venv
folder.
Running tests:
rye run tests
Formatting the code:
rye run format
This project and everyone participating in it is governed by refry's Code of Conduct.
By participating, you are expected to uphold this code. Please report unacceptable behavior to @pydanny.
Thank you for considering contributing to refry! We welcome contributions from everyone.
Please read our CONTRIBUTING.md for detailed guidelines on how to contribute to this project, including how to report bugs, suggest enhancements, and submit pull requests.
- Fork the repository.
- Create a new branch from the
main
branch. - Commit your changes to your branch.
- Push your changes to your fork.
- Submit a pull request from your fork to the
main
branch of the original repository.
Daniel Roy Greenfeld |
Ricardo Vitorino |