Rever, a retrying decorator
Project description
Rever, A retrying decorator
A 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 rever
Keyword Arguments
The rever decorator takes only keyword arguments.
Possible keyword arguments:
backoff:
description: if True subsequent pauses for each retry will increase exponentially
possible values: boolean
total_pause:
description: the total time you are willing to wait for all of your pauses between retrys
possible values: integer or float
steps:
description: related to backoff and is set at 10 because wikipedia says so: https://en.wikipedia.org/wiki/Exponential_backoff
possible values: integer
exception:
description: you can choose which exception or exceptions to catch
possible values: any Exception that gets raised by Python
raises:
description: if all the retrys fail, do you want to raise an exception or not?
possible values: boolean
prior:
description: if you want to call another function/script prior to retrying, you can do so but without any args or kwargs
possible values: a simple function…cannot take args or kwargs
These arguments are used if *backoff* is set to False:
times:
description: the number of times you want the function to retry
possible values: integer
pause:
description: the number of seconds you want to pause before your function retrys
possible values: integer or float
Examples & Explanation
- default
Default behavior
>>> @rever()
rever will use exponential backoff
rever 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 exception
rever will ultimately raise an exception if all retrys fail
- exception
Catch one specific exception
>>> @rever(exception=TypeError) >>> @rever(exception=(TypeError, ))
rever will use exponential backoff
rever 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 only TypeError
rever will ultimately raise an exception if all retrys fail
Catch one of multiple specific exceptions
>>> @rever(exception=(TypeError, ConnectionError))
rever will use exponential backoff
rever 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 only TypeError or ConnectionError
rever will ultimately raise an exception if all retrys fail
- raises
Raise an exception or do not
>>> @rever(raises=False)
rever will use exponential backoff
rever 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 exception
rever will ultimately not raise an exception if all retrys fail
- prior
Call a function prior to retrying
>>> @rever(prior=some_function_to_call_prior_to_retyring)
rever will use exponential backoff
rever 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 exception
rever will ultimately raise an exception if all retrys fail
rever will call some function prior to each retry
Below used only if backoff is set to False, it is included for backwards compatibility
- times
Retry a certain number of times
>>> @rever(backoff=False, times=10)
rever will not use exponential backoff
rever will have a total pause time of 0 seconds (total time your function will pause)
rever will retry 1 time (time here means the number of times your function will retry)
rever will catch any exception
rever will ultimately raise an exception if all retrys fail
- pause
Pause for some number of seconds between each retry
>>> @rever(backoff=False, pause=5)
rever will not use exponential backoff
rever will have a total pause time of 5 seconds (total time your function will pause)
rever will retry 1 time (time here means the number of times your function will retry)
rever will catch any exception
rever will ultimately raise an exception if all retrys fail
You can basically use any combination of keywords you would like
Testing
To run tests, clone the github repository:
$ git clone https://github.com/liamcryan/rever $ cd rever $ pip install pytest $ pytest
History
version 0.3.3 (5/12/2020)
fix bad link in __version__
version 0.3.2 (5/12/2020)
fix non-local rever_kwargs
change structure from multiple to files to one __init__ file
update README.rst with installation instructions
version 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 once
version 0.3.0 (8/23/2017)
wanted to modify behaviour to exponential backoff as default rather than fixed intervals between retrys
to replicate functionality of previous versions include a kwarg backoff=False in your decorator
version 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 retrying
realized that the retry count was off by 1, now it should be correct
version 0.1.0 (6/24/2017)
specify whether to raise exception after all retry attempts
included some testing
default pause is now zero seconds
version 0.0.1 (6/23/2017)
retry decorator
specify number of times to retry
specify number of seconds to wait
specify which exceptions to catch
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file rever-0.3.3.tar.gz
.
File metadata
- Download URL: rever-0.3.3.tar.gz
- Upload date:
- Size: 5.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 958559c8e2d9cdecb26e4184642f7a65e5c02051a1629d07d6b3ef0fc731539c |
|
MD5 | 48a177107c89cf6242ea54a09f2b8160 |
|
BLAKE2b-256 | bac7b3682f108bebcb455f2c56240a03e725d956c897ee947eca9f8257913cdf |
File details
Details for the file rever-0.3.3-py3-none-any.whl
.
File metadata
- Download URL: rever-0.3.3-py3-none-any.whl
- Upload date:
- Size: 5.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/40.8.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.7.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2b69bd02fab2b57cb29cd31c017a56d7546ea1a11896c327ca44d8693236b4b8 |
|
MD5 | 2fa0bb72195ee7b10e44f3232209f964 |
|
BLAKE2b-256 | 90b18253594d0027f74e6735540d8691c9b253e45e6259bda29e8f493772c05b |