Skip to main content

riprova (meaning retry in Italian) is a small, general-purpose and versatile Python library that provides retry mechanisms with multiple backoff strategies for any sort of failed operations.

It’s domain agnostic, highly customizable, extensible and provides a minimal API that’s easy to instrument in any code base via decorators, context managers or raw API consumption.

For a brief introduction about backoff mechanisms for potential failed operations, read this article.

Features

  • Retry decorator for simple and idiomatic consumption.

  • Simple Pythonic programmatic interface.

  • Maximum retry timeout support.

  • Supports error whitelisting and blacklisting.

  • Supports custom error evaluation retry logic (useful to retry only in specific cases).

  • Automatically retry operations on raised exceptions.

  • Supports asynchronous coroutines with both async/await and yield from syntax.

  • Configurable maximum number of retry attempts.

  • Highly configurable supporting max retries, timeouts or retry notifier callback.

  • Built-in backoff strategies: constant, fibonacci and exponential backoffs.

  • Supports sync/async context managers.

  • Pluggable custom backoff strategies.

  • Lightweight library with almost zero embedding cost.

  • Works with Python +2.6, 3.0+ and PyPy.

Backoff strategies

List of built-in backoff strategies.

You can also implement your own one easily. See ConstantBackoff for an implementation reference.

Installation

Using pip package manager (requires pip 1.9+. Upgrade it running: pip install -U pip):

pip install -U riprova

Or install the latest sources from Github:

pip install -e git+git://github.com/h2non/riprova.git#egg=riprova

API

Examples

You can see more featured examples from the documentation site.

Basic usage examples:

import riprova

@riprova.retry
def task():
    """Retry operation if it fails with constant backoff (default)"""

@riprova.retry(backoff=riprova.ConstantBackoff(retries=5))
def task():
    """Retry operation if it fails with custom max number of retry attempts"""

@riprova.retry(backoff=riprova.ExponentialBackOff(factor=0.5))
def task():
    """Retry operation if it fails using exponential backoff"""

@riprova.retry(timeout=10)
def task():
    """Raises a TimeoutError if the retry loop exceeds from 10 seconds"""

def on_retry(err, next_try):
    print('Operation error: {}'.format(err))
    print('Next try in: {}ms'.format(next_try))

@riprova.retry(on_retry=on_retry)
def task():
    """Subscribe via function callback to every retry attempt"""

def evaluator(response):
    # Force retry operation if not a valid response
    if response.status >= 400:
        raise RuntimeError('invalid response status')  # or simple return True
    # Otherwise return False, meaning no retry
    return False

@riprova.retry(evaluator=evaluator)
def task():
    """Use a custom evaluator function to determine if the operation failed or not"""

@riprova.retry
async def task():
    """Asynchronous coroutines are also supported :)"""

Retry failed HTTP requests:

import pook
import requests
from riprova import retry

# Define HTTP mocks to simulate failed requests
pook.get('server.com').times(3).reply(503)
pook.get('server.com').times(1).reply(200).json({'hello': 'world'})


# Retry evaluator function used to determine if the operated failed or not
def evaluator(response):
    if response != 200:
        return Exception('failed request')  # you can also simply return True
    return False


# On retry even subscriptor
def on_retry(err, next_try):
    print('Operation error {}'.format(err))
    print('Next try in {}ms'.format(next_try))


# Register retriable operation
@retry(evaluator=evaluator, on_retry=on_retry)
def fetch(url):
    return requests.get(url)


# Run task that might fail
fetch('http://server.com')

License

MIT - Tomas Aparicio

v0.3.0 / 2023-05-20

  • Deprecate asyncio.corouting

  • Drop Python 2 and 3.4 support

v0.2.7 / 2018-08-24

  • Merge pull request #20 from ffix/forward-exception-instance

  • Correct linter warnings

  • Re-raise exception instance instead of new exception with no args

  • Merge pull request #19 from EdwardBetts/spelling

  • Correct spelling mistakes.

  • feat(setup): support Python 3.7

  • feat(History): add version changes

v0.2.6 / 2018-04-14

  • fix(#17): handle as legit retriable error Timeout exceptions.

v0.2.5 / 2018-03-21

  • Merge pull request #15 from jstasiak/allow-newer-six

  • Allow newer six

  • feat(History): update changes

v0.2.5 / 2018-03-21

  • Merge pull request #15 from jstasiak/allow-newer-six

  • Allow newer six

  • feat(History): update changes

v0.2.4 / 2018-03-20

  • merge(#14): Allow subsecond maxtimes for ExponentialBackoff

v0.2.3 / 2017-01-13

  • refactor(retry): remove unnecessary partial function

  • fix(retry): rename keyword param for partial application

  • feat(docs): improve description

  • refactor(Makefile): update publish task

v0.2.2 / 2017-01-06

  • feat(package): add wheel distribution

v0.2.1 / 2017-01-04

  • fix(retrier): remove debug print statement

v0.2.0 / 2017-01-02

  • feat(core): use seconds as default time unit (introduces API breaking changes)

  • refactor(examples): update examples to use new time unit

  • feat(contextmanager): adds context manager support

  • feat(examples): add context manager example

  • feat: add context managers support

v0.1.3 / 2016-12-30

  • refactor(async_retrier): simplify coroutine wrapper

  • feat(whitelist): add whitelist and blacklist support

  • feat(tests): add missing test cases for whitelist

  • feat(retry): pass error_evaluator param

  • fix(retrier): cast delay to float

  • fix(tests): use valid exception for Python 2.7

  • feat(#6): add custom error whilelist and custom error evaluator function

  • Merge pull request #8 from tsarpaul/master

  • refactor(decorator): do not expose retrier instance

v0.1.2 / 2016-12-27

  • fix(decorator): wrap retries instance per function call

v0.1.1 / 2016-12-27

  • fix(#2): handle and forward asyncio.CancelledError as non-retriable error

v0.1.0 / 2016-12-25

  • First version

Metadata

Release files for riprova 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for riprova 0.3.1
File Size Uploaded
riprova-0.3.1.tar.gz 20.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for riprova 0.3.1
File Interpreter ABI Platform
riprova-0.3.1-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 42.1 kB

Release files / riprova-0.3.1.tar.gz

Download URL riprova-0.3.1.tar.gz
Size 20.2 kB
Tags Source
SHA-256 checksum
How to use checksums
16017249bbc18dc654d9b8e8e34ff53bb82573aa05596d398e29c439f3163152
BLAKE2b-256 checksum
How to use checksums
2af7b163b617abc6057221eec8e37daf437a6b81db5279bee368748be8e2e5b1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.11

Release files / riprova-0.3.1-py2.py3-none-any.whl

Download URL riprova-0.3.1-py2.py3-none-any.whl
Size 21.9 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
fc1bd9bfd8befd453e322b2111839ecb3a0ccabb8af6ff10c5942f1a2143f807
BLAKE2b-256 checksum
How to use checksums
176139b608b848bd1f4028f2fd3be1b1e38da625eecb248f19416af8fd2a7e20
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.2 CPython/3.10.11

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

1 release file

0.2.0

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.1.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page