Skip to main content

Python retry utility

Project description

PyPi Version Travis Test Status

A simple way to auto retry a funciton that has the possibility of raising an error. You can either call retry directly or decorate a function to get it to retry. Intelligent matching logic allows you to retry certain exception while raising other exceptions.

Call a function directly:

from retrypy import retry, check

def dummy_func():
    print "dummy_func called..."
    raise Exception("House")

retry.call(
    dummy_func,
    times=2
)

dummy_func called...
dummy_func called...
Exception: House

# usign a check method
retry.call(
    dummy_func,
    check = check.message_equals("foobar")
)
dummy_func called...
Exception: House

Decorating a function:

# Only retry IOErrors
@retry.decorate(IOError, times=2)
def dummy_func():
    print "dummy_func called..."
    raise IOError("House")
dummy_func()

dummy_func called...
dummy_func called...
IOError: House

# Retry any Exception, use a custom wait function
@retry.decorate(times=2, wait=lambda n: 2*n)
def dummy_func():
    print "dummy_func called..."
    raise Exception("House")
dummy_func()

dummy_func called...
dummy_func called...
Exception: House

Wrap a function and return a new callable:

def dummy_func():
    print "dummy_func called..."
    raise Exception("House")

func = retry.wrap(
    dummy_func,
    times=2
)
func()

dummy_func called...
dummy_func called...
Exception: House

Delay Helpers:

Functions to implement some common backoff strategies: random, exponential, and incremental.

Random:

import time
from retrypy import retry, delay

def dummy_func():
    print time.time()
    raise Exception("House")

retry.call(dummy_func, wait=delay.random(
    min_seconds=1,
    max_seconds=5,
))

Output (wait times: .66s, .84s, 3.42s, .33s):

1423297137.49
1423297138.15
1423297138.99
1423297142.41
1423297142.74
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "retrypy/retry.py", line 63, in call
    wait,
  File "retrypy/retry.py", line 29, in _retry
    raise previous_exception
Exception: House

Exponential:

import time
from retrypy import retry, delay

def dummy_func():
    print time.time()
    raise Exception("House")

retry.call(dummy_func, wait=delay.exponential(
    start_at=1,
))

Output (wait times: 1s, 2s, 4s, 8s):

1423297238.49
1423297239.49
1423297241.49
1423297245.5
1423297253.5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "retrypy/retry.py", line 63, in call
    wait,
  File "retrypy/retry.py", line 29, in _retry
    raise previous_exception
Exception: House

Incremental:

import time
from retrypy import retry, delay

def dummy_func():
    print time.time()
    raise Exception("House")

retry.call(dummy_func, wait=delay.incremental(
  start_at=1,
  step=1,
))

Output (wait times: 1s, 2s, 3s, 4s):

1423297301.64
1423297302.64
1423297304.64
1423297307.65
1423297311.65
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "retrypy/retry.py", line 63, in call
    wait,
  File "retrypy/retry.py", line 29, in _retry
    raise previous_exception
Exception: House

Custom Delay Functions:

You can write your own delay functions, their only requirements are that they take an Integer and return a Number of seconds to wait.

def custom_delay(call_count):
    if call_count == 1:
        # don't wait at all the first time
        return 0

    # wait 4, 8, 16, 32
    return 2 ** call_count

Builtin Exception Checkers:

Exception Checkers can be used to check if you want to retry a specific exception. If the check function returns true then the exception is retryable otherwise we will not catch the exception and retry. The available checkers are: message_equals, message_contains, and message_matches.

message_equals, will match any Exception with a message that is identical to the string provided.

message_contains, will match any Exception with a message that contains the string provided.

message_matches, will match any Exception with a message that matches the regex provided. The regex may be passed as a string or a compiled regex pattern.

Custom Exception Checkers:

You can write your own exception checkers, their only requirements are that they: take an Exception and an Integer as parameters. They should return True if the exception is retryable otherwise False.

def custom_matcher(e, call_count):
    # never fail their first time no matter what
    if call_count == 1:
        return True

    # only retry errors with Bob Barker in the message.
    return "Bob Barker" in str(e):

Installation:

>> pip install retrypy

Development:

>> git clone https://github.com/toddsifleet/retrypy
>> cd retrypy
>> make bootstrap
>> make

License:

See LICENSE

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

retrypy-0.0.33.tar.gz (5.9 kB view details)

Uploaded Source

File details

Details for the file retrypy-0.0.33.tar.gz.

File metadata

  • Download URL: retrypy-0.0.33.tar.gz
  • Upload date:
  • Size: 5.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for retrypy-0.0.33.tar.gz
Algorithm Hash digest
SHA256 08693b096f0eaad6534e31fd7e82f6fdc854c49de642302ab26bb6d9c1e38a86
MD5 fa25c8172492d7968c662d122a5d9660
BLAKE2b-256 2933a6171d4a2b1761c4492a6bf1d7e91f1051524868e95fc5095c8d1e1ffe97

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