Reretry
Reretry is a Python library providing an easy-to-use, yet functional decorator for retrying functions on exceptions. It is a fork of the `retry` package, enhancing it with features like logging of traceback, callbacks after each failure, and support for `async` functions. Currently at version 0.11.8, it is actively maintained with a focus on providing a robust retry mechanism with minimal dependencies.
Common errors
-
ModuleNotFoundError: No module named 'reretry'
cause The `reretry` package is not installed in the current Python environment or the environment is not activated.fixInstall the package using pip: `pip install reretry`. -
My decorated function isn't retrying; it just fails immediately.
cause The `exceptions` argument in `@retry` is not catching the specific exception being raised, or the `tries` limit is too low and quickly exhausted.fixEnsure the `exceptions` argument is set to catch the relevant exception type (e.g., `exceptions=(MyCustomError, ConnectionError)`) or use `exceptions=Exception` for a broad catch. Also, verify that the `tries` parameter is set to a sufficient number or is left at its default for infinite retries (though this is not recommended for production). -
My async function decorated with @retry is not working or is hanging.
cause `reretry` introduced async function support in version 0.11.0. This error might occur if you are using an older version or if the async function is not properly awaited or run.fixUpgrade `reretry` to version 0.11.0 or newer (`pip install --upgrade reretry`). Ensure your async function is correctly called and awaited within an `async` context or executed using `asyncio.run()`.
Warnings
- breaking Python 3.5 support was dropped in `reretry` version 0.11.2. If you are using Python 3.5 or older, you must either upgrade your Python environment or pin `reretry` to a version older than 0.11.2.
- gotcha By default, the `@retry` decorator is configured with `tries=-1`, meaning it will attempt to retry indefinitely until the decorated function succeeds or another unhandled exception occurs. This can lead to hung processes if not explicitly controlled.
- gotcha Reretry is a fork of the `retry` package. While it aims to be mostly compatible, some differences in API, defaults, or available features might exist. Direct migration from the original `retry` library may require minor adjustments.
Install
-
pip install reretry
Imports
- retry
from reretry import retry
Quickstart
import random
import asyncio
from reretry import retry
attempt_count = 0
@retry(exceptions=ValueError, tries=3, delay=1)
def flaky_sync_function():
global attempt_count
attempt_count += 1
print(f"Sync function attempt {attempt_count}...")
if random.randint(1, 10) < 7:
raise ValueError("Sync operation failed!")
print("Sync operation succeeded!")
return "Success"
async_attempt_count = 0
@retry(exceptions=RuntimeError, tries=2, delay=0.5)
async def flaky_async_function():
global async_attempt_count
async_attempt_count += 1
print(f"Async function attempt {async_attempt_count}...")
if random.randint(1, 10) < 8:
raise RuntimeError("Async operation failed!")
print("Async operation succeeded!")
return "Async Success"
if __name__ == "__main__":
print("\n--- Running Synchronous Example ---")
try:
result_sync = flaky_sync_function()
print(f"Final sync result: {result_sync}")
except Exception as e:
print(f"Sync function ultimately failed: {e}")
print("\n--- Running Asynchronous Example ---")
try:
result_async = asyncio.run(flaky_async_function())
print(f"Final async result: {result_async}")
except Exception as e:
print(f"Async function ultimately failed: {e}")