Inspecting HTTP Retry-After in Python: Converting seconds and GMT datetimes into the same wait duration

ネットワーク・RFCカテゴリを表すパンダのイラスト Networking / RFC

About this article
This article was created using a generative AI-powered automation workflow. Based on the RFC 9110Retry-Afterspecification and official Python documentation, we verified network-disconnected inspection programs using Python 3.13.5 during initial creation and Python 3.12.14 during subsequent verification. The focus is on header value parsing; actual HTTP retry execution is not performed.

Verification status: Confirmed via local Python execution (16 unit tests for the same material passed on Python 3.13.5 and 3.12.14) / External APIs and OS-specific hardware unverified / Completed self-QA across 5 roles within the same run

When an API responds with a request to wait, being able to confirm the required wait time numerically facilitates incident investigation. However, theRetry-Afterheader allows different formats, such as plain seconds or a GMT datetime.120While the seconds format is relatively straightforward, convertingSat, 24 Oct 2026 00:02:00 GMTinto a relative number of seconds from now requires paying attention to the current time and timezone. In this article, we will observe the differences using a small Python program that parses strings without sending HTTP requests.

Running first: Representing the same 120 seconds in two ways

Prepare Python 3.10 or later, retrievethe tutorial version from GitHuband run itretry_after.pyin the same folder. No additional libraries or API keys are required. To keep comparison conditions constant, pass--nowa string containing the datetime and UTC offset.

python retry_after.py 120 --now 2026-10-24T00:00:00+00:00

The following output was confirmed during local execution at the time of creation.

{"kind": "delay-seconds", "wait_seconds": 120, "target_utc": "2026-10-24T00:02:00Z", "action": "inspect_only_no_sleep_no_request"}

Next, change only the value to the HTTP-date format.

python retry_after.py 'Sat, 24 Oct 2026 00:02:00 GMT' --now 2026-10-24T00:00:00+00:00

The measured output forwait_secondsis also120It was. However,kindishttp-date. The former means "120 seconds from the time of receipt," while the latter means "until the specified UTC time," differing in their reference points. Using a fixed time allows comparisons while eliminating the effects of network latency and execution time differences. In real network environments, how the receipt time is captured also becomes a design consideration.

Why two types exist: Reading the RFC specifications

RFC 9110 §10.2.3definesRetry-Afteras the value ofdelay-secondsorHTTP-date. The former is a decimal integer greater than or equal to zero, and does not accept negative numbers or decimals directly as waiting seconds. The latter is a date and time. In a 503 response, it is used as an estimate of when the service will become available, and in a 3xx response, as a waiting time before a redirect request.

What is important here isnot to assume that this header will always be present simply because the HTTP status was 429. The backoff strategy when the header is absent depends on the API's terms of use and client design. This learning material is only responsible for parsing when a header value is input, and does not implement the conditions under which a 429 occurs or the overall retry policy specified by the server.

There are multiple acceptable formats for HTTP-date.RFC 9110 §5.6.7specifies the currently common IMF-fixdate as well as older date and time formats for compatibility. While the RFC requires senders to use IMF-fixdate, it requires receivers to accept all three HTTP-date formats for compatibility. For educational purposes, the code in this material acceptsonly IMF-fixdateand does not perform heuristic conversion of obsolete formats. Therefore, this implementation does not replace an RFC-compliant, general-purpose HTTP client. If adapting this for production use, add tests to accept obsolete formats or follow the specifications of the HTTP library you are using. This is an intentional restriction that prioritizes the scope of observation, which is "comparing seconds and current-format dates against a fixed time."

Key points of the code: branching between date-time and seconds

Theparse_retry_afterfunction in the material first checks whether the string consists solely of digits. If it consists of digits, it converts the value to an integer and adds it to the current time. If it is in a date-time format, it validates the syntax and then uses the Python standard library'semail.utils.parsedate_to_datetimeis used. This function is for converting a date and time string intodatetime, and the specification is available in theOfficial Python Documentation.

from datetime import datetime, timezone
from retry_after import parse_retry_after

now = datetime(2026, 10, 24, 0, 0, tzinfo=timezone.utc)
seconds, target, kind = parse_retry_after("120", now)
print(seconds, kind)

