88import random
99import time
1010from concurrent .futures import FIRST_COMPLETED , Future , wait
11- from typing import Any , Callable , Dict , Generator , List , Optional , Sequence , Tuple , Union , cast
11+ from functools import partial , wraps
12+ from typing import Any , Callable , Dict , Generator , List , Optional , Sequence , Tuple , Type , Union , cast
1213
1314import boto3
1415import botocore .config
@@ -333,9 +334,42 @@ def check_duplicated_columns(df: pd.DataFrame) -> Any:
333334 )
334335
335336
337+ def retry (
338+ ex : Type [Exception ],
339+ ex_code : Optional [str ] = None ,
340+ base : float = 1.0 ,
341+ max_num_tries : int = 3 ,
342+ ) -> Callable [..., Any ]:
343+ """
344+ Decorate function with decorrelated Jitter retries.
345+
346+ Parameters
347+ ----------
348+ ex : Exception
349+ Exception to retry on
350+ ex_code : Optional[str]
351+ Response error code
352+ base : float
353+ Base delay
354+ max_num_tries : int
355+ Maximum number of retries
356+
357+ Returns
358+ -------
359+ Callable[..., Any]
360+ Function
361+ """
362+
363+ def wrapper (f : Callable [..., Any ]) -> Any :
364+ return wraps (f )(partial (try_it , f , ex , ex_code = ex_code , base = base , max_num_tries = max_num_tries ))
365+
366+ return wrapper
367+
368+
336369def try_it (
337370 f : Callable [..., Any ],
338371 ex : Any ,
372+ * args : Any ,
339373 ex_code : Optional [str ] = None ,
340374 base : float = 1.0 ,
341375 max_num_tries : int = 3 ,
@@ -348,7 +382,7 @@ def try_it(
348382 delay : float = base
349383 for i in range (max_num_tries ):
350384 try :
351- return f (** kwargs )
385+ return f (* args , * *kwargs )
352386 except ex as exception :
353387 if ex_code is not None and hasattr (exception , "response" ):
354388 if exception .response ["Error" ]["Code" ] != ex_code :
0 commit comments