Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1"""Interfaces for tubthumper package""" 

2 

3import logging 

4 

5from tubthumper import _types 

6from tubthumper._retry_factory import RetryConfig 

7from tubthumper._retry_factory import retry_factory as _retry_factory 

8from tubthumper._types import Decorator, RetryCallable, T 

9 

10__all__ = ["retry", "retry_decorator", "retry_factory"] 

11 

12RETRY_LIMIT_DEFAULT = float("inf") 

13TIME_LIMIT_DEFAULT = float("inf") 

14INIT_BACKOFF_DEFAULT = 1 

15EXPONENTIAL_DEFAULT = 2 

16JITTER_DEFAULT = True 

17RERAISE_DEFAULT = False 

18LOG_LEVEL_DEFAULT = logging.WARNING 

19LOGGER_DEFAULT = logging.getLogger("tubthumper") 

20 

21 

22def retry( 

23 func: RetryCallable[T], 

24 *, 

25 exceptions: _types.Exceptions, 

26 args: _types.Args = None, 

27 kwargs: _types.Kwargs = None, 

28 retry_limit: _types.RetryLimit = RETRY_LIMIT_DEFAULT, 

29 time_limit: _types.TimeLimit = TIME_LIMIT_DEFAULT, 

30 init_backoff: _types.InitBackoff = INIT_BACKOFF_DEFAULT, 

31 exponential: _types.Exponential = EXPONENTIAL_DEFAULT, 

32 jitter: _types.Jitter = JITTER_DEFAULT, 

33 reraise: _types.Reraise = RERAISE_DEFAULT, 

34 log_level: _types.LogLevel = LOG_LEVEL_DEFAULT, 

35 logger: _types.Logger = LOGGER_DEFAULT, 

36) -> T: 

37 r"""Call the provided callable with retry logic. 

38 

39 For usage examples, see `here <index.html#usage>`__. 

40 

41 Args: 

42 func: 

43 callable to be called 

44 exceptions: 

45 exceptions to be caught, resulting in a retry 

46 args: 

47 positional arguments for the callable 

48 kwargs: 

49 keyword arguments for the callable 

50 retry_limit: 

51 number of retries to perform before raising an exception, 

52 e.g. ``retry_limit=1`` results in at most two calls 

53 time_limit: 

54 duration in seconds after which a retry attempt will 

55 be prevented by raising an exception, i.e. not a timeout 

56 stopping long running calls, but rather a mechanism to prevent 

57 retry attempts after a certain duration 

58 init_backoff: 

59 duration in seconds to sleep before the first retry 

60 exponential: 

61 backoff duration between retries grows by this factor with each retry 

62 jitter: 

63 whether or not to "jitter" the backoff duration randomly 

64 reraise: 

65 whether or not to re-raise the caught exception instead of 

66 a `RetryError` when a retry or time limit is reached 

67 log_level: 

68 level for logging caught exceptions, defaults to `logging.WARNING` 

69 logger: 

70 logger to log caught exceptions with 

71 

72 Raises: 

73 RetryError: 

74 Raised when a retry or time limit is reached, unless ``reraise=True`` 

75 

76 Returns: 

77 the returned object of the callable 

78 """ 

79 if args is None: 

80 args = () 

81 if kwargs is None: 

82 kwargs = {} 

83 retry_config = RetryConfig( 

84 exceptions=exceptions, 

85 retry_limit=retry_limit, 

86 time_limit=time_limit, 

87 init_backoff=init_backoff, 

88 exponential=exponential, 

89 jitter=jitter, 

90 reraise=reraise, 

91 log_level=log_level, 

92 logger=logger, 

93 ) 

94 retry_func = _retry_factory(func, retry_config) 

95 return retry_func(*args, **kwargs) 

96 

97 

98def retry_decorator( 

99 *, 

100 exceptions: _types.Exceptions, 

101 retry_limit: _types.RetryLimit = RETRY_LIMIT_DEFAULT, 

102 time_limit: _types.TimeLimit = TIME_LIMIT_DEFAULT, 

103 init_backoff: _types.InitBackoff = INIT_BACKOFF_DEFAULT, 

104 exponential: _types.Exponential = EXPONENTIAL_DEFAULT, 

105 jitter: _types.Jitter = JITTER_DEFAULT, 

106 reraise: _types.Reraise = RERAISE_DEFAULT, 

107 log_level: _types.LogLevel = LOG_LEVEL_DEFAULT, 

108 logger: _types.Logger = LOGGER_DEFAULT, 

109) -> Decorator[T]: 

