Skip to main content

Utilities to retry Python callables.

Project description

Introduction

Redo provides various means to add seamless ability to retry to any Python callable. Redo includes plain functions (redo.retry, redo.retry_async), decorators (redo.retriable, redo.retriable_async), and a context manager (redo.retrying) to enable you to integrate it in the best possible way for your project. As a bonus, a standalone interface is also included ("retry").

Installation

For installing with pip, run following commands

pip install redo

How To Use

Below is the list of functions available

  • retrier

  • retry

  • retry_async

  • retriable

  • retriable_async

  • retrying (contextmanager)

retrier(attempts=5, sleeptime=10, max_sleeptime=300, sleepscale=1.5, jitter=1)

A generator function that sleeps between retries, handles exponential back off and jitter. The action you are retrying is meant to run after retrier yields. At each iteration, we sleep for sleeptime + random.randint(-jitter, jitter). Afterwards sleeptime is multiplied by sleepscale for the next iteration.

Arguments Detail:

  1. attempts (int): maximum number of times to try; defaults to 5

  2. sleeptime (float): how many seconds to sleep between tries; defaults to 60s (one minute)

  3. max_sleeptime (float): the longest we’ll sleep, in seconds; defaults to 300s (five minutes)

  4. sleepscale (float): how much to multiply the sleep time by each iteration; defaults to 1.5

  5. jitter (int): random jitter to introduce to sleep time each iteration. the amount is chosen at random between [-jitter, +jitter] defaults to 1

Output: None, a maximum of attempts number of times

Example:

>>> n = 0
>>> for _ in retrier(sleeptime=0, jitter=0):
...     if n == 3:
...         # We did the thing!
...         break
...     n += 1
>>> n
3
>>> n = 0
>>> for _ in retrier(sleeptime=0, jitter=0):
...     if n == 6:
...         # We did the thing!
...         break
...     n += 1
... else:
...     print("max tries hit")
max tries hit

retry(action, attempts=5, sleeptime=60, max_sleeptime=5 * 60, sleepscale=1.5, jitter=1, retry_exceptions=(Exception,), cleanup=None, args=(), kwargs={})

Calls an action function until it succeeds, or we give up.

Arguments Detail:

  1. action (callable): the function to retry

  2. attempts (int): maximum number of times to try; defaults to 5

  3. sleeptime (float): how many seconds to sleep between tries; defaults to 60s (one minute)

  4. max_sleeptime (float): the longest we’ll sleep, in seconds; defaults to 300s (five minutes)

  5. sleepscale (float): how much to multiply the sleep time by each iteration; defaults to 1.5

  6. jitter (int): random jitter to introduce to sleep time each iteration. The amount is chosen at random between [-jitter, +jitter] defaults to 1

  7. retry_exceptions (tuple): tuple of exceptions to be caught. If other exceptions are raised by action(), then these are immediately re-raised to the caller.

  8. cleanup (callable): optional; called if one of retry_exceptions is caught. No arguments are passed to the cleanup function; if your cleanup requires arguments, consider using functools.partial or a lambda function.

  9. args (tuple): positional arguments to call action with

  10. kwargs (dict): keyword arguments to call action with

Output: Whatever action(*args, **kwargs) returns

Output: Whatever action(*args, **kwargs) raises. retry_exceptions are caught up until the last attempt, in which case they are re-raised.

Example:

>>> count = 0
>>> def foo():
...     global count
...     count += 1
...     print(count)
...     if count < 3:
...         raise ValueError("count is too small!")
...     return "success!"
>>> retry(foo, sleeptime=0, jitter=0)
1
2
3
'success!'

retry_async(func, attempts=5, sleeptime_callback=calculate_sleep_time, retry_exceptions=Exception, args=(), kwargs={}, sleeptime_kwargs=None)

An asynchronous function that retries a given async callable.

Arguments Detail:

  1. func (function): an awaitable function to retry

  2. attempts (int): maximum number of attempts; defaults to 5

  3. sleeptime_callback (function): function to determine sleep time after each attempt; defaults to calculateSleepTime

  4. retry_exceptions (list or exception): exceptions to retry on; defaults to Exception

  5. args (list): arguments to pass to func

  6. kwargs (dict): keyword arguments to pass to func

  7. sleeptime_kwargs (dict): keyword arguments to pass to sleeptime_callback

Output: The value from a successful func call or raises an exception after exceeding attempts.

Example:

>>> async def async_action():
...     # Your async code here
>>> result = await retry_async(async_action)

retriable(*retry_args, **retry_kwargs)

A decorator factory for retry(). Wrap your function in @retriable(...) to give it retry powers!

Arguments Detail: Same as for retry, with the exception of action, args, and kwargs, which are left to the normal function definition.

Output: A function decorator

Example:

>>> count = 0
>>> @retriable(sleeptime=0, jitter=0)
... def foo():
...     global count
...     count += 1
...     print(count)
...     if count < 3:
...         raise ValueError("count too small")
...     return "success!"
>>> foo()
1
2
3
'success!'

retriable_async(retry_exceptions=Exception, sleeptime_kwargs=None)

A decorator for asynchronously retrying a function.

Arguments Detail:

  1. retry_exceptions (list or exception): exceptions to retry on; defaults to Exception

  2. sleeptime_kwargs (dict): keyword arguments to pass to the sleeptime callback

Output: A function decorator that applies retry_async to the decorated function.

Example:

>>> @retriable_async()
... async def async_action():
...     # Your async code here
>>> result = await async_action()

retrying(func, *retry_args, **retry_kwargs)

A context manager for wrapping functions with retry functionality.

Arguments Detail:

  1. func (callable): the function to wrap other arguments as per retry

Output: A context manager that returns retriable(func) on __enter__

Example:

>>> count = 0
>>> def foo():
...     global count
...     count += 1
...     print(count)
...     if count < 3:
...         raise ValueError("count too small")
...     return "success!"
>>> with retrying(foo, sleeptime=0, jitter=0) as f:
...     f()
1
2
3
'success!'

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

redo-3.0.0.tar.gz (20.7 kB view details)

Uploaded Source

Built Distribution

redo-3.0.0-py2.py3-none-any.whl (14.0 kB view details)

Uploaded Python 2Python 3

File details

Details for the file redo-3.0.0.tar.gz.

File metadata

  • Download URL: redo-3.0.0.tar.gz
  • Upload date:
  • Size: 20.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.0

File hashes

Hashes for redo-3.0.0.tar.gz
Algorithm Hash digest
SHA256 52a14200004d6708924a547b31b7d1c717cb36b944f3a5c7b176e0d61ab81eef
MD5 86b4c1319a3733e07d578b477cd424e9
BLAKE2b-256 2391cd9b78aca21a3a5fb915582a9e8b727e2513e38732df45b2c3ee63cbe7be

See more details on using hashes here.

File details

Details for the file redo-3.0.0-py2.py3-none-any.whl.

File metadata

  • Download URL: redo-3.0.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 14.0 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.0

File hashes

Hashes for redo-3.0.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 66905396b2882577fa4bf7edb90fee081db2b98992d303f12e3f898ac7f7bd56
MD5 54faa7ad2c302bf90434974ec723efb4
BLAKE2b-256 6467128a17272a74f56da57cbae4a6f282a29d435d080cf80714c1137192b8c9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page