• Stars
    star
    1,910
  • Rank 24,116 (Top 0.5 %)
  • Language
    Python
  • License
    Apache License 2.0
  • Created over 11 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Retrying is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simplify the task of adding retry behavior to just about anything.

Retrying

Retrying is an Apache 2.0 licensed general-purpose retrying library, written in Python, to simplify the task of adding retry behavior to just about anything.

The simplest use case is retrying a flaky function whenever an Exception occurs until a value is returned.

import random
from retrying import retry

@retry
def do_something_unreliable():
    if random.randint(0, 10) > 1:
        raise IOError("Broken sauce, everything is hosed!!!111one")
    else:
        return "Awesome sauce!"

print do_something_unreliable()

Features

  • Generic Decorator API
  • Specify stop condition (i.e. limit by number of attempts)
  • Specify wait condition (i.e. exponential backoff sleeping between attempts)
  • Customize retrying on Exceptions
  • Customize retrying on expected returned result

Installation

To install retrying, simply:

$ pip install retrying

Or, if you absolutely must:

$ easy_install retrying

But, you might regret that later.

Examples

As you saw above, the default behavior is to retry forever without waiting.

@retry
def never_give_up_never_surrender():
    print "Retry forever ignoring Exceptions, don't wait between retries"

Let's be a little less persistent and set some boundaries, such as the number of attempts before giving up.

@retry(stop_max_attempt_number=7)
def stop_after_7_attempts():
    print "Stopping after 7 attempts"

We don't have all day, so let's set a boundary for how long we should be retrying stuff.

@retry(stop_max_delay=10000)
def stop_after_10_s():
    print "Stopping after 10 seconds"

Most things don't like to be polled as fast as possible, so let's just wait 2 seconds between retries.

@retry(wait_fixed=2000)
def wait_2_s():
    print "Wait 2 second between retries"

Some things perform best with a bit of randomness injected.

@retry(wait_random_min=1000, wait_random_max=2000)
def wait_random_1_to_2_s():
    print "Randomly wait 1 to 2 seconds between retries"

Then again, it's hard to beat exponential backoff when retrying distributed services and other remote endpoints.

@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)
def wait_exponential_1000():
    print "Wait 2^x * 1000 milliseconds between each retry, up to 10 seconds, then 10 seconds afterwards"

We have a few options for dealing with retries that raise specific or general exceptions, as in the cases here.

def retry_if_io_error(exception):
    """Return True if we should retry (in this case when it's an IOError), False otherwise"""
    return isinstance(exception, IOError)

@retry(retry_on_exception=retry_if_io_error)
def might_io_error():
    print "Retry forever with no wait if an IOError occurs, raise any other errors"

@retry(retry_on_exception=retry_if_io_error, wrap_exception=True)
def only_raise_retry_error_when_not_io_error():
    print "Retry forever with no wait if an IOError occurs, raise any other errors wrapped in RetryError"

We can also use the result of the function to alter the behavior of retrying.

def retry_if_result_none(result):
    """Return True if we should retry (in this case when result is None), False otherwise"""
    return result is None

@retry(retry_on_result=retry_if_result_none)
def might_return_none():
    print "Retry forever ignoring Exceptions with no wait if return value is None"

Any combination of stop, wait, etc. is also supported to give you the freedom to mix and match.

Contribute

  1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
  2. Fork the repository on GitHub to start making your changes to the master branch (or branch off of it).
  3. Write a test which shows that the bug was fixed or that the feature works as expected.
  4. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to AUTHORS.

More Repositories

1

guava-retrying

This is a small extension to Google's Guava library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that talks to a remote service with flaky uptime.
Java
1,427
star
2

gradle-one-jar

The gradle-one-jar project is a Gradle plugin that uses One-JAR, a specialised Class-Loader written by Simon Tuffs (http://one-jar.sourceforge.net/), for building self-contained executable jars that include all dependencies.
Groovy
218
star
3

gradle-view

The Gradle View IntelliJ IDEA plugin shows a split tree rollup of the dependencies for each Gradle configuration in use by a project.
Java
179
star
4

csv2es

Load a CSV (or TSV) file into an Elasticsearch instance
Python
62
star
5

fauxflake

Fauxflake is an easily embeddable, decentralized, k-ordered unique ID generator.
Java
41
star
6

snowball-stemmer

This is a repackaging of a version of the snowball-stemmer found at http://snowball.tartarus.org/ so that it's available on Maven Central.
Java
19
star
7

nilsimsa

This module contains an implementation of the Nilsimsa locality-sensitive hashing algorithm in Java.
Java
18
star
8

debinate

Roll up your projects into little standalone Debian packages.
Shell
14
star
9

gradle-autojar

The gradle-autojar project is a Gradle plugin that uses Autojar, a specialized jar archive minimizer written by Bernd Eggink (http://autojar.sourceforge.net/), for building self-contained executable jars that include only those dependencies that are actually used.
Groovy
14
star
10

esthree

An S3 client that just works
Java
8
star
11

i3status-title-on-bar

Inject the active window title into the output of i3status.
Go
8
star
12

sshuttle-binary

This is a single-binary package of sshuttle.
Python
7
star
13

jvm-loop-unswitching-bug

Cause the JVM to produce a segmentation fault from org.apache.http.impl.cookie.BestMatchSpec.formatCookies
Java
7
star
14

dynq

Dynq is a DynamoDB client intended to make querying and sourcing environment variables from the commandline very easy.
Python
6
star
15

jfpm

Run fpm (which lets you build RPM's, DEB's, etc.) from a single standalone binary using the JVM.
Shell
6
star
16

grepby

Output counts of matching regular expressions like a group by for grep.
Go
5
star
17

gradle-wrapper-here

Drop a Gradle wrapper in the current directory.
Shell
4
star
18

moar-concurrent

This module contains a collection of useful builders and concurrency classes to assist in modeling complex or overly tweakable concurrent processing pipelines.
Java
4
star
19

oggtrackutil

This is a simple audio extraction utility written during a weekend to extract well-formed, single track WAV files from any compressed Ogg Vorbis audio file including those with more than 8 tracks.
C
3
star
20

ns4600

This is a small Python module to control the Promise SmartStor NS4600 NAS server.
Python
2
star
21

jfss

Run fss, which lets you provision cloud infrastructure Chef-style with only shell scripts, from a single standalone binary using the JVM.
Java
1
star
22

laptop-sleep-tool

Tinker with sleep mode settings on your laptop with this little tool.
Shell
1
star
23

python-debian-packaging

This is a collection of slides, etc. for my Python and Debian packaging talk.
JavaScript
1
star
24

windowtools

This is a collection of scripts for manipulating windows on various Linux desktop environments.
Shell
1
star
25

rholder.github.com

JavaScript
1
star
26

cram-maven-plugin

1
star
27

transaction-binding

This project extracts some of the transactional binding functionality from Alfresco 3.2's core libraries, and it aims to rely on very minimal external runtime dependencies.
Java
1
star
28

uci-security

UCI Security is a derivative of RBAC that slightly rearranges the components found in a traditional access control system. It includes the familiar idea of roles to the extent that they are used to control the access a particular user has within the system, but also introduces a new way of thinking about how their relationship to a particular situation is relevant.
1
star