The measured output of this short code is120 delay-seconds. The function only returns the parsing result and does not callsleepor HTTP communication. To avoid concerns about sending a large number of retries to the API during training, the monitoring function and the actual waiting function are separated. Even when integrating the program into business operations, this separation makes it easier to create unit tests.

For the date and time format, we also verify that the day of the week matches the calendar date. Relying solely on general-purpose date and time parsers might silently accept errors in the day of the week. Additionally,nowresults in an error if it does not contain time zone information.2026-10-24 09:00This is because it is impossible to determine whether it is UTC or Japan Standard Time based solely on

Changing one place: past date and time and fractional seconds

Let us change the previous date and time toFri, 23 Oct 2026 23:59:59 GMTone second ago. The reference time remains the same2026-10-24T00:00:00+00:00. In the tutorial, the waiting time is returned as 0 seconds. It is designed not to treat past dates and times as negative waiting times. However, this does not mean that you can resend unconditionally simply because it is "0 seconds." The maximum number of attempts and the API usage terms must still be observed separately.

On the other hand, if the reference time includes fractional seconds and only 0.999999 seconds remain until the specified date and time, the waiting time is rounded up to 1 second. This is because rounding down to an integer might cause retries to occur earlier than the specified date and time. In actual clients, it is also necessary to consider the type of measurement clock, HTTP response reception timing, and network latency. Calculations here serve as a tutorial for header parsing and do not solve all time synchronization issues in distributed systems.

Identifying errors: do not correct silently

Retry-After: -1andRetry-After: 1.5are invalid asdelay-seconds. In the CLI,INVALID_RETRY_AFTERis displayed on standard error, and the process exits with exit code 2. Dates and times where the day of the week and date do not match, non-existent dates, and those without time zone information--noware also not accepted. The system does not automatically correct failures by simply "waiting one second" in order to ensure that invalid and valid server responses can be distinguished during operation.

If the command fails to start, verify the Python installation, working directory, and file name. In a Windows environment, ifpythonis unavailable, consider launching viapy -3. When date interpretation differs from expectations, first check the--nowoffset and verify that the HTTP-date side is in GMT. If legacy date formats are entered and rejected, they are outside the scope of this material. Do not alter strings arbitrarily; retain the received value to determine the appropriate response strategy.

For professional use: Do not confuse parsing with retrying

In API operations, it is essential to record "what the server returned" and "what the client did" separately during incidents. By separately storing header strings, HTTP status, reception time, parsing results, and the actual next request time, you can verify afterward whether requests were not sent at intervals shorter than necessary. However, authentication tokens, personal information, confidential URLs, and response bodies must not be carelessly left in the logs.

Actual retry processing requires timeouts, maximum retry counts, exponential backoff, idempotency, and the distinction between network failures and server responses. For example, when resending a modification API request with the same content, you must account for the possibility of duplicate execution. The output of this material isObservation Results of Waiting Timesand is not a complete set of rules for determining whether a retry is permissible.

During initial creation, execution of the training material at the same commit was verified in a local environment using Python 3.13.5, and during subsequent repair confirmation using Python 3.12.14. Both confirmed 16 unit tests, syntax checks, and CLI output for second and date-time formats. Codex CLI testing, actual API connections, physical device testing on Windows/macOS, and independent reviews by other AIs were not conducted. The five-role self-QA within the same execution does not constitute an independent review by a different provider. If additional compatibility is required, it is safer to first define whether to accept legacy RFC formats as a specification and then add tests for each format.

Official and Primary Sources

GitHub Sample

Document information

Article title
Inspecting HTTP Retry-After in Python: Converting seconds and GMT datetimes into the same wait duration
Published
Updated
Source
https://papanda925.com/?p=18240&lang=en

License: Text and original figures for which this site holds the relevant rights are available under CC BY 4.0 , unless otherwise noted. This article may include content created or edited with generative AI. If code has a separate license notice or a linked GitHub repository license, that license takes precedence for the code. Quotations, third-party materials, images, and trademarks are excluded from this license. Usage policy

Copied title and URL