redo


Nameredo JSON
Version 3.0.0 PyPI version JSON
download
home_pagehttps://github.com/mozilla-releng/redo
SummaryUtilities to retry Python callables.
upload_time2024-07-17 18:31:13
maintainerNone
docs_urlNone
authorBen Hearsum
requires_pythonNone
licenseMPL-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            Redo - Utilities to retry Python callables
==========================================

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!'

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/mozilla-releng/redo",
    "name": "redo",
    "maintainer": null,
    "docs_url": null,
    "requires_python": null,
    "maintainer_email": null,
    "keywords": null,
    "author": "Ben Hearsum",
    "author_email": "ben@hearsum.ca",
    "download_url": "https://files.pythonhosted.org/packages/23/91/cd9b78aca21a3a5fb915582a9e8b727e2513e38732df45b2c3ee63cbe7be/redo-3.0.0.tar.gz",
    "platform": null,
    "description": "Redo - Utilities to retry Python callables\n==========================================\n\nIntroduction\n************\n\nRedo 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\"``).\n\nInstallation\n************\n\nFor installing with pip, run following commands\n\n::\n\n    pip install redo\n\nHow To Use\n**********\n\nBelow is the list of functions available\n\n* retrier\n* retry\n* retry_async\n* retriable\n* retriable_async\n* retrying (contextmanager)\n\nretrier(attempts=5, sleeptime=10, max_sleeptime=300, sleepscale=1.5, jitter=1)\n------------------------------------------------------------------------------\n\nA 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.\n\n**Arguments Detail:**    \n\n1. **attempts (int):** maximum number of times to try; defaults to 5\n2. **sleeptime (float):** how many seconds to sleep between tries; defaults to 60s (one minute)\n3. **max_sleeptime (float):** the longest we'll sleep, in seconds; defaults to 300s (five minutes)\n4. **sleepscale (float):** how much to multiply the sleep time by each iteration; defaults to 1.5\n5. **jitter (int):** random jitter to introduce to sleep time each iteration. the amount is chosen at random between ``[-jitter, +jitter]`` defaults to 1\n\n**Output:** None, a maximum of ``attempts`` number of times\n\n**Example:**\n\n::\n\n    >>> n = 0\n    >>> for _ in retrier(sleeptime=0, jitter=0):\n    ...     if n == 3:\n    ...         # We did the thing!\n    ...         break\n    ...     n += 1\n    >>> n\n    3\n    >>> n = 0\n    >>> for _ in retrier(sleeptime=0, jitter=0):\n    ...     if n == 6:\n    ...         # We did the thing!\n    ...         break\n    ...     n += 1\n    ... else:\n    ...     print(\"max tries hit\")\n    max tries hit\n\nretry(action, attempts=5, sleeptime=60, max_sleeptime=5 * 60, sleepscale=1.5, jitter=1, retry_exceptions=(Exception,), cleanup=None, args=(), kwargs={})  \n--------------------------------------------------------------------------------------------------------------------------------------------------------\n\nCalls an action function until it succeeds, or we give up.\n\n**Arguments Detail:**  \n\n1. **action (callable):** the function to retry\n2. **attempts (int):** maximum number of times to try; defaults to 5\n3. **sleeptime (float):** how many seconds to sleep between tries; defaults to 60s (one minute)\n4. **max_sleeptime (float):** the longest we'll sleep, in seconds; defaults to 300s (five minutes)\n5. **sleepscale (float):** how much to multiply the sleep time by each iteration; defaults to 1.5\n6. **jitter (int):** random jitter to introduce to sleep time each iteration. The amount is chosen at random between ``[-jitter, +jitter]`` defaults to 1\n7. **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.\n8. **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.\n9. **args (tuple):** positional arguments to call ``action`` with\n10. **kwargs (dict):** keyword arguments to call ``action`` with\n\n**Output:** Whatever action(\\*args, \\*\\*kwargs) returns\n \n**Output:** Whatever action(\\*args, \\*\\*kwargs) raises. ``retry_exceptions`` are caught up until the last attempt, in which case they are re-raised.\n\n**Example:**\n\n::\n\n    >>> count = 0\n    >>> def foo():\n    ...     global count\n    ...     count += 1\n    ...     print(count)\n    ...     if count < 3:\n    ...         raise ValueError(\"count is too small!\")\n    ...     return \"success!\"\n    >>> retry(foo, sleeptime=0, jitter=0)\n    1\n    2\n    3\n    'success!'\n\nretry_async(func, attempts=5, sleeptime_callback=calculate_sleep_time, retry_exceptions=Exception, args=(), kwargs={}, sleeptime_kwargs=None)\n---------------------------------------------------------------------------------------------------------------------------------------------\n\nAn asynchronous function that retries a given async callable.\n\n**Arguments Detail:**\n\n1. **func (function):** an awaitable function to retry\n2. **attempts (int):** maximum number of attempts; defaults to 5\n3. **sleeptime_callback (function):** function to determine sleep time after each attempt; defaults to `calculateSleepTime`\n4. **retry_exceptions (list or exception):** exceptions to retry on; defaults to `Exception`\n5. **args (list):** arguments to pass to `func`\n6. **kwargs (dict):** keyword arguments to pass to `func`\n7. **sleeptime_kwargs (dict):** keyword arguments to pass to `sleeptime_callback`\n\n**Output:** The value from a successful `func` call or raises an exception after exceeding attempts.\n\n**Example:**\n\n::\n\n    >>> async def async_action():\n    ...     # Your async code here\n    >>> result = await retry_async(async_action)\n\nretriable(\\*retry_args, \\*\\*retry_kwargs)\n-----------------------------------------\n\nA decorator factory for ``retry()``. Wrap your function in ``@retriable(...)`` to give it retry powers!\n\n**Arguments Detail:** Same as for ``retry``, with the exception of ``action``, ``args``, and ``kwargs``, which are left to the normal function definition.\n\n**Output:** A function decorator\n\n**Example:**\n\n::\n\n    >>> count = 0\n    >>> @retriable(sleeptime=0, jitter=0)\n    ... def foo():\n    ...     global count\n    ...     count += 1\n    ...     print(count)\n    ...     if count < 3:\n    ...         raise ValueError(\"count too small\")\n    ...     return \"success!\"\n    >>> foo()\n    1\n    2\n    3\n    'success!'\n\nretriable_async(retry_exceptions=Exception, sleeptime_kwargs=None)\n------------------------------------------------------------------\n\nA decorator for asynchronously retrying a function.\n\n**Arguments Detail:**\n\n1. **retry_exceptions (list or exception):** exceptions to retry on; defaults to `Exception`\n2. **sleeptime_kwargs (dict):** keyword arguments to pass to the sleeptime callback\n\n**Output:** A function decorator that applies `retry_async` to the decorated function.\n\n**Example:**\n\n::\n\n    >>> @retriable_async()\n    ... async def async_action():\n    ...     # Your async code here\n    >>> result = await async_action()\n\nretrying(func, \\*retry_args, \\*\\*retry_kwargs)\n----------------------------------------------\n\nA context manager for wrapping functions with retry functionality.\n\n**Arguments Detail:**   \n\n1. **func (callable):** the function to wrap other arguments as per ``retry``\n\n**Output:** A context manager that returns ``retriable(func)`` on ``__enter__``\n\n**Example:**\n\n::\n\n    >>> count = 0\n    >>> def foo():\n    ...     global count\n    ...     count += 1\n    ...     print(count)\n    ...     if count < 3:\n    ...         raise ValueError(\"count too small\")\n    ...     return \"success!\"\n    >>> with retrying(foo, sleeptime=0, jitter=0) as f:\n    ...     f()\n    1\n    2\n    3\n    'success!'\n",
    "bugtrack_url": null,
    "license": "MPL-2.0",
    "summary": "Utilities to retry Python callables.",
    "version": "3.0.0",
    "project_urls": {
        "Homepage": "https://github.com/mozilla-releng/redo"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "6467128a17272a74f56da57cbae4a6f282a29d435d080cf80714c1137192b8c9",
                "md5": "54faa7ad2c302bf90434974ec723efb4",
                "sha256": "66905396b2882577fa4bf7edb90fee081db2b98992d303f12e3f898ac7f7bd56"
            },
            "downloads": -1,
            "filename": "redo-3.0.0-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "54faa7ad2c302bf90434974ec723efb4",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 14006,
            "upload_time": "2024-07-17T18:31:12",
            "upload_time_iso_8601": "2024-07-17T18:31:12.366742Z",
            "url": "https://files.pythonhosted.org/packages/64/67/128a17272a74f56da57cbae4a6f282a29d435d080cf80714c1137192b8c9/redo-3.0.0-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2391cd9b78aca21a3a5fb915582a9e8b727e2513e38732df45b2c3ee63cbe7be",
                "md5": "86b4c1319a3733e07d578b477cd424e9",
                "sha256": "52a14200004d6708924a547b31b7d1c717cb36b944f3a5c7b176e0d61ab81eef"
            },
            "downloads": -1,
            "filename": "redo-3.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "86b4c1319a3733e07d578b477cd424e9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 20723,
            "upload_time": "2024-07-17T18:31:13",
            "upload_time_iso_8601": "2024-07-17T18:31:13.739076Z",
            "url": "https://files.pythonhosted.org/packages/23/91/cd9b78aca21a3a5fb915582a9e8b727e2513e38732df45b2c3ee63cbe7be/redo-3.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-17 18:31:13",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "mozilla-releng",
    "github_project": "redo",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "tox": true,
    "lcname": "redo"
}
        
Elapsed time: 0.52092s