Skip to content

Commit

Permalink
- default_stop_condition stops retrying after 3 attempts.
Browse files Browse the repository at this point in the history
- default_wait_condition waits 1 second between attempts.
- If no stop_condition or wait_condition is provided, the defaults will be used.
  • Loading branch information
talaatmagdyx committed Jun 7, 2024
1 parent 400ea2f commit 5505325
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 10 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@
- Customizable retry conditions based on exceptions and result values.
- Context manager support.
- Logging and custom callbacks before/after retries and before sleep.
- Retry statistics and dynamic arguments at runtime.
- Retry statistics and dynamic arguments at runtime.
## [1.0.4] - 2024-06-07
- default_stop_condition stops retrying after 3 attempts.
- default_wait_condition waits 1 second between attempts.
- If no stop_condition or wait_condition is provided, the defaults will be used.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,28 @@ except Exception as e:
print(f"Failed to fetch data after retries. Error: {e}")

```
## Default Conditions
If `stop_condition` and `wait_condition` are not provided, the following defaults will be used:

- Stop Condition: Stops after 3 attempts.
- Wait Condition: Waits 1 second between attempts.
```python
from retry import Retry
import time

@Retry()
def default_unreliable_function():
print("Trying to perform an unreliable operation.")
if time.time() % 2 < 1:
raise ValueError("Simulated transient error.")
return "Success"

try:
result = default_unreliable_function()
print(f"Function succeeded with result: {result}")
except Exception as e:
print(f"Function failed after retries with exception: {e}")
```

## Tests

Expand Down
31 changes: 31 additions & 0 deletions example/http_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import requests
from retry import Retry, stop_after_attempt, wait_exponential

# Define a function to make an HTTP request
@Retry(
# stop_condition=stop_after_attempt(5), # Retry up to 5 times
# wait_condition=wait_exponential(multiplier=1, min_wait=1, max_wait=10), # Exponential backoff
retry_on_exceptions=(requests.RequestException,), # Retry on any requests exception
retry_on_result=lambda result: result.status_code != 200 # Retry if the status code is not 200
)
def fetch_data_from_api(url):
print(f"Trying to fetch data from {url}")
response = requests.get(url)
response.raise_for_status() # Raise an HTTPError on bad status
return response

# Use the function with a simulated unreliable endpoint
try:
# Simulating a service that returns 500 Internal Server Error 50% of the time
data = fetch_data_from_api("https://httpbin.org/status/500")
print("Data fetched successfully:", data)
except Exception as e:
print(f"Failed to fetch data after retries. Error: {e}")

# Use the function with a simulated successful endpoint
try:
# Simulating a service that returns 200 OK
data = fetch_data_from_api("https://httpbin.org/status/200")
print("Data fetched successfully:", data)
except Exception as e:
print(f"Failed to fetch data after retries. Error: {e}")
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "retry_plus"
version = "1.0.3"
version = "1.0.4"
description = "A generic retry package for Python"
readme = "README.md"
authors = [
Expand Down
20 changes: 14 additions & 6 deletions retry/retry.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class Retry:
Retry decorator and context manager to retry operations based on specified conditions.
Args:
stop_condition: Callable that determines when to stop retrying.
wait_condition: Callable that determines how long to wait between attempts.
stop_condition: Callable that determines when to stop retrying. Default stop condition: stops after 3 attempts.
wait_condition: Callable that determines how long to wait between attempts. Default wait condition: waits 1 second between attempts.
retry_on_exceptions: Tuple of exception types that trigger a retry.
retry_on_result: Callable that determines if the result should trigger a retry.
before: Callable executed before each attempt.
Expand All @@ -36,23 +36,31 @@ class Retry:
"""

def __init__(self,
stop_condition: Callable[[int, Optional[Exception], Optional[Any]], bool],
wait_condition: Callable[[int], float],
stop_condition: Callable[[int, Optional[Exception], Optional[Any]], bool] = None,
wait_condition: Callable[[int], float] = None,
retry_on_exceptions: Tuple[Type[Exception], ...] = (Exception,),
retry_on_result: Optional[Callable[[Any], bool]] = None,
before: Optional[Callable] = None,
after: Optional[Callable] = None,
before_sleep: Optional[Callable] = None,
reraise: bool = False):
self.stop_condition = stop_condition # Storing the stop condition function
self.wait_condition = wait_condition # Storing the wait condition function
self.stop_condition = stop_condition if stop_condition is not None else self.default_stop_condition
self.wait_condition = wait_condition if wait_condition is not None else self.default_wait_condition
self.retry_on_exceptions = retry_on_exceptions # Storing the exceptions that trigger a retry
self.retry_on_result = retry_on_result # Storing the result-based retry condition
self.before = before # Storing the before attempt callback
self.after = after # Storing the after attempt callback
self.before_sleep = before_sleep # Storing the before sleep callback
self.reraise = reraise # Storing the reraise flag

def default_stop_condition(self, attempt: int, exception: Optional[Exception], result: Optional[Any]) -> bool:
"""Default stop condition: stops after 3 attempts."""
return attempt >= 3

def default_wait_condition(self, attempt: int) -> float:
"""Default wait condition: waits 1 second between attempts."""
return 1.0

def __call__(self, func: Callable):
"""
Wraps the function with retry logic.
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = retry_plus
version = 1.0.3
version = 1.0.4
description = A generic retry package for Python
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='retry_plus',
version='1.0.3',
version='1.0.4',
description='A generic retry package for Python',
long_description=long_description,
long_description_content_type='text/markdown',
Expand Down

0 comments on commit 5505325

Please sign in to comment.