canonicalwebteam.store-api 6.8.0__py3-none-any.whl → 6.8.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- canonicalwebteam/retry_utils.py +103 -36
- {canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/METADATA +1 -1
- {canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/RECORD +5 -5
- {canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/LICENSE +0 -0
- {canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/WHEEL +0 -0
canonicalwebteam/retry_utils.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from typing import Callable, Tuple, Type, TypeVar
|
|
2
|
-
from random import
|
|
2
|
+
from random import uniform
|
|
3
3
|
from sys import maxsize as MAX_INT
|
|
4
4
|
import functools
|
|
5
5
|
|
|
@@ -22,27 +22,45 @@ def retry(
|
|
|
22
22
|
Decorator that implements retry logic for `func` when any of the
|
|
23
23
|
Exceptions in `exceptions` happen.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
25
|
+
Args:
|
|
26
|
+
func (Callable[P, R], optional): The function that will be retried.
|
|
27
|
+
Defaults to `None` when invoking the decorator using parameters,
|
|
28
|
+
e.g. `@retry(limit=3)`).
|
|
29
|
+
limit (int, optional): The maximum number of retry attempts.
|
|
30
|
+
Defaults to `sys.maxsize`, allowing for a very large number of
|
|
31
|
+
retries.
|
|
32
|
+
delay_fn (Callable[[int], float], optional): A function that accepts
|
|
33
|
+
the current attempt number (starting from 1) and returns a float
|
|
34
|
+
representing the delay in seconds before the next call to `func`.
|
|
35
|
+
Defaults to a function that always returns 0.0 (no delay).
|
|
36
|
+
sleep_fn (Callable[[float], None], optional): A function that takes
|
|
37
|
+
a float (delay in seconds) and pauses execution for that duration.
|
|
38
|
+
Users are responsible for ensuring this function is appropriate
|
|
39
|
+
for their environment (e.g., an async sleep for async contexts).
|
|
40
|
+
Defaults to a function that performs no actual sleep.
|
|
41
|
+
callback_fn (Callable[[Exception], bool], optional): A function that
|
|
42
|
+
is called every time an exception from `exceptions` is caught
|
|
43
|
+
during the retry loop. It receives the caught exception as an
|
|
44
|
+
argument and should return `True` to abort the retry loop, or
|
|
45
|
+
`False` to continue. Defaults to a function that always returns
|
|
46
|
+
`False`.
|
|
47
|
+
logger_fn (Callable[[str], None], optional): A function designed to
|
|
48
|
+
log errors that are caught and handled (not propagated) during
|
|
49
|
+
the retry loop. It's invoked each time an exception from
|
|
50
|
+
`exceptions` is caught. Defaults to a function that performs no
|
|
51
|
+
logging.
|
|
52
|
+
exceptions (Tuple[Type[Exception]], optional): A tuple containing the
|
|
53
|
+
types of exceptions that will trigger a retry. Defaults to
|
|
54
|
+
`(Exception)`, meaning any standard exception will cause a retry.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Callable[P, R]: A decorated version of the input function `func`
|
|
58
|
+
that incorporates the defined retry logic. If `func` is initially
|
|
59
|
+
`None` (when used as `@retry(...)`), it returns a decorator
|
|
60
|
+
function ready to be applied to another callable.
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
ValueError: if `limit` is less than 1
|
|
46
64
|
"""
|
|
47
65
|
|
|
48
66
|
if func is None:
|
|
@@ -59,7 +77,7 @@ def retry(
|
|
|
59
77
|
exceptions=exceptions,
|
|
60
78
|
)
|
|
61
79
|
|
|
62
|
-
if limit
|
|
80
|
+
if limit < 1:
|
|
63
81
|
raise ValueError("The limit must be at least 1")
|
|
64
82
|
|
|
65
83
|
@functools.wraps(func)
|
|
@@ -94,30 +112,59 @@ def retry(
|
|
|
94
112
|
return _retry
|
|
95
113
|
|
|
96
114
|
|
|
97
|
-
def delay_constant(
|
|
115
|
+
def delay_constant(d: float):
|
|
98
116
|
"""
|
|
99
|
-
|
|
117
|
+
Create a constant delay function that always returns `d`.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
d (float): The constant delay in seconds that the returned function
|
|
121
|
+
will always provide.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Callable[[int], float]: A function that takes an integer
|
|
125
|
+
(representing the attempt number) and always returns the
|
|
126
|
+
specified `d` float.
|
|
127
|
+
|
|
128
|
+
Raises:
|
|
129
|
+
ValueError: if `d` is negative
|
|
100
130
|
"""
|
|
101
|
-
if
|
|
131
|
+
if d < 0:
|
|
102
132
|
raise ValueError("The delay must be at least 0")
|
|
103
133
|
|
|
104
134
|
def _delay_constant(_: int):
|
|
105
|
-
return
|
|
135
|
+
return d
|
|
106
136
|
|
|
107
137
|
return _delay_constant
|
|
108
138
|
|
|
109
139
|
|
|
110
|
-
def delay_random(
|
|
140
|
+
def delay_random(min_delay: float, max_delay: float):
|
|
111
141
|
"""
|
|
112
|
-
|
|
142
|
+
Create a random delay function that returns a random value between
|
|
143
|
+
`min_delay` and `max_delay`.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
min_delay (float): The minimum delay in seconds that the returned
|
|
147
|
+
function will provide.
|
|
148
|
+
max_delay (float): The maximum delay in seconds that the returned
|
|
149
|
+
function will provide.
|
|
150
|
+
|
|
151
|
+
Returns:
|
|
152
|
+
Callable[[int], float]: A function that takes an integer
|
|
153
|
+
(representing the attempt number) and returns a random float
|
|
154
|
+
between `min_delay` and `max_delay`.
|
|
155
|
+
|
|
156
|
+
Raises:
|
|
157
|
+
ValueError: if `min` is negative
|
|
158
|
+
ValueError: if `max` is less than or equal to `min`
|
|
113
159
|
"""
|
|
114
|
-
|
|
160
|
+
|
|
161
|
+
if min_delay < 0:
|
|
115
162
|
raise ValueError("The minimum delay must be at least 0")
|
|
116
|
-
if
|
|
163
|
+
if max_delay <= min_delay:
|
|
117
164
|
raise ValueError("The maximum delay must be greater than the minimum")
|
|
118
165
|
|
|
119
166
|
def _delay_random(_: int):
|
|
120
|
-
return
|
|
167
|
+
return uniform(min_delay, max_delay)
|
|
121
168
|
|
|
122
169
|
return _delay_random
|
|
123
170
|
|
|
@@ -126,10 +173,30 @@ def delay_exponential(
|
|
|
126
173
|
delay_mult: float, exp_base: float, max_delay: float = float("inf")
|
|
127
174
|
):
|
|
128
175
|
"""
|
|
129
|
-
|
|
130
|
-
limit based on the number of attempts made `n`,
|
|
131
|
-
formula:
|
|
132
|
-
min(
|
|
176
|
+
Create a function that implements an exponential backoff with an upper
|
|
177
|
+
limit. The delay is calculated based on the number of attempts made `n`,
|
|
178
|
+
according to the following formula:
|
|
179
|
+
`min(max_delay, delay_mult * exp_base^n)`.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
delay_mult (float): The multiplier for the exponential delay
|
|
183
|
+
calculation. This value scales the base exponential growth.
|
|
184
|
+
exp_base (float): The base of the exponent for the delay
|
|
185
|
+
calculation. This determines how quickly the delay increases
|
|
186
|
+
with each attempt.
|
|
187
|
+
max_delay (float, optional): The upper limit for the delay in
|
|
188
|
+
seconds. The calculated exponential delay will not exceed this
|
|
189
|
+
value. Defaults to positive infinity.
|
|
190
|
+
|
|
191
|
+
Returns:
|
|
192
|
+
Callable[[int], float]: A function that takes an integer
|
|
193
|
+
(representing the attempt number `n`) and returns a float
|
|
194
|
+
indicating the calculated exponential delay.
|
|
195
|
+
|
|
196
|
+
Raises:
|
|
197
|
+
ValueError: if `delay_mult` is negative or zero
|
|
198
|
+
ValueError: if `exp_base` is less than 1
|
|
199
|
+
ValueError: if `max_delay` is negative
|
|
133
200
|
"""
|
|
134
201
|
if delay_mult <= 0:
|
|
135
202
|
raise ValueError("The delay multiplier must be greater than 0")
|
{canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/RECORD
RENAMED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
canonicalwebteam/__init__.py,sha256=ED6jHcYiuYpr_0vjGz0zx2lrrmJT9sDJCzIljoDfmlM,65
|
|
2
2
|
canonicalwebteam/exceptions.py,sha256=Uf9HxtLH5fAXPdDm6H14tA8jUxKQAWUmWIovzHLtdRw,2134
|
|
3
|
-
canonicalwebteam/retry_utils.py,sha256=
|
|
3
|
+
canonicalwebteam/retry_utils.py,sha256=zGGabWzHyoXPNdwXBS_gbz3W0Qpdg3wN1G6aNy_xef8,8517
|
|
4
4
|
canonicalwebteam/store_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
canonicalwebteam/store_api/base.py,sha256=_kx3_hPQHJPUtdf3z4NXmcwHlswV1g1mw483fZXD5LM,3331
|
|
6
6
|
canonicalwebteam/store_api/dashboard.py,sha256=M5JLjTTahN-bfiVz9SuP6ahLjqEvOalwmNim6X5Ky6o,22796
|
|
7
7
|
canonicalwebteam/store_api/devicegw.py,sha256=YXmVXdHCZhukNHJq-eaFUCxa2VxqLT8qt19UrqgXGN0,9777
|
|
8
8
|
canonicalwebteam/store_api/publishergw.py,sha256=u2D2Y76xC8ms16XTZcUe_KmRdcyzqOV2g0aN9HYZBrQ,29702
|
|
9
|
-
canonicalwebteam_store_api-6.8.
|
|
10
|
-
canonicalwebteam_store_api-6.8.
|
|
11
|
-
canonicalwebteam_store_api-6.8.
|
|
12
|
-
canonicalwebteam_store_api-6.8.
|
|
9
|
+
canonicalwebteam_store_api-6.8.1.dist-info/LICENSE,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
|
|
10
|
+
canonicalwebteam_store_api-6.8.1.dist-info/METADATA,sha256=EwLBQ8u54hVJw3XFgYLribWqsubU_gNtAMdVMyj6VxA,2253
|
|
11
|
+
canonicalwebteam_store_api-6.8.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
12
|
+
canonicalwebteam_store_api-6.8.1.dist-info/RECORD,,
|
{canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/LICENSE
RENAMED
|
File without changes
|
{canonicalwebteam_store_api-6.8.0.dist-info → canonicalwebteam_store_api-6.8.1.dist-info}/WHEEL
RENAMED
|
File without changes
|