Skip to main content

Retries for humans

Project description

Opnieuw

Opnieuw is a general-purpose retrying library, written in Python, in order to simplify the task of adding retry behavior to both synchronous as well as asynchronous tasks. Opnieuw is easy and straightforward to use.

Opnieuw makes it easy to add robust retries:

  • There is a single retry strategy, exponential backoff with jitter, which makes it impossible to forget to add jitter.
  • It has just two parameters, to eliminate the possibility of invalid and nonsensical combinations.
  • Parameters are named clearly, to avoid confusing e.g. number of calls (including the initial one) with number of retries (excluding the initial call).
  • The parameters are intuitive: instead of configuring the base delay for exponential backoff, Opnieuw accepts a maximum number of calls to make, and maximum time after the first call to still retry.
  • Time units are clear from parameter names to make the decorated code obvious, and readable without needing to refer to documentation.

See our announcement post for a bit more background on why we wrote Opnieuw.

Example

Suppose we want to parse https://tech.channable.com/atom.xml and we want to add a retry to handle a specific network Exception. We can add Opnieuw to our network handler as follows:

import requests
from requests.exceptions import ConnectionError, HTTPError

from opnieuw import retry

@retry(
    retry_on_exceptions=(ConnectionError, HTTPError),
    max_calls_total=4,
    retry_window_after_first_call_in_seconds=60,
)
def get_page() -> str:
    response = requests.get('https://tech.channable.com/atom.xml')
    return response.text
  • retry_on_exceptions specifies which exceptions we want to retry on.

  • max_calls_total is the maximum number of times that the decorated function gets called, including the initial call.

  • retry_window_after_first_call_in_seconds is the maximum number of seconds after the first call was initiated, where we would still do a new attempt.

Features

  • Generic decorator API
  • Specify retry exception (i.e. type of exception that we want retry)
  • Exponential backoff with jitter
  • Pre-shipped list of popular exceptions, which can easily be expanded

Installation

To install Opnieuw, simply:

$ pip install opnieuw

More examples

The short example above provides a concise demonstration of how Opnieuw could be used. Let's dig deeper into Opnieuw and add another exception to retry_on_exceptions to do a retry on:

from urllib.error import URLError
import requests
from opnieuw import RetryException, retry

@retry(
    retry_on_exceptions=(ConnectionError, RetryException, URLError),
    max_calls_total=4,
    retry_window_after_first_call_in_seconds=60,
)
def get_page() -> str:
    response = requests.get('https://tech.channable.com/atom.xml')

    if response.status_code != 200:
        raise RetryException

    return response.text

We can pass the name of exception we want do retry for or a tuple of exceptions to the retry_on_exceptions. As mentioned earlier Opnieuw was developed to make it more convenient to add retry behavior to any task.

Let's make it a little bit more generic and define a list of retry exceptions that should trigger a retry of the function:

STANDARD_HTTP_EXCEPTIONS = (
    ConnectionError,
    ProtocolError,
    RetryException,
    ...
)

@retry(
    retry_on_exceptions=STANDARD_HTTP_EXCEPTIONS,
    max_calls_total=4,
    retry_window_after_first_call_in_seconds=60,
)
def get_page() -> str:
    response = requests.post('https://tech.channable.com/atom.xml')
    return response.text

Now our retry is more generic, as exceptions raised which are in STANDARD_HTTP_EXCEPTIONS will be retried.

If you want retry behavior for async tasks, then there is also an async retry which basically work the same way, but for async tasks.

Here is the example above but in async mode:

from opnieuw import retry_async

STANDARD_HTTP_EXCEPTIONS = (
    ConnectionError,
    EOFError,
    RetryException,
    ...
)

@retry_async(
    retry_on_exceptions=STANDARD_HTTP_EXCEPTIONS,
    max_calls_total=4,
    retry_window_after_first_call_in_seconds=60,
)
async def get_page() -> str:
    response = requests.get('https://tech.channable.com/atom.xml')
    return response.text

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

opnieuw-1.1.0.tar.gz (6.6 kB view details)

Uploaded Source

Built Distribution

opnieuw-1.1.0-py3-none-any.whl (8.9 kB view details)

Uploaded Python 3

File details

Details for the file opnieuw-1.1.0.tar.gz.

File metadata

  • Download URL: opnieuw-1.1.0.tar.gz
  • Upload date:
  • Size: 6.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/44.1.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/2.7.17

File hashes

Hashes for opnieuw-1.1.0.tar.gz
Algorithm Hash digest
SHA256 9fd38886d08ed1d77dd26f82a26d6de86f2d59b7894e559600a93408889278da
MD5 a09022e2a5e4467d9e4c8b006843f1d1
BLAKE2b-256 47686f2672f605ef05426070cda6d1b9e34f1af952e5bdf53be73872598375d0

See more details on using hashes here.

File details

Details for the file opnieuw-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: opnieuw-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/44.1.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/2.7.17

File hashes

Hashes for opnieuw-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b49b92dd7eb6b641d77a7fab21e06cdd6d9c8149410341d9523d28fb25b75d9e
MD5 824855155df77d0902ab26802686106c
BLAKE2b-256 9e3d29527e2a2e36a725c0c235a5131dced12fb53d8f84b55532c17867da3332

See more details on using hashes here.

Supported by

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