110 r"""Construct a decorator function for defining a function with built-in retry logic. 

111 

112 For usage examples, see `here <index.html#usage>`__. 

113 

114 Args: 

115 exceptions: 

116 exceptions to be caught, resulting in a retry 

117 retry_limit: 

118 number of retries to perform before raising an exception, 

119 e.g. ``retry_limit=1`` results in at most two calls 

120 time_limit: 

121 duration in seconds after which a retry attempt will 

122 be prevented by raising an exception, i.e. not a timeout 

123 stopping long running calls, but rather a mechanism to prevent 

124 retry attempts after a certain duration 

125 init_backoff: 

126 duration in seconds to sleep before the first retry 

127 exponential: 

128 backoff duration between retries grows by this factor with each retry 

129 jitter: 

130 whether or not to "jitter" the backoff duration randomly 

131 reraise: 

132 whether or not to re-raise the caught exception instead of 

133 a `RetryError` when a retry or time limit is reached 

134 log_level: 

135 level for logging caught exceptions, defaults to `logging.WARNING` 

136 logger: 

137 logger to log caught exceptions with 

138 

139 Raises: 

140 RetryError: 

141 Raised when a retry or time limit is reached, unless ``reraise=True`` 

142 

143 Returns: 

144 a decorator function that, when used as such, 

145 returns a function that looks like the callable it 

146 decorates, but with configured retry logic 

147 """ 

148 

149 def decorator(func: RetryCallable[T]) -> RetryCallable[T]: 

150 retry_config = RetryConfig( 

151 exceptions=exceptions, 

152 retry_limit=retry_limit, 

153 time_limit=time_limit, 

154 init_backoff=init_backoff, 

155 exponential=exponential, 

156 jitter=jitter, 

157 reraise=reraise, 

158 log_level=log_level, 

159 logger=logger, 

160 ) 

161 return _retry_factory(func, retry_config) 

162 

163 return decorator 

164 

165 

166def retry_factory( 

167 func: RetryCallable[T], 

168 *, 

169 exceptions: _types.Exceptions, 

170 retry_limit: _types.RetryLimit = RETRY_LIMIT_DEFAULT, 

171 time_limit: _types.TimeLimit = TIME_LIMIT_DEFAULT, 

172 init_backoff: _types.InitBackoff = INIT_BACKOFF_DEFAULT, 

173 exponential: _types.Exponential = EXPONENTIAL_DEFAULT, 

174 jitter: _types.Jitter = JITTER_DEFAULT, 

175 reraise: _types.Reraise = RERAISE_DEFAULT, 

176 log_level: _types.LogLevel = LOG_LEVEL_DEFAULT, 

177 logger: _types.Logger = LOGGER_DEFAULT, 

178) -> RetryCallable[T]: 

179 r"""Construct a function with built-in retry logic given a callable to retry. 

180 

181 For usage examples, see `here <index.html#usage>`__. 

182 

183 Args: 

184 func: 

185 callable to be called 

186 exceptions: 

187 exceptions to be caught, resulting in a retry 

188 retry_limit: 

189 number of retries to perform before raising an exception, 

190 e.g. ``retry_limit=1`` results in at most two calls 

191 time_limit: 

192 duration in seconds after which a retry attempt will 

193 be prevented by raising an exception, i.e. not a timeout 

194 stopping long running calls, but rather a mechanism to prevent 

195 retry attempts after a certain duration 

196 init_backoff: 

197 duration in seconds to sleep before the first retry 

198 exponential: 

199 backoff duration between retries grows by this factor with each retry 

200 jitter: 

201 whether or not to "jitter" the backoff duration randomly 

202 reraise: 

203 whether or not to re-raise the caught exception instead of 

204 a `RetryError` when a retry or time limit is reached 

205 log_level: 

206 level for logging caught exceptions, defaults to `logging.WARNING` 

207 logger: 

208 logger to log caught exceptions with 

209 

210 Raises: 

211 RetryError: 

212 Raised when a retry or time limit is reached, unless ``reraise=True`` 

213 

214 Returns: 

215 a function that looks like the callable provided, 

216 but with configured retry logic 

217 """ 

218 retry_config = RetryConfig( 

219 exceptions=exceptions, 

220 retry_limit=retry_limit, 

221 time_limit=time_limit, 

222 init_backoff=init_backoff, 

223 exponential=exponential, 

224 jitter=jitter, 

225 reraise=reraise, 

226 log_level=log_level, 

227 logger=logger, 

228 ) 

229 return _retry_factory(func, retry_config)