Name | retrying JSON |
Version |
1.4.2
JSON |
| download |
home_page | None |
Summary | Retrying |
upload_time | 2025-08-03 03:35:25 |
maintainer | None |
docs_url | None |
author | Alex Kuang, Anthony McClosky, Cyrus Durgin, Daniel Nephin, Dougal Matthews, Greg Roodt, Haïkel Guémar, Hugo Klepsch, J Derek Wilson, James Page, Jason Dunkelberger, Job Evers, Jonathan Herriott, Josh Marshall, Joshua Harlow, Justin Turner Arthur, Maxym Shalenyi, Monty Taylor, Pierre-Yves Chibon, Ray Holder, Rees Dooley, Saul Shanabrook, Simon Dollé, Simeon Visser, Thomas Goirand |
requires_python | >=3.6 |
license | None |
keywords |
decorator
decorators
retry
retrying
exception
exponential
backoff
|
VCS |
 |
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# 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.
```python
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
## Examples
As you saw above, the default behavior is to retry forever without waiting.
```python
@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.
```python
@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.
```python
@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.
```python
@retry(wait_fixed=2000)
def wait_2_s():
print("Wait 2 second between retries")
```
Some things perform best with a bit of randomness injected.
```python
@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.
```python
@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.
```python
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.
```python
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](http://github.com/groodt/retrying) 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 the authors list in pyproject.toml.
Raw data
{
"_id": null,
"home_page": null,
"name": "retrying",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": null,
"keywords": "decorator, decorators, retry, retrying, exception, exponential, backoff",
"author": "Alex Kuang, Anthony McClosky, Cyrus Durgin, Daniel Nephin, Dougal Matthews, Greg Roodt, Ha\u00efkel Gu\u00e9mar, Hugo Klepsch, J Derek Wilson, James Page, Jason Dunkelberger, Job Evers, Jonathan Herriott, Josh Marshall, Joshua Harlow, Justin Turner Arthur, Maxym Shalenyi, Monty Taylor, Pierre-Yves Chibon, Ray Holder, Rees Dooley, Saul Shanabrook, Simon Doll\u00e9, Simeon Visser, Thomas Goirand",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/c8/5a/b17e1e257d3e6f2e7758930e1256832c9ddd576f8631781e6a072914befa/retrying-1.4.2.tar.gz",
"platform": null,
"description": "# Retrying\n\nRetrying is an Apache 2.0 licensed general-purpose retrying library, written in\nPython, to simplify the task of adding retry behavior to just about anything.\n\nThe simplest use case is retrying a flaky function whenever an Exception occurs\nuntil a value is returned.\n\n```python\nimport random\nfrom retrying import retry\n\n@retry\ndef do_something_unreliable():\n if random.randint(0, 10) > 1:\n raise IOError(\"Broken sauce, everything is hosed!!!111one\")\n else:\n return \"Awesome sauce!\"\n\nprint(do_something_unreliable())\n```\n\n## Features\n\n- Generic Decorator API\n- Specify stop condition (i.e. limit by number of attempts)\n- Specify wait condition (i.e. exponential backoff sleeping between attempts)\n- Customize retrying on Exceptions\n- Customize retrying on expected returned result\n\n## Examples\n\nAs you saw above, the default behavior is to retry forever without waiting.\n\n```python\n@retry\ndef never_give_up_never_surrender():\n print(\"Retry forever ignoring Exceptions, don't wait between retries\")\n```\n\nLet's be a little less persistent and set some boundaries, such as the number of attempts before giving up.\n\n```python\n@retry(stop_max_attempt_number=7)\ndef stop_after_7_attempts():\n print(\"Stopping after 7 attempts\")\n```\n\nWe don't have all day, so let's set a boundary for how long we should be retrying stuff.\n\n```python\n@retry(stop_max_delay=10000)\ndef stop_after_10_s():\n print(\"Stopping after 10 seconds\")\n```\n\nMost things don't like to be polled as fast as possible, so let's just wait 2 seconds between retries.\n\n```python\n@retry(wait_fixed=2000)\ndef wait_2_s():\n print(\"Wait 2 second between retries\")\n```\n\nSome things perform best with a bit of randomness injected.\n\n```python\n@retry(wait_random_min=1000, wait_random_max=2000)\ndef wait_random_1_to_2_s():\n print(\"Randomly wait 1 to 2 seconds between retries\")\n```\n\nThen again, it's hard to beat exponential backoff when retrying distributed services and other remote endpoints.\n\n```python\n@retry(wait_exponential_multiplier=1000, wait_exponential_max=10000)\ndef wait_exponential_1000():\n print(\"Wait 2^x * 1000 milliseconds between each retry, up to 10 seconds, then 10 seconds afterwards\")\n```\n\nWe have a few options for dealing with retries that raise specific or general exceptions, as in the cases here.\n\n```python\ndef retry_if_io_error(exception):\n \"\"\"Return True if we should retry (in this case when it's an IOError), False otherwise\"\"\"\n return isinstance(exception, IOError)\n\n@retry(retry_on_exception=retry_if_io_error)\ndef might_io_error():\n print(\"Retry forever with no wait if an IOError occurs, raise any other errors\")\n\n@retry(retry_on_exception=retry_if_io_error, wrap_exception=True)\ndef only_raise_retry_error_when_not_io_error():\n print(\"Retry forever with no wait if an IOError occurs, raise any other errors wrapped in RetryError\")\n```\n\nWe can also use the result of the function to alter the behavior of retrying.\n\n```python\ndef retry_if_result_none(result):\n \"\"\"Return True if we should retry (in this case when result is None), False otherwise\"\"\"\n return result is None\n\n@retry(retry_on_result=retry_if_result_none)\ndef might_return_none():\n print(\"Retry forever ignoring Exceptions with no wait if return value is None\")\n```\n\nAny combination of stop, wait, etc. is also supported to give you the freedom to mix and match.\n\n## Contribute\n\n1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.\n2. Fork [the repository](http://github.com/groodt/retrying) on GitHub to start making your changes to the **master** branch (or branch off of it).\n3. Write a test which shows that the bug was fixed or that the feature works as expected.\n4. Send a pull request and bug the maintainer until it gets merged and published. :) Make sure to add yourself to the authors list in pyproject.toml.\n",
"bugtrack_url": null,
"license": null,
"summary": "Retrying",
"version": "1.4.2",
"project_urls": {
"Homepage": "https://github.com/groodt/retrying",
"Repository": "https://github.com/groodt/retrying"
},
"split_keywords": [
"decorator",
" decorators",
" retry",
" retrying",
" exception",
" exponential",
" backoff"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "67f36cd296376653270ac1b423bb30bd70942d9916b6978c6f40472d6ac038e7",
"md5": "e698656f9d2b65563d50b3c6c9f51546",
"sha256": "bbc004aeb542a74f3569aeddf42a2516efefcdaff90df0eb38fbfbf19f179f59"
},
"downloads": -1,
"filename": "retrying-1.4.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "e698656f9d2b65563d50b3c6c9f51546",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6",
"size": 10859,
"upload_time": "2025-08-03T03:35:23",
"upload_time_iso_8601": "2025-08-03T03:35:23.829851Z",
"url": "https://files.pythonhosted.org/packages/67/f3/6cd296376653270ac1b423bb30bd70942d9916b6978c6f40472d6ac038e7/retrying-1.4.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "c85ab17e1e257d3e6f2e7758930e1256832c9ddd576f8631781e6a072914befa",
"md5": "f21de7ff40577f72d9a08dcc1604d2be",
"sha256": "d102e75d53d8d30b88562d45361d6c6c934da06fab31bd81c0420acb97a8ba39"
},
"downloads": -1,
"filename": "retrying-1.4.2.tar.gz",
"has_sig": false,
"md5_digest": "f21de7ff40577f72d9a08dcc1604d2be",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 11411,
"upload_time": "2025-08-03T03:35:25",
"upload_time_iso_8601": "2025-08-03T03:35:25.189544Z",
"url": "https://files.pythonhosted.org/packages/c8/5a/b17e1e257d3e6f2e7758930e1256832c9ddd576f8631781e6a072914befa/retrying-1.4.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-03 03:35:25",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "groodt",
"github_project": "retrying",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "retrying"
}