Easy-to-Use Retry Decorator
retry2 is a Python library that provides an easy-to-use decorator for retrying functions. It is a fork of the unmaintained `invl/retry` library, offering similar functionality with a focus on being pure standard library Python, though it can optionally preserve function signatures with an additional `decorator` dependency. The current version is 0.9.5.
Warnings
- gotcha By default, the `@retry` decorator sets `tries=-1`, leading to infinite retries if no `tries` or `max_delay` is specified. This can cause indefinite blocking or resource exhaustion in production systems.
- gotcha The default `delay=0` and `backoff=1` can lead to 'retry storms' where failed operations are immediately retried without a pause. This can overwhelm an already struggling service or cause cascading failures.
- gotcha The library explicitly states that preserving function signatures (e.g., for introspection or other decorators) is optional and requires installing the `decorator` package. Without it, `inspect.signature` or other tools might report incorrect signatures.
- gotcha Retries should only be applied to transient failures (e.g., network hiccups, temporary service unavailability). Retrying on permanent failures (e.g., 4xx client errors, validation errors) will not resolve the issue and will waste resources.
- gotcha When retrying operations that modify state (e.g., payments, creating resources), ensure the underlying operation is idempotent. Without idempotency, retries can lead to unintended side effects like duplicate charges or entries.
Install
-
pip install retry2 -
pip install retry2 decorator
Imports
- retry
from retry import retry
- retry_call
from retry import retry_call
Quickstart
from retry import retry
import time
call_count = 0
@retry(exceptions=IOError, tries=3, delay=1, backoff=2)
def might_fail_api_call():
global call_count
call_count += 1
print(f"Attempt {call_count}: Calling API...")
if call_count < 3:
raise IOError("Temporary network issue")
print("API call successful!")
return "Data"
try:
result = might_fail_api_call()
print(f"Final result: {result}")
except IOError as e:
print(f"Failed after multiple retries: {e}")