2020
2121from . import keys
2222from .utils import urlopen_and_read
23- from .flickrerrors import FlickrError , FlickrAPIError , FlickrServerError , FlickrRateLimitError
23+ from .flickrerrors import (
24+ FlickrAPIError ,
25+ FlickrError ,
26+ FlickrServerError ,
27+ )
28+ from . import retry as retry_module
2429from .cache import SimpleCache
2530
2631REST_URL = "https://api.flickr.com/services/rest/"
4146_RATE_LIMIT_LAST_REQUEST : float | None = None
4247
4348
49+ # Initialize retry module with our config getters
50+ def _init_retry_module () -> None :
51+ """Initialize retry module with config getters."""
52+ retry_module .set_retry_config_getter (get_retry_config )
53+ retry_module .set_rate_limit_wait_func (_maybe_wait_for_rate_limit )
54+
55+
4456def enable_cache (cache_object : Any | None = None ) -> None :
4557 """enable caching
4658 Parameters:
@@ -208,12 +220,8 @@ def _calculate_retry_delay(attempt: int, retry_after: float | None) -> float:
208220 --------
209221 Delay in seconds
210222 """
211- if retry_after is not None and retry_after > 0 :
212- return min (retry_after , RETRY_MAX_DELAY )
213-
214- # Exponential backoff: base_delay * 2^attempt
215- delay = RETRY_BASE_DELAY * (2 ** attempt )
216- return min (delay , RETRY_MAX_DELAY )
223+ # Delegate to retry module for consistency
224+ return retry_module .calculate_retry_delay (attempt , retry_after )
217225
218226
219227def _parse_retry_after (response : requests .Response ) -> float | None :
@@ -228,24 +236,19 @@ def _parse_retry_after(response: requests.Response) -> float | None:
228236 --------
229237 Seconds to wait, or None if header not present/parseable
230238 """
231- retry_after = response .headers .get ("Retry-After" )
232- if retry_after is None :
233- return None
234-
235- try :
236- return float (retry_after )
237- except ValueError :
238- # Could be an HTTP-date format, but Flickr typically uses seconds
239- logger .warning ("Could not parse Retry-After header: %s" , retry_after )
240- return None
239+ # Delegate to retry module for consistency
240+ return retry_module .parse_retry_after (response )
241241
242242
243243def _make_request_with_retry (
244244 request_url : str ,
245245 args : dict [str , Any ],
246246 oauth_auth : Any ,
247247) -> requests .Response :
248- """Make HTTP request with automatic retry on rate limit errors.
248+ """Make HTTP request with automatic retry on transient errors.
249+
250+ Handles HTTP 429 (rate limit), 5xx (server errors), timeouts, and
251+ connection errors with configurable retry behavior.
249252
250253 Parameters:
251254 -----------
@@ -263,40 +266,16 @@ def _make_request_with_retry(
263266 Raises:
264267 -------
265268 FlickrRateLimitError: If rate limit exceeded and max retries exhausted
269+ FlickrServerError: If server error and max retries exhausted
270+ FlickrTimeoutError: If timeout/connection error and max retries exhausted
266271 """
267- _maybe_wait_for_rate_limit ()
268-
269- last_error : FlickrRateLimitError | None = None
270-
271- for attempt in range (MAX_RETRIES + 1 ):
272- resp = requests .post (request_url , args , auth = oauth_auth , timeout = get_timeout ())
273-
274- if resp .status_code != 429 :
275- return resp
276-
277- # Rate limited - parse retry info and potentially retry
278- retry_after = _parse_retry_after (resp )
279- content = resp .content .decode ("utf8" ) if resp .content else "Too Many Requests"
280- last_error = FlickrRateLimitError (retry_after , content )
281-
282- if attempt >= MAX_RETRIES :
283- logger .warning (
284- "Rate limit exceeded, max retries (%d) exhausted" ,
285- MAX_RETRIES ,
286- )
287- break
288-
289- delay = _calculate_retry_delay (attempt , retry_after )
290- logger .warning (
291- "Rate limit exceeded (attempt %d/%d), retrying in %.1f seconds" ,
292- attempt + 1 ,
293- MAX_RETRIES + 1 ,
294- delay ,
295- )
296- time .sleep (delay )
297-
298- # If we get here, we've exhausted retries
299- raise last_error # type: ignore[misc]
272+ # Ensure retry module is initialized
273+ _init_retry_module ()
274+
275+ def make_request () -> requests .Response :
276+ return requests .post (request_url , args , auth = oauth_auth , timeout = get_timeout ())
277+
278+ return retry_module .retry_request (make_request , operation_name = "API call" )
300279
301280
302281def send_request (url , data ):
0 commit comments