Skip to content

Commit a36868c

Browse files
authored
Merge pull request #6 from community-of-python/fix-wo-redis
fix using without redis
2 parents 96c6cc8 + 9cdd65c commit a36868c

File tree

6 files changed

+46
-38
lines changed

6 files changed

+46
-38
lines changed

.github/workflows/workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ jobs:
1616
uses: community-of-python/community-workflow/.github/workflows/preset.yml@main
1717
with:
1818
python-version: '["3.10","3.11","3.12","3.13"]'
19-
secrets: inherit
19+
secrets: inherit

README.md

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -70,55 +70,57 @@ if __name__ == "__main__":
7070
```
7171

7272
### Retrier
73+
7374
```python
7475
import asyncio
7576
import logging
7677

7778
import httpx
7879
import tenacity
7980

80-
from circuit_breaker_box.retryer import Retrier
81-
81+
from circuit_breaker_box.retrier import Retrier
8282

8383
MAX_RETRIES = 4
8484
SOME_HOST = "http://example.com/"
8585

8686

8787
async def main() -> None:
88-
"""
89-
Use Retrier with tenacity adjustments to automatically retry failed operations raising specific exceptions like:
90-
stop_rule
91-
retry_cause
92-
wait_strategy
88+
"""
89+
Use Retrier with tenacity adjustments to automatically retry failed operations raising specific exceptions like:
90+
stop_rule
91+
retry_cause
92+
wait_strategy
9393
94-
`foo` as example function will be retried immediately (no wait) when it raises ZeroDivisionError up to MAX_RETRIES
95-
After exceeding MAX_RETRIES attempts, the exception will propagate.
96-
"""
97-
logging.basicConfig(level=logging.DEBUG)
98-
retryer = Retrier[httpx.Response](
99-
stop_rule=tenacity.stop.stop_after_attempt(MAX_RETRIES),
100-
retry_cause=tenacity.retry_if_exception_type(ZeroDivisionError),
101-
wait_strategy=tenacity.wait_none(),
102-
)
103-
example_request = httpx.Request("GET", httpx.URL(SOME_HOST))
94+
`foo` as example function will be retried immediately (no wait) when it raises ZeroDivisionError up to MAX_RETRIES
95+
After exceeding MAX_RETRIES attempts, the exception will propagate.
96+
"""
97+
logging.basicConfig(level=logging.DEBUG)
98+
retryer = Retrier[httpx.Response](
99+
stop_rule=tenacity.stop.stop_after_attempt(MAX_RETRIES),
100+
retry_cause=tenacity.retry_if_exception_type(ZeroDivisionError),
101+
wait_strategy=tenacity.wait_none(),
102+
)
103+
example_request = httpx.Request("GET", httpx.URL(SOME_HOST))
104104

105-
async def foo(request: httpx.Request) -> httpx.Response:
106-
raise ZeroDivisionError(request)
105+
async def foo(request: httpx.Request) -> httpx.Response:
106+
raise ZeroDivisionError(request)
107107

108-
await retryer.retry(foo, request=example_request)
108+
await retryer.retry(foo, request=example_request)
109109

110110

111111
if __name__ == "__main__":
112-
asyncio.run(main())
113-
114-
115-
>>> INFO:circuit_breaker_box.retryer:Attempt: attempt_number: 1, outcome_timestamp: None
116-
>>> INFO:circuit_breaker_box.retryer:Attempt: attempt_number: 2, outcome_timestamp: None
117-
>>> INFO:circuit_breaker_box.retryer:Attempt: attempt_number: 3, outcome_timestamp: None
118-
>>> INFO:circuit_breaker_box.retryer:Attempt: attempt_number: 4, outcome_timestamp: None
119-
>>> Traceback (most recent call last):
120-
>>> ...
121-
>>> ZeroDivisionError: <Request('GET', 'http://example.com/')>
112+
asyncio.run(main())
113+
114+
>> > INFO: circuit_breaker_box.retryer:Attempt: attempt_number: 1, outcome_timestamp: None
115+
>> > INFO: circuit_breaker_box.retryer:Attempt: attempt_number: 2, outcome_timestamp: None
116+
>> > INFO: circuit_breaker_box.retryer:Attempt: attempt_number: 3, outcome_timestamp: None
117+
>> > INFO: circuit_breaker_box.retryer:Attempt: attempt_number: 4, outcome_timestamp: None
118+
>> > Traceback(most
119+
recent
120+
call
121+
last):
122+
>> > ...
123+
>> > ZeroDivisionError: < Request('GET', 'http://example.com/') >
122124
```
123125

124126
### Retrier with CircuitBreaker

circuit_breaker_box/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from circuit_breaker_box.circuit_breaker_redis import CircuitBreakerRedis
44
from circuit_breaker_box.common_types import ResponseType
55
from circuit_breaker_box.errors import BaseCircuitBreakerError, HostUnavailableError
6-
from circuit_breaker_box.retryer import Retrier
6+
from circuit_breaker_box.retrier import Retrier
77

88

99
__all__ = [

circuit_breaker_box/circuit_breaker_redis.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
import contextlib
12
import dataclasses
23
import logging
34
import typing
45

56
import tenacity
6-
from redis import asyncio as aioredis
7-
from redis.exceptions import ConnectionError as RedisConnectionError
8-
from redis.exceptions import WatchError
97

108
from circuit_breaker_box import BaseCircuitBreaker, errors
119

1210

11+
with contextlib.suppress(ImportError):
12+
from redis import asyncio as aioredis
13+
from redis.exceptions import ConnectionError as RedisConnectionError
14+
from redis.exceptions import WatchError
15+
16+
1317
logger = logging.getLogger(__name__)
1418

1519

circuit_breaker_box/retryer.py renamed to circuit_breaker_box/retrier.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Retrier(abc.ABC, typing.Generic[ResponseType]):
2222
retry_cause: retry_clause_types
2323
circuit_breaker: BaseCircuitBreaker | None = None
2424

25-
async def retry( # type: ignore[return]
25+
async def retry(
2626
self,
2727
coroutine: typing.Callable[P, typing.Awaitable[ResponseType]],
2828
/,
@@ -34,7 +34,7 @@ async def retry( # type: ignore[return]
3434
msg = "'host' argument should be defined"
3535
raise ValueError(msg)
3636

37-
for attempt in tenacity.Retrying( # noqa: RET503
37+
for attempt in tenacity.Retrying(
3838
stop=self.stop_rule,
3939
wait=self.wait_strategy,
4040
retry=self.retry_cause,
@@ -51,6 +51,8 @@ async def retry( # type: ignore[return]
5151
await self.circuit_breaker.increment_failures_count(host)
5252

5353
return await coroutine(*args, **kwargs)
54+
msg = "Unreachable section" # pragma: no cover
55+
raise RuntimeError(msg) # pragma: no cover
5456

5557
@staticmethod
5658
def do_before_attempts(retry_state: tenacity.RetryCallState) -> None:

examples/example_retry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import httpx
55
import tenacity
66

7-
from circuit_breaker_box.retryer import Retrier
7+
from circuit_breaker_box.retrier import Retrier
88

99

1010
MAX_RETRIES = 4

0 commit comments

Comments
 (0)