| 326 | return float(max(0, min(self.backoff_max, backoff_value))) |
| 327 | |
| 328 | def parse_retry_after(self, retry_after: str) -> float: |
| 329 | seconds: float |
| 330 | # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 |
| 331 | if re.match(r"^\s*[0-9]+\s*$", retry_after): |
| 332 | seconds = int(retry_after) |
| 333 | else: |
| 334 | retry_date_tuple = email.utils.parsedate_tz(retry_after) |
| 335 | if retry_date_tuple is None: |
| 336 | raise InvalidHeader(f"Invalid Retry-After header: {retry_after}") |
| 337 | |
| 338 | retry_date = email.utils.mktime_tz(retry_date_tuple) |
| 339 | seconds = retry_date - time.time() |
| 340 | |
| 341 | seconds = max(seconds, 0) |
| 342 | |
| 343 | # Check the seconds do not exceed the specified maximum |
| 344 | if seconds > self.retry_after_max: |
| 345 | seconds = self.retry_after_max |
| 346 | |
| 347 | return seconds |
| 348 | |
| 349 | def get_retry_after(self, response: BaseHTTPResponse) -> float | None: |
| 350 | """Get the value of Retry-After in seconds.""" |