reattempt


Namereattempt JSON
Version 1.1.3 PyPI version JSON
download
home_pageNone
SummaryRetrying a python function when exceptions are raised
upload_time2024-10-09 18:58:37
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords async async gen decorator exception handling exponential backoff generator python retry sync
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ReAttempt

ReAttempt is a python decorator to retry a function when exceptions are raised.

### Demonstration:

```python
from reattempt import reattempt

@reattempt(max_retries=5, min_time=0.1, max_time=2)
def simulate_network_failure():
    raise Exception("Connection timeout")

if __name__ == "__main__":
    simulate_network_failure()

------------------------------------------------------- live log call -------------------------------------------------------
WARNING  root:__init__.py:167 [RETRY] Attempt 1/5 failed, retrying in 0.17 seconds...
WARNING  root:__init__.py:167 [RETRY] Attempt 2/5 failed, retrying in 0.19 seconds...
WARNING  root:__init__.py:167 [RETRY] Attempt 3/5 failed, retrying in 0.19 seconds...
WARNING  root:__init__.py:167 [RETRY] Attempt 4/5 failed, retrying in 0.19 seconds...
WARNING  root:__init__.py:163 [RETRY] Attempt 5/5 failed, stopping
ERROR    root:__init__.py:177 [RETRY] Max retries reached
```

## Table of Contents

