Total Complexity | 4 |
Total Lines | 47 |
Duplicated Lines | 0 % |
Changes | 0 |
1 | """Retry utilities module.""" |
||
2 | import logging |
||
3 | |||
4 | from functools import wraps |
||
5 | from typing import Callable |
||
6 | |||
7 | from tenacity import retry |
||
8 | |||
9 | |||
10 | LOG = logging.getLogger(__name__) |
||
11 | |||
12 | |||
13 | def before_sleep(state) -> None: |
||
14 | """Before sleep function for tenacity to also logs args and kwargs.""" |
||
15 | LOG.warning( |
||
16 | f"Retry #{state.attempt_number} for {state.fn.__name__}, " |
||
17 | f"args: {state.args}, kwargs: {state.kwargs}, " |
||
18 | f"seconds since start: {state.seconds_since_start:.2f}", |
||
19 | ) |
||
20 | |||
21 | |||
22 | def retries(func: Callable, **tenacity_kwargs) -> Callable: |
||
23 | """Retries decorator.""" |
||
24 | @retry(**tenacity_kwargs) |
||
25 | @wraps(func) |
||
26 | def decorated(*args, **kwargs): |
||
27 | return func(*args, **kwargs) |
||
28 | |||
29 | return decorated |
||
30 | |||
31 | |||
32 | def for_all_methods(decorator: Callable, **kwargs) -> Callable: |
||
33 | """Decorator for all methods.""" |
||
34 | |||
35 | def decorated(cls): |
||
36 | for attr in [ |
||
37 | name |
||
38 | for name in dir(cls) |
||
39 | if callable(getattr(cls, name)) |
||
40 | and not name.startswith("_") |
||
41 | and not hasattr(getattr(cls, name), "__wrapped__") |
||
42 | ]: |
||
43 | setattr(cls, attr, decorator(getattr(cls, attr), **kwargs)) |
||
44 | return cls |
||
45 | |||
46 | return decorated |
||
47 |