Retrying a python function when exceptions are raised
Project description
ReAttempt
ReAttempt is a python decorator to retry a function when exceptions are raised.
Demonstration:
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
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
# Install the dependency
pip install reattempt
uv add reattempt
poetry add reattempt
Usage
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 file for more details.
Contact
For questions, suggestions, or issues related to ReAttempt, please open an issue on the GitHub repository.
Project details
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 reattempt-1.1.1.tar.gz
.
File metadata
- Download URL: reattempt-1.1.1.tar.gz
- Upload date:
- Size: 43.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7c1b819f3110cd41564743b5dc15a6e14327c0242c65390c40a6f84e58ed1e92 |
|
MD5 | 3f6af492a544d40bfaf77ed2fe030a82 |
|
BLAKE2b-256 | 62809b4cfa3ee9fd02759b421b6b33aa9c8d02d31a252d33a9ed082cb7374ee3 |
File details
Details for the file reattempt-1.1.1-py3-none-any.whl
.
File metadata
- Download URL: reattempt-1.1.1-py3-none-any.whl
- Upload date:
- Size: 5.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | d5f14b4f1d14485339062296224cf1fe2ee28523c9a50d9166a5fa39acf77f8c |
|
MD5 | 043cf2b76c90a819fb5512a636774b7b |
|
BLAKE2b-256 | 8d5193b12a90183ebca00098203c861e6a26f89e7f31b0048b1c554891be9a7f |