# the-retry
Retry decorator for both synchronous and asynchronous functions.
## Features
- No external dependencies.
- Supports asyncio. Works with both synchronous and asynchronous functions.
- Exponential backoff with jitter.
- Able to call custom function or await custom coroutine on exception occurs.
## Installation
```bash
pip install the-retry
```
## Decorator parameters
Arguments:
- `expected_exception`:
exception or tuple of exceptions (default BaseException).
Keyword arguments:
- `attempts`:
how much times the function will be retried, value -1 is infinite (default 2).
- `backoff`:
time interval between the `attemps` (default 0).
- `exponential_backoff`:
`current_backoff = backoff * 2 ** retries` (default False).
- `ignore_exceptions`:
only log error but not raise exception if `attempts` exceeds (default False).
- `jitter`:
maximum value of deviation from the `current_backoff` (default 0).
- `maximum_backoff`:
`current_backoff = min(current_backoff, maximum_backoff)` (default 0).
- `on_exception`:
function that called or await on error occurs (default None).
Be aware if a decorating function is synchronous `on_exception` function must be
synchronous too and accordingly for asynchronous function `on_exception` must be
asynchronous.
## Examples
### Immediately retry once without delay on any exception occurs
```python3
from the_retry import retry
@retry()
def some_function():
print("some function")
```
### Immediately retry once without delay on ValueError occurs with calling side effect function
```python3
from the_retry import retry
def side_effect():
print("side effect")
@retry(expected_exception=ValueError, on_exception=side_effect)
def some_function():
print("some function")
```
### Retry async function with 10 attempts with exponential backoff on ValueError or AttributeError occurs with calling side effect coroutine
```python3
from the_retry import retry
async def async_side_effect():
print("async side effect")
@retry(
expected_exception=(ValueError, AttributeError)
attempts=10,
backoff=1,
exponential_backoff=True,
jitter=1,
maximum_backoff=60,
on_exception=async_side_effect,
)
async def async_some_function():
print("some function")
```
Raw data
{
"_id": null,
"home_page": "https://gitlab.com/ramil.minnigaliev/the-retry",
"name": "the-retry",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6,<4.0",
"maintainer_email": "",
"keywords": "decorator,retry,async-retry",
"author": "Ramil Minnigaliev",
"author_email": "minnigaliev-r@yandex.ru",
"download_url": "https://files.pythonhosted.org/packages/2f/76/4cd9f60ec057d9548e404a209997fb236e435e96e382ca74b935997b1f4e/the-retry-0.1.1.tar.gz",
"platform": null,
"description": "# the-retry\n\nRetry decorator for both synchronous and asynchronous functions.\n\n## Features\n\n- No external dependencies.\n- Supports asyncio. Works with both synchronous and asynchronous functions.\n- Exponential backoff with jitter.\n- Able to call custom function or await custom coroutine on exception occurs.\n\n## Installation\n\n```bash\npip install the-retry\n```\n\n## Decorator parameters\n\nArguments:\n\n- `expected_exception`:\n exception or tuple of exceptions (default BaseException).\n\nKeyword arguments:\n\n- `attempts`:\n how much times the function will be retried, value -1 is infinite (default 2).\n- `backoff`:\n time interval between the `attemps` (default 0).\n- `exponential_backoff`:\n `current_backoff = backoff * 2 ** retries` (default False).\n- `ignore_exceptions`:\n only log error but not raise exception if `attempts` exceeds (default False).\n- `jitter`:\n maximum value of deviation from the `current_backoff` (default 0).\n- `maximum_backoff`:\n `current_backoff = min(current_backoff, maximum_backoff)` (default 0).\n- `on_exception`:\n function that called or await on error occurs (default None).\n Be aware if a decorating function is synchronous `on_exception` function must be\n synchronous too and accordingly for asynchronous function `on_exception` must be\n asynchronous.\n\n## Examples\n\n### Immediately retry once without delay on any exception occurs\n\n```python3\nfrom the_retry import retry\n\n@retry()\ndef some_function():\n print(\"some function\")\n```\n\n### Immediately retry once without delay on ValueError occurs with calling side effect function\n\n```python3\nfrom the_retry import retry\n\ndef side_effect():\n print(\"side effect\")\n\n@retry(expected_exception=ValueError, on_exception=side_effect)\ndef some_function():\n print(\"some function\")\n\n```\n\n### Retry async function with 10 attempts with exponential backoff on ValueError or AttributeError occurs with calling side effect coroutine\n\n```python3\nfrom the_retry import retry\n\nasync def async_side_effect():\n print(\"async side effect\")\n\n@retry(\n expected_exception=(ValueError, AttributeError)\n attempts=10,\n backoff=1,\n exponential_backoff=True,\n jitter=1,\n maximum_backoff=60,\n on_exception=async_side_effect,\n)\nasync def async_some_function():\n print(\"some function\")\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Retry decorator for both synchronous and asynchronous functions.",
"version": "0.1.1",
"split_keywords": [
"decorator",
"retry",
"async-retry"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5fcac240e3467db7832a5ea755da6b93b20b8a3347e8c5950f669d7eff41e21f",
"md5": "04bfb33e213185c57f06f654019b406d",
"sha256": "c5c3ad10629b255e47e5f9ade8314f34ca46aa723092a983f0b9f0232fa2220d"
},
"downloads": -1,
"filename": "the_retry-0.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "04bfb33e213185c57f06f654019b406d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6,<4.0",
"size": 4173,
"upload_time": "2023-01-16T10:15:28",
"upload_time_iso_8601": "2023-01-16T10:15:28.805545Z",
"url": "https://files.pythonhosted.org/packages/5f/ca/c240e3467db7832a5ea755da6b93b20b8a3347e8c5950f669d7eff41e21f/the_retry-0.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2f764cd9f60ec057d9548e404a209997fb236e435e96e382ca74b935997b1f4e",
"md5": "013a0f0c4231a772c19f0ba0409b6d57",
"sha256": "ab6b801adc3ef40c9ec6b2def3890621572ee1f33b51972503a1cb7e4759e687"
},
"downloads": -1,
"filename": "the-retry-0.1.1.tar.gz",
"has_sig": false,
"md5_digest": "013a0f0c4231a772c19f0ba0409b6d57",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6,<4.0",
"size": 3998,
"upload_time": "2023-01-16T10:15:27",
"upload_time_iso_8601": "2023-01-16T10:15:27.155469Z",
"url": "https://files.pythonhosted.org/packages/2f/76/4cd9f60ec057d9548e404a209997fb236e435e96e382ca74b935997b1f4e/the-retry-0.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-01-16 10:15:27",
"github": false,
"gitlab": true,
"bitbucket": false,
"gitlab_user": "ramil.minnigaliev",
"gitlab_project": "the-retry",
"lcname": "the-retry"
}