{"id":15442564,"url":"https://github.com/sylvainmouquet/reattempt","last_synced_at":"2025-08-04T08:34:01.285Z","repository":{"id":257802577,"uuid":"862222800","full_name":"sylvainmouquet/reattempt","owner":"sylvainmouquet","description":"Python library - Retry N times on failure - Functions sync/async and async generator","archived":false,"fork":false,"pushed_at":"2025-07-29T07:27:04.000Z","size":237,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-29T09:37:30.480Z","etag":null,"topics":["async","generator","library","python","reattempt","retry"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/reattempt","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sylvainmouquet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-09-24T08:41:08.000Z","updated_at":"2025-04-23T17:27:15.000Z","dependencies_parsed_at":"2024-09-27T10:38:44.771Z","dependency_job_id":"040a7f2d-3dc1-440a-9257-be61121d1588","html_url":"https://github.com/sylvainmouquet/reattempt","commit_stats":{"total_commits":10,"total_committers":1,"mean_commits":10.0,"dds":0.0,"last_synced_commit":"a625b3307d5a63c6fb825817f23cfd54beeaaca9"},"previous_names":["sylvainmouquet/reattempt"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/sylvainmouquet/reattempt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sylvainmouquet%2Freattempt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sylvainmouquet%2Freattempt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sylvainmouquet%2Freattempt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sylvainmouquet%2Freattempt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sylvainmouquet","download_url":"https://codeload.github.com/sylvainmouquet/reattempt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sylvainmouquet%2Freattempt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268669989,"owners_count":24287892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-04T02:00:09.867Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["async","generator","library","python","reattempt","retry"],"created_at":"2024-10-01T19:28:36.860Z","updated_at":"2025-08-04T08:34:01.124Z","avatar_url":"https://github.com/sylvainmouquet.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 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() \u003c 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() \u003c 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() \u003c 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() \u003c 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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsylvainmouquet%2Freattempt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsylvainmouquet%2Freattempt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsylvainmouquet%2Freattempt/lists"}