A simple Python library for retrying functions with various backoff and callback strategies.
Project description
retry
A simple, yet powerful, generic retry decorator in Python for retrying functions with various backoff and callback strategies.
Install
pip install retry-reloaded
Features:
- Exception Handling: Retry based on specific exceptions. If not specified then the default behaviour is to retry on all exceptions.
- Maximum Retries: Set the maximum number of retry attempts.
- Timeout: Specify the maximum time in seconds to spend on retries. Timeout check happens right before retry execution of the wrapped function.
- Deadline: Define a deadline in seconds for retries to complete. Deadline check happens right after the retry execution of the wrapped function.
- Backoff Strategies: Choose from various backoff strategies: fixed, exponential, linear, random
- Retry Callback: Execute a callback function between retry attempts.
- Successful Retry Callback: Perform an action after a successful retry.
- Failure Callback: Define a callback function after failing all retries.
- Logging control: Define which logger (or no logger) to use for logging retries and exceptions.
API
- Decorator:
retry
- Retry exceptions:
MaxRetriesException
,RetriesTimeoutException
,RetriesDeadlineException
- Callback factory:
CallbackFactory
,callback_factory
- Backoff strategies:
FixedBackOff
,LinearBackOff
,ExponentialBackOff
,RandomUniformBackOff
Examples
# public API
from retry_reloaded import (
retry,
callback_factory,
CallbackFactory,
FixedBackOff,
LinearBackOff,
ExponentialBackOff,
RandomUniformBackOff,
MaxRetriesException,
RetriesTimeoutException,
RetriesDeadlineException
)
# Retry until maximum retries are reached
# no backoff strategy means the default will apply,
# which is 0 delay between retries
@retry((AssertionError,), max_retries=3)
def cause_max_retries_error():
assert False
# Retry until timeout error after 2 seconds
# Fixed backoff strategy for 1 second delay between retries
@retry((ValueError,), timeout=2, backoff=FixedBackOff(base_delay=1))
def cause_timeout_error():
raise ValueError
# Retry until deadline error after 3 seconds
# Not really retrying here, this will just execute once
# as the execution will take longer than deadline
@retry(deadline=3)
def cause_deadline_error():
sleep(4)
# Retry until deadline error after 2 seconds
# Fixed backoff strategy for 1 second delay between retries
# Expected to retry twice and then succeed but restricted by deadline
@retry(
(ValueError,),
deadline=2,
backoff=FixedBackOff(base_delay=1)
)
def cause_deadline_error_after_retries():
if not hasattr(cause_deadline_error_after_retries, "call_count"):
cause_deadline_error_after_retries.call_count = 0
cause_deadline_error_after_retries.call_count += 1
if cause_deadline_error_after_retries.call_count < 2:
raise ValueError
else:
sleep(1)
# Retry until maximum retries are reached
# Random backoff strategy with an initial delay and
# limits for min and max delay in next retries
# Callback function between retries by passing a callable function
def retry_callback():
logger.debug("Calling between retries")
@retry(
(ValueError,),
max_retries=3,
backoff=RandomUniformBackOff(base_delay=0.3, min_delay=0.1, max_delay=0.5),
retry_callback=retry_callback
)
def retry_with_callback():
raise ValueError
# Retry indefinetely as there is no max retries, timeout
# or deadline specified
# Exponential backoff strategy with an initial delay of 1 second
# Parametrized callback with utility of package to call after successful retry
# Successful callback is expected after successful retry on 3rd round
def successful_retry_callback(value):
logger.debug(f"Calling on successful retry with value: {value}")
successful_retry_callback_ = callback_factory(successful_retry_callback, "phew")
@retry(
(ValueError,),
backoff=ExponentialBackOff(base_delay=1),
successful_retry_callback=successful_retry_callback_
)
def successful_retry_with_callback():
if not hasattr(successful_retry_with_callback, "call_count"):
successful_retry_with_callback.call_count = 0
successful_retry_with_callback.call_count += 1
if successful_retry_with_callback.call_count < 3:
raise ValueError
# Retry until maximum retries are reached
# Linear backoff strategy with an initial delay of 0.1 second and 0.1 second as step
# Parametrized callback with utility of package to call after failure of all retries
# Failure callback is expected after failing all 3 retries
def failure_callback(value):
logger.debug(f"Calling after failure of all retries with value: {value}")
failure_callback_ = CallbackFactory(failure_callback, value="wasted")
@retry(
max_retries=3,
backoff=LinearBackOff(base_delay=0.1, step=0.1),
failure_callback=failure_callback_
)
def fail_with_callback():
raise ValueError
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
retry_reloaded-0.0.4.tar.gz
(11.5 kB
view details)
Built Distribution
File details
Details for the file retry_reloaded-0.0.4.tar.gz
.
File metadata
- Download URL: retry_reloaded-0.0.4.tar.gz
- Upload date:
- Size: 11.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.0.0 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 47466de4f4350663655d32aac26099afc5a525a0977f7ff5efd0ec68ac92b439 |
|
MD5 | d9a8038fbe80697b824fc9970ba5a090 |
|
BLAKE2b-256 | aec0c2a8f26e458e78e200dd41579f6974c5dc9e2698f8ee006852041dbd920f |
File details
Details for the file retry_reloaded-0.0.4-py3-none-any.whl
.
File metadata
- Download URL: retry_reloaded-0.0.4-py3-none-any.whl
- Upload date:
- Size: 10.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.0.0 CPython/3.12.3
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 52f3993c2048b040b719202686fe9bbd43b2e1ee81ad84edfc6454e394c06c97 |
|
MD5 | 9d75955f26e0f042837edf530c80e3ff |
|
BLAKE2b-256 | 90ad84cae0fc2713894746d050e9770224d3ef9718bfef742587b2ed360fbbb7 |