Skip to main content

Easy to use retry decorator.

Project description

https://img.shields.io/pypi/dm/reretry.svg?maxAge=2592000 https://img.shields.io/pypi/v/reretry.svg?maxAge=2592000 https://img.shields.io/pypi/l/reretry.svg?maxAge=2592000

Easy to use retry decorator.

This package is a fork from the retry package, with a lot of added community-sourced features.

Features

  • Retry on specific exceptions.

  • Set a maximum number of retries.

  • Set a delay between retries.

  • Set a maximum delay between retries.

  • Set backoff and jitter parameters.

  • Show traceback of an error that lead to a failed attempt.

  • Use a custom logger.

  • Call a custom callback after each failed attempt.

  • Can be used with async functions.

  • No external dependencies (stdlib only).

  • (Optionally) Preserve function signatures (pip install decorator).

Installation

$ pip install reretry

API

retry decorator

def retry(
    exceptions=Exception, tries=-1, delay=0, max_delay=None, backoff=1,
    jitter=0, show_traceback=False, logger=logging_logger, fail_callback=None
):
    """Return a retry decorator.

    Args:
        exceptions: an exception or a tuple of exceptions to catch. default: Exception.
        tries: the maximum number of attempts. default: -1 (infinite).
        delay: initial delay between attempts (in seconds). default: 0.
        max_delay: the maximum value of delay (in seconds). default: None (no limit).
        backoff: multiplier applied to delay between attempts. default: 1 (no backoff).
        jitter: extra seconds added to delay between attempts. default: 0.
                   fixed if a number, random if a range tuple (min, max)
        show_traceback: Print traceback before retrying (Python3 only). default: False.
        logger: logger.warning(fmt, error, delay) will be called on failed attempts.
                   default: retry.logging_logger. if None, logging is disabled.
        fail_callback: fail_callback(e) will be called on failed attempts.
    """

Various retrying logic can be achieved by combination of arguments.

Examples

from reretry import retry
@retry()
def make_trouble():
    '''Retry until succeeds'''
@retry()
async def async_make_trouble():
    '''Retry an async function until it succeeds'''
@retry(ZeroDivisionError, tries=3, delay=2)
def make_trouble():
    '''Retry on ZeroDivisionError, raise error after 3 attempts,
    sleep 2 seconds between attempts.'''
@retry((ValueError, TypeError), delay=1, backoff=2)
def make_trouble():
    '''Retry on ValueError or TypeError, sleep 1, 2, 4, 8, ... seconds between attempts.'''
@retry((ValueError, TypeError), delay=1, backoff=2, max_delay=4)
def make_trouble():
    '''Retry on ValueError or TypeError, sleep 1, 2, 4, 4, ... seconds between attempts.'''
@retry(ValueError, delay=1, jitter=1)
def make_trouble():
    '''Retry on ValueError, sleep 1, 2, 3, 4, ... seconds between attempts.'''
def callback(e: Exception):
    '''Print error message'''
    print(e)

@retry(ValueError, fail_callback=callback):
def make_trouble():
    '''Retry on ValueError, between attempts call callback(e)
    (where e is the Exception raised).'''
# If you enable logging, you can get warnings like 'ValueError, retrying in
# 1 seconds'
if __name__ == '__main__':
    import logging
    logging.basicConfig()
    make_trouble()

retry_call

def retry_call(
    f, fargs=None, fkwargs=None, exceptions=Exception, tries=-1, delay=0,
    max_delay=None, backoff=1, jitter=0, show_traceback=False, logger=logging_logger,
    fail_callback=None
):

Calls a function and re-executes it if it failed.

This is very similar to the decorator, except that it takes a function and its arguments as parameters. The use case behind it is to be able to dynamically adjust the retry arguments.

import requests

from reretry.api import retry_call


def make_trouble(service, info=None):
    if not info:
        info = ''
    r = requests.get(service + info)
    return r.text


def what_is_my_ip(approach=None):
    if approach == "optimistic":
        tries = 1
    elif approach == "conservative":
        tries = 3
    else:
        # skeptical
        tries = -1
    result = retry_call(
        make_trouble,
        fargs=["http://ipinfo.io/"],
        fkwargs={"info": "ip"},
        tries=tries
    )
    print(result)

what_is_my_ip("conservative")

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

reretry-0.11.0.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

reretry-0.11.0-py2.py3-none-any.whl (6.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file reretry-0.11.0.tar.gz.

File metadata

  • Download URL: reretry-0.11.0.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for reretry-0.11.0.tar.gz
Algorithm Hash digest
SHA256 762e5930fc9b52a411884aa8229a1a4f03620d36582ed0951e4dce1d65be070d
MD5 f215dfccdac0d22848fd95b54dd1b529
BLAKE2b-256 80818c97fa53acf9ced95d9ab34fa94cccbefa682ec9b7654278b74b4312fac9

See more details on using hashes here.

File details

Details for the file reretry-0.11.0-py2.py3-none-any.whl.

File metadata

  • Download URL: reretry-0.11.0-py2.py3-none-any.whl
  • Upload date:
  • Size: 6.3 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.0 CPython/3.9.12

File hashes

Hashes for reretry-0.11.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 81730c0081fa50ecd0c4f688b2c8c4a6e8f72b16565ba644a566d4e27fd0d26a
MD5 c74b1586f5427e51dd899c8e77c87c1f
BLAKE2b-256 69a6bb2bc460fcee54504d36b5380e2bab501018a534d653c5ba9854cf7e9768

See more details on using hashes here.

Supported by

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