Package: rever
Rever, A retrying decoratorA retry decorator can be useful in many situations.  One example is when scraping web pages.
Suppose you have a function that retrieves the status code response of a GET request.  If the status
code returns 200, then you are happy.  But if not, then there here is what you might do:You could write your retrying logic directly into your functions>>> def get_response(webpage):
>>>     response = function_to_get_webpage(webpage)
>>>     status_code = function_to_get_status_code(response)
>>>     if status_code == 200:
>>>         return status_code
>>>     else:
>>>         time.sleep(3)
>>>         num_tries -= 1
>>>         if num_tries > 0:
>>>             return get_response(webpage)
>>>
>>> if __name__ == "__main__":
>>>     num_tries = 2
>>>     get_response("http://www.google.com")You could use a retrying decorator like rever>>> from rever import rever
>>> @rever(times=2, pause=3, exception=MyException, raises=False)
>>> def get_response(webpage):
>>>     response = function_to_get_webpage(webpage)
>>>     status_code = function_to_get_status_code(response)
>>>     if status_code == 200:
>>>         return status_code
>>>     else:
>>>         raise MyException
>>>
>>> if __name__ == "__main__":
>>>     get_response("http://www.google.com")In the first example, you need to write out the retrying logic yourself.  The second
example it is taken care of in the decorator; a nice way of keeping things separate.Installation$ pip install reverKeyword ArgumentsThe rever decorator takes only keyword arguments.Possible keyword arguments:backoff:description:  if True subsequent pauses for each retry will increase exponentiallypossible values:  booleantotal_pause:description:  the total time you are willing to wait for all of your pauses between retryspossible values: integer or floatsteps:description:  related to backoff and is set at 10 because wikipedia says so:https://en.wikipedia.org/wiki/Exponential_backoffpossible values:  integerexception:description:   you can choose which exception or exceptions to catchpossible values:  any Exception that gets raised by Pythonraises:description:  if all the retrys fail, do you want to raise an exception or not?possible values:  booleanprior:description:  if you want to call another function/script prior to retrying, you can do so but without any args or kwargspossible values:  a simple function…cannot take args or kwargsThese arguments are used if *backoff* is set to False:times:description:  the number of times you want the function to retrypossible values:  integerpause:description:  the number of seconds you want to pause before your function retryspossible values:  integer or floatExamples & ExplanationdefaultDefault behavior>>> @rever()rever will use exponential backoffrever will have a total pause time of 30 seconds (total time your function will pause)rever will have 10 steps (steps here means the number of times your function will retry)rever will catch any exceptionrever will ultimately raise an exception if all retrys failexceptionCatch one specific exception>>> @rever(exception=TypeError)
>>> @rever(exception=(TypeError, ))rever will use exponential backoffrever will have a total pause time of 30 seconds (total time your function will pause)rever will have 10 steps (steps here means the number of times your function will retry)rever will catch onlyTypeErrorrever will ultimately raise an exception if all retrys failCatch one of multiple specific exceptions>>> @rever(exception=(TypeError, ConnectionError))rever will use exponential backoffrever will have a total pause time of 30 seconds (total time your function will pause)rever will have 10 steps (steps here means the number of times your function will retry)rever will catch any of onlyTypeErrororConnectionErrorrever will ultimately raise an exception if all retrys failraisesRaise an exception or do not>>> @rever(raises=False)rever will use exponential backoffrever will have a total pause time of 30 seconds (total time your function will pause)rever will have 10 steps (steps here means the number of times your function will retry)rever will catch any exceptionrever will ultimatelynotraise an exception if all retrys failpriorCall a function prior to retrying>>> @rever(prior=some_function_to_call_prior_to_retyring)rever will use exponential backoffrever will have a total pause time of 30 seconds (total time your function will pause)rever will have 10 steps (steps here means the number of times your function will retry)rever will catch any exceptionrever will ultimately raise an exception if all retrys failrever will call some function prior to each retryBelow used only if backoff is set to False, it is included for backwards compatibilitytimesRetry a certain number of times>>> @rever(backoff=False, times=10)rever willnotuse exponential backoffrever will have a total pause time of0seconds (total time your function will pause)rever will retry1time (time here means the number of times your function will retry)rever will catch any exceptionrever will ultimately raise an exception if all retrys failpausePause for some number of seconds between each retry>>> @rever(backoff=False, pause=5)rever willnotuse exponential backoffrever will have a total pause time of5seconds (total time your function will pause)rever will retry1time (time here means the number of times your function will retry)rever will catch any exceptionrever will ultimately raise an exception if all retrys failYou can basically use any combination of keywords you would likeTestingTo run tests, clone the github repository:$ git clonehttps://github.com/liamcryan/rever$ cd rever
$ pip install pytest
$ pytestHistoryversion 0.3.3 (5/12/2020)fix bad link in __version__version 0.3.2 (5/12/2020)fix non-local rever_kwargschange structure from multiple to files to one __init__ fileupdate README.rst with installation instructionsversion 0.3.1 (7/13/2018)found bug when calling the same decorated function multiple times.  In certain cases the ‘times’ keyword argument decreased to 0 triggering a ReachedMaxRetries exception despite the function only being called onceversion 0.3.0 (8/23/2017)wanted to modify behaviour to exponential backoff as default rather than fixed intervals between retrysto replicate functionality of previous versions include a kwarg backoff=False in your decoratorversion 0.2.1 (8/8/2017)realized that any function wanting to return any value would return None, so fixed that :)version 0.2.0 (6/26/2017)specify a function to call prior to retryingrealized that the retry count was off by 1, now it should be correctversion 0.1.0 (6/24/2017)specify whether to raise exception after all retry attemptsincluded some testingdefault pause is now zero secondsversion 0.0.1 (6/23/2017)retry decoratorspecify number of times to retryspecify number of seconds to waitspecify which exceptions to catch