@@ -7,10 +7,11 @@ easy to see exactly what is happening when retrying requests.
77The example below demonstrates this.
88
99``` python
10-
1110import logging
11+
1212import httpx
13- from httpx_retries import RetryTransport, Retry
13+
14+ from httpx_retries import Retry, RetryTransport
1415
1516logging.basicConfig(
1617 format = " %(levelname)s [%(asctime)s ] %(name)s - %(message)s " ,
@@ -21,47 +22,66 @@ logging.basicConfig(
2122transport = RetryTransport(retry = Retry(total = 3 , backoff_factor = 0.5 ))
2223
2324with httpx.Client(transport = transport) as client:
24- response = client.get(" http ://httpstat.us /429" )
25+ response = client.get(" https ://httpco.de /429" )
2526```
2627
2728The result on ` stdout ` is:
2829
2930```
30- DEBUG [2025-04-20 19:44:23] httpx_retries.transport - handle_request started request=<Request('GET', 'http://httpstat.us/429')>
31- DEBUG [2025-04-20 19:44:23] httpcore.connection - connect_tcp.started host='httpstat.us' port=80 local_address=None timeout=5.0 socket_options=None
32- DEBUG [2025-04-20 19:44:23] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x10426f9d0>
33- DEBUG [2025-04-20 19:44:23] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
34- DEBUG [2025-04-20 19:44:23] httpcore.http11 - send_request_headers.complete
35- DEBUG [2025-04-20 19:44:23] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
36- DEBUG [2025-04-20 19:44:23] httpcore.http11 - send_request_body.complete
37- DEBUG [2025-04-20 19:44:23] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
38- DEBUG [2025-04-20 19:44:23] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Content-Length', b'21'), (b'Content-Type', b'text/plain'), (b'Date', b'Sun, 20 Apr 2025 18:44:22 GMT'), (b'Server', b'Kestrel'), (b'Retry-After', b'5'), (b'Set-Cookie', b'ARRAffinity=1c4ce6b282a4edef63e94171500d99e8b18888422937ab7168b9007141be8730;Path=/;HttpOnly;Domain=httpstat.us'), (b'Request-Context', b'appId=cid-v1:3548b0f5-7f75-492f-82bb-b6eb0e864e53')])
39- DEBUG [2025-04-20 19:44:23] httpx_retries.transport - _retry_operation retrying response=<Response [429 Too Many Requests]> retry=<Retry(total=2, attempts_made=0)>
40- DEBUG [2025-04-20 19:44:23] httpx_retries.retry - increment retry=<Retry(total=2, attempts_made=0)> new_attempts_made=1
41- DEBUG [2025-04-20 19:44:23] httpx_retries.retry - sleep seconds=5.0
42- DEBUG [2025-04-20 19:44:28] httpcore.connection - connect_tcp.started host='httpstat.us' port=80 local_address=None timeout=5.0 socket_options=None
43- DEBUG [2025-04-20 19:44:28] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x104287df0>
44- DEBUG [2025-04-20 19:44:28] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
45- DEBUG [2025-04-20 19:44:28] httpcore.http11 - send_request_headers.complete
46- DEBUG [2025-04-20 19:44:28] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
47- DEBUG [2025-04-20 19:44:28] httpcore.http11 - send_request_body.complete
48- DEBUG [2025-04-20 19:44:28] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
49- DEBUG [2025-04-20 19:44:29] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Content-Length', b'21'), (b'Content-Type', b'text/plain'), (b'Date', b'Sun, 20 Apr 2025 18:44:28 GMT'), (b'Server', b'Kestrel'), (b'Retry-After', b'5'), (b'Set-Cookie', b'ARRAffinity=1c4ce6b282a4edef63e94171500d99e8b18888422937ab7168b9007141be8730;Path=/;HttpOnly;Domain=httpstat.us'), (b'Request-Context', b'appId=cid-v1:3548b0f5-7f75-492f-82bb-b6eb0e864e53')])
50- DEBUG [2025-04-20 19:44:29] httpx_retries.transport - _retry_operation retrying response=<Response [429 Too Many Requests]> retry=<Retry(total=2, attempts_made=1)>
51- DEBUG [2025-04-20 19:44:29] httpx_retries.retry - increment retry=<Retry(total=2, attempts_made=1)> new_attempts_made=2
52- DEBUG [2025-04-20 19:44:29] httpx_retries.retry - sleep seconds=5.0
53- DEBUG [2025-04-20 19:44:34] httpcore.connection - connect_tcp.started host='httpstat.us' port=80 local_address=None timeout=5.0 socket_options=None
54- DEBUG [2025-04-20 19:44:34] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x104287a60>
55- DEBUG [2025-04-20 19:44:34] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
56- DEBUG [2025-04-20 19:44:34] httpcore.http11 - send_request_headers.complete
57- DEBUG [2025-04-20 19:44:34] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
58- DEBUG [2025-04-20 19:44:34] httpcore.http11 - send_request_body.complete
59- DEBUG [2025-04-20 19:44:34] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
60- DEBUG [2025-04-20 19:44:34] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Content-Length', b'21'), (b'Content-Type', b'text/plain'), (b'Date', b'Sun, 20 Apr 2025 18:44:33 GMT'), (b'Server', b'Kestrel'), (b'Retry-After', b'5'), (b'Set-Cookie', b'ARRAffinity=1c4ce6b282a4edef63e94171500d99e8b18888422937ab7168b9007141be8730;Path=/;HttpOnly;Domain=httpstat.us'), (b'Request-Context', b'appId=cid-v1:3548b0f5-7f75-492f-82bb-b6eb0e864e53')])
61- DEBUG [2025-04-20 19:44:34] httpx_retries.transport - handle_request finished request=<Request('GET', 'http://httpstat.us/429')> response=<Response [429 Too Many Requests]>
62- INFO [2025-04-20 19:44:34] httpx - HTTP Request: GET http://httpstat.us/429 "HTTP/1.1 429 Too Many Requests"
63- DEBUG [2025-04-20 19:44:34] httpcore.http11 - receive_response_body.started request=<Request [b'GET']>
64- DEBUG [2025-04-20 19:44:34] httpcore.http11 - receive_response_body.complete
65- DEBUG [2025-04-20 19:44:34] httpcore.http11 - response_closed.started
66- DEBUG [2025-04-20 19:44:34] httpcore.http11 - response_closed.complete
31+ DEBUG [2025-08-23 09:34:21] httpx_retries.transport - handle_request started request=<Request('GET', 'https://httpco.de/429')>
32+ DEBUG [2025-08-23 09:34:21] httpcore.connection - connect_tcp.started host='httpco.de' port=443 local_address=None timeout=5.0 socket_options=None
33+ DEBUG [2025-08-23 09:34:21] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070af9a0>
34+ DEBUG [2025-08-23 09:34:21] httpcore.connection - start_tls.started ssl_context=<ssl.SSLContext object at 0x1070a0510> server_hostname='httpco.de' timeout=5.0
35+ DEBUG [2025-08-23 09:34:22] httpcore.connection - start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070af970>
36+ DEBUG [2025-08-23 09:34:22] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
37+ DEBUG [2025-08-23 09:34:22] httpcore.http11 - send_request_headers.complete
38+ DEBUG [2025-08-23 09:34:22] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
39+ DEBUG [2025-08-23 09:34:22] httpcore.http11 - send_request_body.complete
40+ DEBUG [2025-08-23 09:34:22] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
41+ DEBUG [2025-08-23 09:34:22] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Date', b'Sat, 23 Aug 2025 08:34:22 GMT'), (b'Content-Type', b'text/plain; charset=utf-8'), (b'Content-Length', b'17'), (b'Connection', b'keep-alive')])
42+ DEBUG [2025-08-23 09:34:22] httpx_retries.transport - _retry_operation retrying request=<Request('GET', 'https://httpco.de/429')> response=<Response [429 Too Many Requests]> retry=<Retry(total=3, attempts_made=0)>
43+ DEBUG [2025-08-23 09:34:22] httpx_retries.retry - increment retry=<Retry(total=3, attempts_made=0)> new_attempts_made=1
44+ DEBUG [2025-08-23 09:34:22] httpx_retries.retry - sleep seconds=0.7751384536885068
45+ DEBUG [2025-08-23 09:34:22] httpcore.connection - connect_tcp.started host='httpco.de' port=443 local_address=None timeout=5.0 socket_options=None
46+ DEBUG [2025-08-23 09:34:22] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070c7c40>
47+ DEBUG [2025-08-23 09:34:22] httpcore.connection - start_tls.started ssl_context=<ssl.SSLContext object at 0x1070a0510> server_hostname='httpco.de' timeout=5.0
48+ DEBUG [2025-08-23 09:34:23] httpcore.connection - start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070c7c10>
49+ DEBUG [2025-08-23 09:34:23] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
50+ DEBUG [2025-08-23 09:34:23] httpcore.http11 - send_request_headers.complete
51+ DEBUG [2025-08-23 09:34:23] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
52+ DEBUG [2025-08-23 09:34:23] httpcore.http11 - send_request_body.complete
53+ DEBUG [2025-08-23 09:34:23] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
54+ DEBUG [2025-08-23 09:34:23] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Date', b'Sat, 23 Aug 2025 08:34:23 GMT'), (b'Content-Type', b'text/plain; charset=utf-8'), (b'Content-Length', b'17'), (b'Connection', b'keep-alive')])
55+ DEBUG [2025-08-23 09:34:23] httpx_retries.transport - _retry_operation retrying request=<Request('GET', 'https://httpco.de/429')> response=<Response [429 Too Many Requests]> retry=<Retry(total=3, attempts_made=1)>
56+ DEBUG [2025-08-23 09:34:23] httpx_retries.retry - increment retry=<Retry(total=3, attempts_made=1)> new_attempts_made=2
57+ DEBUG [2025-08-23 09:34:23] httpx_retries.retry - sleep seconds=0.979677107701836
58+ DEBUG [2025-08-23 09:34:24] httpcore.connection - connect_tcp.started host='httpco.de' port=443 local_address=None timeout=5.0 socket_options=None
59+ DEBUG [2025-08-23 09:34:24] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070e54c0>
60+ DEBUG [2025-08-23 09:34:24] httpcore.connection - start_tls.started ssl_context=<ssl.SSLContext object at 0x1070a0510> server_hostname='httpco.de' timeout=5.0
61+ DEBUG [2025-08-23 09:34:24] httpcore.connection - start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070c7940>
62+ DEBUG [2025-08-23 09:34:24] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
63+ DEBUG [2025-08-23 09:34:24] httpcore.http11 - send_request_headers.complete
64+ DEBUG [2025-08-23 09:34:24] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
65+ DEBUG [2025-08-23 09:34:24] httpcore.http11 - send_request_body.complete
66+ DEBUG [2025-08-23 09:34:24] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
67+ DEBUG [2025-08-23 09:34:24] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Date', b'Sat, 23 Aug 2025 08:34:24 GMT'), (b'Content-Type', b'text/plain; charset=utf-8'), (b'Content-Length', b'17'), (b'Connection', b'keep-alive')])
68+ DEBUG [2025-08-23 09:34:24] httpx_retries.transport - _retry_operation retrying request=<Request('GET', 'https://httpco.de/429')> response=<Response [429 Too Many Requests]> retry=<Retry(total=3, attempts_made=2)>
69+ DEBUG [2025-08-23 09:34:24] httpx_retries.retry - increment retry=<Retry(total=3, attempts_made=2)> new_attempts_made=3
70+ DEBUG [2025-08-23 09:34:24] httpx_retries.retry - sleep seconds=2.250136320382409
71+ DEBUG [2025-08-23 09:34:26] httpcore.connection - connect_tcp.started host='httpco.de' port=443 local_address=None timeout=5.0 socket_options=None
72+ DEBUG [2025-08-23 09:34:26] httpcore.connection - connect_tcp.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070e51c0>
73+ DEBUG [2025-08-23 09:34:26] httpcore.connection - start_tls.started ssl_context=<ssl.SSLContext object at 0x1070a0510> server_hostname='httpco.de' timeout=5.0
74+ DEBUG [2025-08-23 09:34:27] httpcore.connection - start_tls.complete return_value=<httpcore._backends.sync.SyncStream object at 0x1070e5430>
75+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - send_request_headers.started request=<Request [b'GET']>
76+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - send_request_headers.complete
77+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - send_request_body.started request=<Request [b'GET']>
78+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - send_request_body.complete
79+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - receive_response_headers.started request=<Request [b'GET']>
80+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - receive_response_headers.complete return_value=(b'HTTP/1.1', 429, b'Too Many Requests', [(b'Date', b'Sat, 23 Aug 2025 08:34:27 GMT'), (b'Content-Type', b'text/plain; charset=utf-8'), (b'Content-Length', b'17'), (b'Connection', b'keep-alive')])
81+ DEBUG [2025-08-23 09:34:27] httpx_retries.transport - handle_request finished request=<Request('GET', 'https://httpco.de/429')> response=<Response [429 Too Many Requests]>
82+ INFO [2025-08-23 09:34:27] httpx - HTTP Request: GET https://httpco.de/429 "HTTP/1.1 429 Too Many Requests"
83+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - receive_response_body.started request=<Request [b'GET']>
84+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - receive_response_body.complete
85+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - response_closed.started
86+ DEBUG [2025-08-23 09:34:27] httpcore.http11 - response_closed.complete
6787```
0 commit comments