- [ReAttempt](#ReAttempt)
  - [Table of Contents](#table-of-contents)
  - [Description](#description)
  - [Installation](#installation)
  - [Usage](#usage)
  - [License](#license)
  - [Contact](#contact)

## Description

ReAttempt is a Python library that provides a decorator to automatically retry a function when exceptions are raised. It uses an exponential backoff strategy to wait between retries, ensuring that the function has multiple chances to succeed before ultimately failing.

## Installation

```bash
# Install the dependency
pip install reattempt
uv add reattempt
poetry add reattempt
```

## Usage

```python
from reattempt import reattempt
import asyncio
import random

# List of flowers for our examples
flowers = ["Rose", "Tulip", "Sunflower", "Daisy", "Lily"]

# Synchronous function example
@reattempt
def plant_flower():
    flower = random.choice(flowers)
    print(f"Attempting to plant a {flower}")
    if random.random() < 0.8:  # 80% chance of failure
        raise Exception(f"The {flower} didn't take root")
    return f"{flower} planted successfully"

# Synchronous generator example
@reattempt
def grow_flowers():
    for _ in range(3):
        flower = random.choice(flowers)
        print(f"Growing {flower}")
        yield flower
    if random.random() < 0.5:  # 50% chance of failure at the end
        raise Exception("The garden needs more fertilizer")

# Asynchronous function example
@reattempt
async def water_flower():
    flower = random.choice(flowers)
    print(f"Watering the {flower}")
    await asyncio.sleep(0.1)  # Simulating watering time
    if random.random() < 0.6:  # 60% chance of failure
        raise Exception(f"The {flower} needs more water")
    return f"{flower} is well-watered"

# Asynchronous generator function example
@reattempt
async def harvest_flowers():
    for _ in range(3):
        flower = random.choice(flowers)
        print(f"Harvesting {flower}")
        yield flower
        await asyncio.sleep(0.1)  # Time between harvests
    if random.random() < 0.4:  # 40% chance of failure at the end
        raise Exception("The garden needs more care")

async def tend_garden():
    # Plant a flower (sync function)
    try:
        result = plant_flower()
        print(result)
    except Exception as e:
        print(f"Planting error: {e}")

    # Grow flowers (sync generator)
    try:
        for flower in grow_flowers():
            print(f"Grown: {flower}")
    except Exception as e:
        print(f"Growing error: {e}")

    # Water a flower (async function)
    try:
        result = await water_flower()
        print(result)
    except Exception as e:
        print(f"Watering error: {e}")

    # Harvest flowers (async generator function)
    try:
        async for flower in harvest_flowers():
            print(f"Harvested: {flower}")
    except Exception as e:
        print(f"Harvesting error: {e}")

if __name__ == "__main__":
    asyncio.run(tend_garden())
```


## License

ReAttempt is released under the MIT License. See the [LICENSE](LICENSE) file for more details.

## Contact

For questions, suggestions, or issues related to ReAttempt, please open an issue on the GitHub repository.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "reattempt",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "async, async gen, decorator, exception handling, exponential backoff, generator, python, retry, sync",
    "author": null,
    "author_email": "Sylvain Mouquet <sylvain.mouquet@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/35/8d/a56393bbb21da5a63c359c516d6f065660984e49b6fda755a04e37d56c08/reattempt-1.1.3.tar.gz",
    "platform": null,
    "description": "# ReAttempt\n\nReAttempt is a python decorator to retry a function when exceptions are raised.\n\n### Demonstration:\n\n```python\nfrom reattempt import reattempt\n\n@reattempt(max_retries=5, min_time=0.1, max_time=2)\ndef simulate_network_failure():\n    raise Exception(\"Connection timeout\")\n\nif __name__ == \"__main__\":\n    simulate_network_failure()\n\n------------------------------------------------------- live log call -------------------------------------------------------\nWARNING  root:__init__.py:167 [RETRY] Attempt 1/5 failed, retrying in 0.17 seconds...\nWARNING  root:__init__.py:167 [RETRY] Attempt 2/5 failed, retrying in 0.19 seconds...\nWARNING  root:__init__.py:167 [RETRY] Attempt 3/5 failed, retrying in 0.19 seconds...\nWARNING  root:__init__.py:167 [RETRY] Attempt 4/5 failed, retrying in 0.19 seconds...\nWARNING  root:__init__.py:163 [RETRY] Attempt 5/5 failed, stopping\nERROR    root:__init__.py:177 [RETRY] Max retries reached\n```\n\n## Table of Contents\n\n- [ReAttempt](#ReAttempt)\n  - [Table of Contents](#table-of-contents)\n  - [Description](#description)\n  - [Installation](#installation)\n  - [Usage](#usage)\n  - [License](#license)\n  - [Contact](#contact)\n\n## Description\n\nReAttempt is a Python library that provides a decorator to automatically retry a function when exceptions are raised. It uses an exponential backoff strategy to wait between retries, ensuring that the function has multiple chances to succeed before ultimately failing.\n\n## Installation\n\n```bash\n# Install the dependency\npip install reattempt\nuv add reattempt\npoetry add reattempt\n```\n\n## Usage\n\n```python\nfrom reattempt import reattempt\nimport asyncio\nimport random\n\n# List of flowers for our examples\nflowers = [\"Rose\", \"Tulip\", \"Sunflower\", \"Daisy\", \"Lily\"]\n\n# Synchronous function example\n@reattempt\ndef plant_flower():\n    flower = random.choice(flowers)\n    print(f\"Attempting to plant a {flower}\")\n    if random.random() < 0.8:  # 80% chance of failure\n        raise Exception(f\"The {flower} didn't take root\")\n    return f\"{flower} planted successfully\"\n\n# Synchronous generator example\n@reattempt\ndef grow_flowers():\n    for _ in range(3):\n        flower = random.choice(flowers)\n        print(f\"Growing {flower}\")\n        yield flower\n    if random.random() < 0.5:  # 50% chance of failure at the end\n        raise Exception(\"The garden needs more fertilizer\")\n\n# Asynchronous function example\n@reattempt\nasync def water_flower():\n    flower = random.choice(flowers)\n    print(f\"Watering the {flower}\")\n    await asyncio.sleep(0.1)  # Simulating watering time\n    if random.random() < 0.6:  # 60% chance of failure\n        raise Exception(f\"The {flower} needs more water\")\n    return f\"{flower} is well-watered\"\n\n# Asynchronous generator function example\n@reattempt\nasync def harvest_flowers():\n    for _ in range(3):\n        flower = random.choice(flowers)\n        print(f\"Harvesting {flower}\")\n        yield flower\n        await asyncio.sleep(0.1)  # Time between harvests\n    if random.random() < 0.4:  # 40% chance of failure at the end\n        raise Exception(\"The garden needs more care\")\n\nasync def tend_garden():\n    # Plant a flower (sync function)\n    try:\n        result = plant_flower()\n        print(result)\n    except Exception as e:\n        print(f\"Planting error: {e}\")\n\n    # Grow flowers (sync generator)\n    try:\n        for flower in grow_flowers():\n            print(f\"Grown: {flower}\")\n    except Exception as e:\n        print(f\"Growing error: {e}\")\n\n    # Water a flower (async function)\n    try:\n        result = await water_flower()\n        print(result)\n    except Exception as e:\n        print(f\"Watering error: {e}\")\n\n    # Harvest flowers (async generator function)\n    try:\n        async for flower in harvest_flowers():\n            print(f\"Harvested: {flower}\")\n    except Exception as e:\n        print(f\"Harvesting error: {e}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(tend_garden())\n```\n\n\n## License\n\nReAttempt is released under the MIT License. See the [LICENSE](LICENSE) file for more details.\n\n## Contact\n\nFor questions, suggestions, or issues related to ReAttempt, please open an issue on the GitHub repository.\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Retrying a python function when exceptions are raised",
    "version": "1.1.3",
    "project_urls": {
        "changelog": "https://github.com/sylvainmouquet/reattempt/releases",
        "documentation": "https://github.com/sylvainmouquet/reattempt",
        "homepage": "https://github.com/sylvainmouquet/reattempt",
        "repository": "https://github.com/sylvainmouquet/reattempt"
    },
    "split_keywords": [
        "async",
        " async gen",
        " decorator",
        " exception handling",
        " exponential backoff",
        " generator",
        " python",
        " retry",
        " sync"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9518c9839bc6ed1a88dcfc58d0e9e119ddc3864289eeafa2ad01cc0384239e7c",
                "md5": "7043a530d578a04ac3d8745a9092c2a6",
                "sha256": "8c9193c7f6c4d186dc1475321c890e64306bfa6348bae91922baf1ba37b9241f"
            },
            "downloads": -1,
            "filename": "reattempt-1.1.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7043a530d578a04ac3d8745a9092c2a6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 5162,
            "upload_time": "2024-10-09T18:58:36",
            "upload_time_iso_8601": "2024-10-09T18:58:36.254653Z",
            "url": "https://files.pythonhosted.org/packages/95/18/c9839bc6ed1a88dcfc58d0e9e119ddc3864289eeafa2ad01cc0384239e7c/reattempt-1.1.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "358da56393bbb21da5a63c359c516d6f065660984e49b6fda755a04e37d56c08",
                "md5": "0b5f2292fd20717ace40f9121f08fe7a",
                "sha256": "de04b069bfb3e5bf09ccfec0163d93bc6ae0595badca43b7eb36483057996ff1"
            },
            "downloads": -1,
            "filename": "reattempt-1.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "0b5f2292fd20717ace40f9121f08fe7a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 44613,
            "upload_time": "2024-10-09T18:58:37",
            "upload_time_iso_8601": "2024-10-09T18:58:37.885411Z",
            "url": "https://files.pythonhosted.org/packages/35/8d/a56393bbb21da5a63c359c516d6f065660984e49b6fda755a04e37d56c08/reattempt-1.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-09 18:58:37",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "sylvainmouquet",
    "github_project": "reattempt",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "reattempt"
}
        
Elapsed time: 0.37482s