Package: 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.importrandomfromretryingimportretry@retrydefdo_something_unreliable():ifrandom.randint(0,10)>1:raiseIOError("Broken sauce, everything is hosed!!!111one")else:return"Awesome sauce!"printdo_something_unreliable()FeaturesGeneric Decorator APISpecify stop condition (i.e. limit by number of attempts)Specify wait condition (i.e. exponential backoff sleeping between attempts)Customize retrying on ExceptionsCustomize retrying on expected returned resultExamplesAs you saw above, the default behavior is to retry forever without waiting.@retrydefnever_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)defstop_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)defstop_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)defwait_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)defwait_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)defwait_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.defretry_if_io_error(exception):"""Return True if we should retry (in this case when it's an IOError), False otherwise"""returnisinstance(exception,IOError)@retry(retry_on_exception=retry_if_io_error)defmight_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)defonly_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.defretry_if_result_none(result):"""Return True if we should retry (in this case when result is None), False otherwise"""returnresultisNone@retry(retry_on_result=retry_if_result_none)defmight_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.ContributeCheck for open issues or open a fresh issue to start a discussion around a feature idea or a bug.Forkthe repositoryon GitHub to start making your changes to themasterbranch (or branch off of it).Write a test which shows that the bug was fixed or that the feature works as expected.Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself toAUTHORS.History1.3.4 (2022-09-03)Added Greg Roodt as maintainerFormatted code with blackUpdated repository references1.3.3 (2014-12-14)Add minimum six version of 1.7.0 since anything less will break things1.3.2 (2014-11-09)Ensure we wrap the decorated functions to prevent information lossAllow a jitter value to be passed in1.3.1 (2014-09-30)Add requirements.txt to MANIFEST.in to fix pip installs1.3.0 (2014-09-30)Add upstream six dependency, remove embedded six functionality1.2.3 (2014-08-25)Add support for custom wait and stop functions1.2.2 (2014-06-20)Bug fix to not raise a RetryError on failure when exceptions aren’t being wrapped1.2.1 (2014-05-05)Bug fix for explicitly passing in a wait type1.2.0 (2014-05-04)Remove the need for explicit specification of stop/wait types when they can be inferredAdd a little checking for exception propagation1.1.0 (2014-03-31)Added proper exception propagation through reraising with Python 2.6, 2.7, and 3.2 compatibilityUpdate test suite for behavior changes1.0.1 (2013-03-20)Fixed a bug where classes not extending from the Python exception hierarchy could slip throughUpdate test suite for custom Python exceptions1.0.0 (2013-01-21)First stable, tested version now existsApache 2.0 license appliedSanitizing some setup.py and test suite runningAdded Travis CI support