pyqwest 0.1.0__cp310-cp310-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyqwest/__init__.py +47 -0
- pyqwest/_glue.py +79 -0
- pyqwest/httpx/__init__.py +5 -0
- pyqwest/httpx/_transport.py +280 -0
- pyqwest/pyqwest.cpython-310-aarch64-linux-gnu.so +0 -0
- pyqwest/pyqwest.pyi +1104 -0
- pyqwest-0.1.0.dist-info/METADATA +21 -0
- pyqwest-0.1.0.dist-info/RECORD +11 -0
- pyqwest-0.1.0.dist-info/WHEEL +4 -0
- pyqwest-0.1.0.dist-info/licenses/LICENSE +21 -0
- pyqwest.libs/libgcc_s-39080030.so.1 +0 -0
pyqwest/pyqwest.pyi
ADDED
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
from collections.abc import (
|
|
2
|
+
AsyncIterator,
|
|
3
|
+
ItemsView,
|
|
4
|
+
Iterable,
|
|
5
|
+
Iterator,
|
|
6
|
+
KeysView,
|
|
7
|
+
Mapping,
|
|
8
|
+
Sequence,
|
|
9
|
+
ValuesView,
|
|
10
|
+
)
|
|
11
|
+
from types import TracebackType
|
|
12
|
+
from typing import Protocol, TypeAlias, TypeVar, overload
|
|
13
|
+
|
|
14
|
+
_T = TypeVar("_T")
|
|
15
|
+
JSON: TypeAlias = Mapping[str, JSON] | Sequence[JSON] | str | int | float | bool | None
|
|
16
|
+
|
|
17
|
+
class Headers:
|
|
18
|
+
"""Container of HTTP headers.
|
|
19
|
+
|
|
20
|
+
This class behaves like a dictionary with case-insensitive keys and
|
|
21
|
+
string values. Standard dictionary access will act as if keys can only
|
|
22
|
+
have a single value. The add method can be used to It additionally can be used to store
|
|
23
|
+
multiple values for the same key by using the add method. Iterating over
|
|
24
|
+
values or items will return all values, including duplicates.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self, items: Mapping[str, str] | Iterable[tuple[str, str]] | None = None
|
|
29
|
+
) -> None:
|
|
30
|
+
"""Creates a new Headers object.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
items: Initial headers to add.
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __getitem__(self, key: str) -> str:
|
|
37
|
+
"""Return the header value for the key.
|
|
38
|
+
|
|
39
|
+
If multiple values are present for the key, returns the first value.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
key: The header name.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
KeyError: If the key is not present.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
def __setitem__(self, key: str, value: str) -> None:
|
|
49
|
+
"""Sets the header value for the key, replacing any existing values.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
key: The header name.
|
|
53
|
+
value: The header value.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
def __delitem__(self, key: str) -> None:
|
|
57
|
+
"""Deletes all values for the key.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
key: The header name.
|
|
61
|
+
|
|
62
|
+
Raises:
|
|
63
|
+
KeyError: If the key is not present.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
def __iter__(self) -> Iterator[str]:
|
|
67
|
+
"""Returns an iterator over the header names."""
|
|
68
|
+
|
|
69
|
+
def __len__(self) -> int:
|
|
70
|
+
"""Returns the number of unique header names."""
|
|
71
|
+
|
|
72
|
+
def __eq__(
|
|
73
|
+
self, other: Headers | Mapping[str, str] | Iterable[tuple[str, str]]
|
|
74
|
+
) -> bool:
|
|
75
|
+
"""Compares the headers for equality with another Headers object,
|
|
76
|
+
mapping, or iterable of key-value pairs.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
other: The object to compare against.
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
def get(self, key: str, default: str | None = None) -> str | None:
|
|
83
|
+
"""Returns the header value for the key, or default if not present.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
key: The header name.
|
|
87
|
+
default: The default value to return if the key is not present.
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
@overload
|
|
91
|
+
def pop(self, key: str) -> str:
|
|
92
|
+
"""Removes and returns the header value for the key.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
key: The header name.
|
|
96
|
+
|
|
97
|
+
Raises:
|
|
98
|
+
KeyError: If the key is not present.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
@overload
|
|
102
|
+
def pop(self, key: str, default: _T) -> str | _T:
|
|
103
|
+
"""Removes and returns the header value for the key, or default if not present.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
key: The header name.
|
|
107
|
+
default: The default value to return if the key is not present.
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
def popitem(self) -> tuple[str, str]:
|
|
111
|
+
"""Removes and returns an arbitrary (name, value) pair. Will return the same
|
|
112
|
+
name multiple times if it has multiple values.
|
|
113
|
+
|
|
114
|
+
Raises:
|
|
115
|
+
KeyError: If the headers are empty.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def setdefault(self, key: str, default: str | None = None) -> str:
|
|
119
|
+
"""If the key is not present, sets it to the default value.
|
|
120
|
+
Returns the value for the key.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
key: The header name.
|
|
124
|
+
default: The default value to set and return if the key is not present.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
def add(self, key: str, value: str) -> None:
|
|
128
|
+
"""Adds a header value for the key. Existing values are preserved.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
key: The header name.
|
|
132
|
+
value: The header value.
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
@overload
|
|
136
|
+
def update(self, **kwargs: str) -> None:
|
|
137
|
+
"""Updates headers from keyword arguments. Existing values are replaced.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
**kwargs: Header names and values to set.
|
|
141
|
+
"""
|
|
142
|
+
@overload
|
|
143
|
+
def update(
|
|
144
|
+
self, items: Mapping[str, str] | Iterable[tuple[str, str]], /, **kwargs: str
|
|
145
|
+
) -> None:
|
|
146
|
+
"""Updates headers with the provided items. Existing values are replaced.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
items: Header names and values to set.
|
|
150
|
+
**kwargs: Additional header names and values to set after items. May overwrite items.
|
|
151
|
+
"""
|
|
152
|
+
|
|
153
|
+
def clear(self) -> None:
|
|
154
|
+
"""Removes all headers."""
|
|
155
|
+
|
|
156
|
+
def getall(self, key: str) -> Sequence[str]:
|
|
157
|
+
"""Returns all header values for the key.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
key: The header name.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def items(self) -> ItemsView[str, str]:
|
|
164
|
+
"""Returns a new view of all header name-value pairs, including duplicates."""
|
|
165
|
+
|
|
166
|
+
def keys(self) -> KeysView[str]:
|
|
167
|
+
"""Returns a new view of all unique header names."""
|
|
168
|
+
|
|
169
|
+
def values(self) -> ValuesView[str]:
|
|
170
|
+
"""Returns a new view of all header values, including duplicates."""
|
|
171
|
+
|
|
172
|
+
def __contains__(self, key: object) -> bool:
|
|
173
|
+
"""Returns True if the header name is present.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
key: The header name.
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
class HTTPVersion:
|
|
180
|
+
"""An enumeration of HTTP versions."""
|
|
181
|
+
|
|
182
|
+
HTTP1: HTTPVersion
|
|
183
|
+
"""HTTP/1.1"""
|
|
184
|
+
|
|
185
|
+
HTTP2: HTTPVersion
|
|
186
|
+
"""HTTP/2"""
|
|
187
|
+
|
|
188
|
+
HTTP3: HTTPVersion
|
|
189
|
+
"""HTTP/3"""
|
|
190
|
+
|
|
191
|
+
class Client:
|
|
192
|
+
"""An asynchronous HTTP client.
|
|
193
|
+
|
|
194
|
+
A client is a lightweight wrapper around a Transport, providing convenience methods
|
|
195
|
+
for common HTTP operations with buffering.
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
def __init__(self, transport: Transport | None = None) -> None:
|
|
199
|
+
"""Creates a new asynchronous HTTP client.
|
|
200
|
+
|
|
201
|
+
Args:
|
|
202
|
+
transport: The transport to use for requests. If None, the shared default
|
|
203
|
+
transport will be used.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
async def get(
|
|
207
|
+
self,
|
|
208
|
+
url: str,
|
|
209
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
210
|
+
timeout: float | None = None,
|
|
211
|
+
) -> FullResponse:
|
|
212
|
+
"""Executes a GET HTTP request.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
url: The unencoded request URL.
|
|
216
|
+
headers: The request headers.
|
|
217
|
+
timeout: The timeout for the request in seconds.
|
|
218
|
+
|
|
219
|
+
Raises:
|
|
220
|
+
ConnectionError: If the connection fails.
|
|
221
|
+
TimeoutError: If the request times out.
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
async def post(
|
|
225
|
+
self,
|
|
226
|
+
url: str,
|
|
227
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
228
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
229
|
+
timeout: float | None = None,
|
|
230
|
+
) -> FullResponse:
|
|
231
|
+
"""Executes a POST HTTP request.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
url: The unencoded request URL.
|
|
235
|
+
headers: The request headers.
|
|
236
|
+
content: The request content.
|
|
237
|
+
timeout: The timeout for the request in seconds.
|
|
238
|
+
|
|
239
|
+
Raises:
|
|
240
|
+
ConnectionError: If the connection fails.
|
|
241
|
+
TimeoutError: If the request times out.
|
|
242
|
+
"""
|
|
243
|
+
|
|
244
|
+
async def delete(
|
|
245
|
+
self,
|
|
246
|
+
url: str,
|
|
247
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
248
|
+
timeout: float | None = None,
|
|
249
|
+
) -> FullResponse:
|
|
250
|
+
"""Executes a DELETE HTTP request.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
url: The unencoded request URL.
|
|
254
|
+
headers: The request headers.
|
|
255
|
+
timeout: The timeout for the request in seconds.
|
|
256
|
+
|
|
257
|
+
Raises:
|
|
258
|
+
ConnectionError: If the connection fails.
|
|
259
|
+
TimeoutError: If the request times out.
|
|
260
|
+
"""
|
|
261
|
+
|
|
262
|
+
async def head(
|
|
263
|
+
self,
|
|
264
|
+
url: str,
|
|
265
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
266
|
+
timeout: float | None = None,
|
|
267
|
+
) -> FullResponse:
|
|
268
|
+
"""Executes a HEAD HTTP request.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
url: The unencoded request URL.
|
|
272
|
+
headers: The request headers.
|
|
273
|
+
timeout: The timeout for the request in seconds.
|
|
274
|
+
|
|
275
|
+
Raises:
|
|
276
|
+
ConnectionError: If the connection fails.
|
|
277
|
+
TimeoutError: If the request times out.
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
async def options(
|
|
281
|
+
self,
|
|
282
|
+
url: str,
|
|
283
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
284
|
+
timeout: float | None = None,
|
|
285
|
+
) -> FullResponse:
|
|
286
|
+
"""Executes a OPTIONS HTTP request.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
url: The unencoded request URL.
|
|
290
|
+
headers: The request headers.
|
|
291
|
+
timeout: The timeout for the request in seconds.
|
|
292
|
+
|
|
293
|
+
Raises:
|
|
294
|
+
ConnectionError: If the connection fails.
|
|
295
|
+
TimeoutError: If the request times out.
|
|
296
|
+
"""
|
|
297
|
+
|
|
298
|
+
async def patch(
|
|
299
|
+
self,
|
|
300
|
+
url: str,
|
|
301
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
302
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
303
|
+
timeout: float | None = None,
|
|
304
|
+
) -> FullResponse:
|
|
305
|
+
"""Executes a PATCH HTTP request.
|
|
306
|
+
|
|
307
|
+
Args:
|
|
308
|
+
url: The unencoded request URL.
|
|
309
|
+
headers: The request headers.
|
|
310
|
+
content: The request content.
|
|
311
|
+
timeout: The timeout for the request in seconds.
|
|
312
|
+
|
|
313
|
+
Raises:
|
|
314
|
+
ConnectionError: If the connection fails.
|
|
315
|
+
TimeoutError: If the request times out.
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
async def put(
|
|
319
|
+
self,
|
|
320
|
+
url: str,
|
|
321
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
322
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
323
|
+
timeout: float | None = None,
|
|
324
|
+
) -> FullResponse:
|
|
325
|
+
"""Executes a PUT HTTP request.
|
|
326
|
+
|
|
327
|
+
Args:
|
|
328
|
+
url: The unencoded request URL.
|
|
329
|
+
headers: The request headers.
|
|
330
|
+
content: The request content.
|
|
331
|
+
timeout: The timeout for the request in seconds.
|
|
332
|
+
|
|
333
|
+
Raises:
|
|
334
|
+
ConnectionError: If the connection fails.
|
|
335
|
+
TimeoutError: If the request times out.
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
async def execute(
|
|
339
|
+
self,
|
|
340
|
+
method: str,
|
|
341
|
+
url: str,
|
|
342
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
343
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
344
|
+
timeout: float | None = None,
|
|
345
|
+
) -> FullResponse:
|
|
346
|
+
"""Executes an HTTP request, returning the full buffered response.
|
|
347
|
+
|
|
348
|
+
Args:
|
|
349
|
+
method: The HTTP method.
|
|
350
|
+
url: The unencoded request URL.
|
|
351
|
+
headers: The request headers.
|
|
352
|
+
content: The request content.
|
|
353
|
+
timeout: The timeout for the request in seconds.
|
|
354
|
+
|
|
355
|
+
Raises:
|
|
356
|
+
ConnectionError: If the connection fails.
|
|
357
|
+
TimeoutError: If the request times out.
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
async def stream(
|
|
361
|
+
self,
|
|
362
|
+
method: str,
|
|
363
|
+
url: str,
|
|
364
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
365
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
366
|
+
timeout: float | None = None,
|
|
367
|
+
) -> Response:
|
|
368
|
+
"""Executes an HTTP request, allowing the response content to be streamed.
|
|
369
|
+
|
|
370
|
+
Args:
|
|
371
|
+
method: The HTTP method.
|
|
372
|
+
url: The unencoded request URL.
|
|
373
|
+
headers: The request headers.
|
|
374
|
+
content: The request content.
|
|
375
|
+
timeout: The timeout for the request in seconds.
|
|
376
|
+
|
|
377
|
+
Raises:
|
|
378
|
+
ConnectionError: If the connection fails.
|
|
379
|
+
TimeoutError: If the request times out.
|
|
380
|
+
"""
|
|
381
|
+
|
|
382
|
+
class Transport(Protocol):
|
|
383
|
+
"""Protocol for asynchronous HTTP transport implementations.
|
|
384
|
+
|
|
385
|
+
The default implementation of Transport is HTTPTransport which issues requests.
|
|
386
|
+
Custom implementations may be useful to:
|
|
387
|
+
|
|
388
|
+
- Mock requests for testing.
|
|
389
|
+
- Add middleware wrapping transports
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
async def execute(self, request: Request) -> Response:
|
|
393
|
+
"""Executes a request."""
|
|
394
|
+
|
|
395
|
+
class HTTPTransport:
|
|
396
|
+
"""An HTTP transport implementation using reqwest."""
|
|
397
|
+
|
|
398
|
+
def __init__(
|
|
399
|
+
self,
|
|
400
|
+
*,
|
|
401
|
+
tls_ca_cert: bytes | None = None,
|
|
402
|
+
tls_key: bytes | None = None,
|
|
403
|
+
tls_cert: bytes | None = None,
|
|
404
|
+
http_version: HTTPVersion | None = None,
|
|
405
|
+
timeout: float | None = None,
|
|
406
|
+
connect_timeout: float | None = None,
|
|
407
|
+
read_timeout: float | None = None,
|
|
408
|
+
pool_idle_timeout: float | None = None,
|
|
409
|
+
pool_max_idle_per_host: int | None = None,
|
|
410
|
+
tcp_keepalive_interval: float | None = None,
|
|
411
|
+
enable_gzip: bool = False,
|
|
412
|
+
enable_brotli: bool = False,
|
|
413
|
+
enable_zstd: bool = False,
|
|
414
|
+
use_system_dns: bool = False,
|
|
415
|
+
) -> None:
|
|
416
|
+
"""Creates a new HTTPTransport object.
|
|
417
|
+
|
|
418
|
+
Without any arguments, the transport behaves like a raw, low-level HTTP transport,
|
|
419
|
+
with no timeouts or other higher level behavior. When creating a transport, take care
|
|
420
|
+
to set options to meet your needs. Also consider using get_default_transport instead
|
|
421
|
+
which is preconfigured with reasonable defaults, though does not support custom TLS
|
|
422
|
+
certificates.
|
|
423
|
+
|
|
424
|
+
Args:
|
|
425
|
+
tls_ca_cert: The CA certificate to use to verify the server for TLS connections.
|
|
426
|
+
tls_key: The client private key to identify the client for mTLS connections.
|
|
427
|
+
tls_cert must also be set.
|
|
428
|
+
tls_cert: The client certificate to identify the client for mTLS connections.
|
|
429
|
+
tls_key must also be set.
|
|
430
|
+
http_version: The HTTP version to use for requests. If unset, HTTP/1 is used for
|
|
431
|
+
plaintext and ALPN negotiates the version for TLS connections
|
|
432
|
+
which typically means HTTP/2 if the server supports it.
|
|
433
|
+
timeout: Default timeout for requests in seconds. This is the timeout from
|
|
434
|
+
the start of the request to the end of the response.
|
|
435
|
+
connect_timeout: Timeout for connection establishment in seconds.
|
|
436
|
+
read_timeout: Timeout for each read operation of a request in seconds.
|
|
437
|
+
pool_idle_timeout: Timeout for idle connections in the connection pool in seconds.
|
|
438
|
+
pool_max_idle_per_host: Maximum number of idle connections to keep in the pool per host.
|
|
439
|
+
Defaults to 2.
|
|
440
|
+
tcp_keepalive_interval: Interval for TCP keepalive probes in seconds.
|
|
441
|
+
enable_gzip: Whether to enable gzip decompression for responses.
|
|
442
|
+
enable_brotli: Whether to enable brotli decompression for responses.
|
|
443
|
+
enable_zstd: Whether to enable zstd decompression for responses.
|
|
444
|
+
use_system_dns: Whether to use the system DNS resolver. By default, pyqwest uses an
|
|
445
|
+
asynchronous DNS resolver implemented in Rust, but it can have different
|
|
446
|
+
behavior from system DNS in certain environments. Try enabling this option if
|
|
447
|
+
you have any DNS resolution issues.
|
|
448
|
+
"""
|
|
449
|
+
|
|
450
|
+
async def __aenter__(self) -> HTTPTransport:
|
|
451
|
+
"""Enters the context manager for the transport to automatically close it when
|
|
452
|
+
leaving.
|
|
453
|
+
"""
|
|
454
|
+
|
|
455
|
+
async def __aexit__(
|
|
456
|
+
self,
|
|
457
|
+
_exc_type: type[BaseException] | None,
|
|
458
|
+
_exc_value: BaseException | None,
|
|
459
|
+
_traceback: TracebackType | None,
|
|
460
|
+
) -> None:
|
|
461
|
+
"""Exits the context manager for the transport, closing it."""
|
|
462
|
+
|
|
463
|
+
async def execute(self, request: Request) -> Response:
|
|
464
|
+
"""Executes the given request, returning the response.
|
|
465
|
+
|
|
466
|
+
Args:
|
|
467
|
+
request: The request to execute.
|
|
468
|
+
|
|
469
|
+
Raises:
|
|
470
|
+
ConnectionError: If the connection fails.
|
|
471
|
+
TimeoutError: If the request times out.
|
|
472
|
+
"""
|
|
473
|
+
|
|
474
|
+
async def close(self) -> None:
|
|
475
|
+
"""Closes the transport, releasing any underlying resources."""
|
|
476
|
+
|
|
477
|
+
def get_default_transport() -> HTTPTransport:
|
|
478
|
+
"""Returns the singleton default HTTP transport instance used by clients that do not
|
|
479
|
+
specify a transport.
|
|
480
|
+
|
|
481
|
+
The default transport is constructed as follows:
|
|
482
|
+
```
|
|
483
|
+
HTTPTransport(
|
|
484
|
+
connect_timeout=30.0,
|
|
485
|
+
pool_idle_timeout=90.0,
|
|
486
|
+
pool_max_idle_per_host=2,
|
|
487
|
+
tcp_keepalive_interval=30.0,
|
|
488
|
+
enable_gzip: bool = True,
|
|
489
|
+
enable_brotli: bool = True,
|
|
490
|
+
enable_zstd: bool = True,
|
|
491
|
+
)
|
|
492
|
+
```
|
|
493
|
+
"""
|
|
494
|
+
|
|
495
|
+
class Request:
|
|
496
|
+
"""An HTTP request."""
|
|
497
|
+
|
|
498
|
+
def __init__(
|
|
499
|
+
self,
|
|
500
|
+
method: str,
|
|
501
|
+
url: str,
|
|
502
|
+
headers: Headers | None = None,
|
|
503
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
504
|
+
) -> None:
|
|
505
|
+
"""Creates a new Request object.
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
method: The HTTP method.
|
|
509
|
+
url: The unencoded request URL.
|
|
510
|
+
headers: The request headers.
|
|
511
|
+
content: The request content.
|
|
512
|
+
"""
|
|
513
|
+
|
|
514
|
+
@property
|
|
515
|
+
def method(self) -> str:
|
|
516
|
+
"""Returns the HTTP method of the request."""
|
|
517
|
+
|
|
518
|
+
@property
|
|
519
|
+
def url(self) -> str:
|
|
520
|
+
"""Returns the unencoded request URL."""
|
|
521
|
+
|
|
522
|
+
@property
|
|
523
|
+
def headers(self) -> Headers:
|
|
524
|
+
"""Returns the request headers."""
|
|
525
|
+
|
|
526
|
+
@property
|
|
527
|
+
def content(self) -> AsyncIterator[bytes]:
|
|
528
|
+
"""Returns an async iterator over the request content."""
|
|
529
|
+
|
|
530
|
+
class Response:
|
|
531
|
+
"""An HTTP response."""
|
|
532
|
+
|
|
533
|
+
def __init__(
|
|
534
|
+
self,
|
|
535
|
+
*,
|
|
536
|
+
status: int,
|
|
537
|
+
http_version: HTTPVersion | None = None,
|
|
538
|
+
headers: Headers | None = None,
|
|
539
|
+
content: bytes | AsyncIterator[bytes] | None = None,
|
|
540
|
+
trailers: Headers | None = None,
|
|
541
|
+
) -> None:
|
|
542
|
+
"""Creates a new Response object.
|
|
543
|
+
|
|
544
|
+
Care must be taken if your service uses trailers and you override content.
|
|
545
|
+
Trailers will not be received without fully consuming the original response content.
|
|
546
|
+
Patterns that wrap the original response content should not have any issue but if
|
|
547
|
+
you replace it completely and need trailers, make sure to still read and discard
|
|
548
|
+
the original content.
|
|
549
|
+
|
|
550
|
+
Args:
|
|
551
|
+
status: The HTTP status code of the response.
|
|
552
|
+
http_version: The HTTP version of the response.
|
|
553
|
+
headers: The response headers.
|
|
554
|
+
content: The response content.
|
|
555
|
+
trailers: The response trailers.
|
|
556
|
+
"""
|
|
557
|
+
|
|
558
|
+
async def __aenter__(self) -> Response:
|
|
559
|
+
"""Enters the context manager for the response to automatically close it when
|
|
560
|
+
leaving.
|
|
561
|
+
|
|
562
|
+
Note that if your code is guaranteed to fully consume the response content,
|
|
563
|
+
it is not necessary to explicitly close the response.
|
|
564
|
+
"""
|
|
565
|
+
|
|
566
|
+
async def __aexit__(
|
|
567
|
+
self,
|
|
568
|
+
_exc_type: type[BaseException] | None,
|
|
569
|
+
_exc_value: BaseException | None,
|
|
570
|
+
_traceback: TracebackType | None,
|
|
571
|
+
) -> None:
|
|
572
|
+
"""Exits the context manager for the response, closing it."""
|
|
573
|
+
|
|
574
|
+
@property
|
|
575
|
+
def status(self) -> int:
|
|
576
|
+
"""Returns the HTTP status code of the response."""
|
|
577
|
+
|
|
578
|
+
@property
|
|
579
|
+
def http_version(self) -> HTTPVersion:
|
|
580
|
+
"""Returns the HTTP version of the response."""
|
|
581
|
+
|
|
582
|
+
@property
|
|
583
|
+
def headers(self) -> Headers:
|
|
584
|
+
"""Returns the response headers."""
|
|
585
|
+
|
|
586
|
+
@property
|
|
587
|
+
def content(self) -> AsyncIterator[bytes]:
|
|
588
|
+
"""Returns an asynchronous iterator over the response content."""
|
|
589
|
+
|
|
590
|
+
@property
|
|
591
|
+
def trailers(self) -> Headers:
|
|
592
|
+
"""Returns the response trailers.
|
|
593
|
+
|
|
594
|
+
Because trailers complete the response, this will only be filled after fully
|
|
595
|
+
consuming the content iterator.
|
|
596
|
+
"""
|
|
597
|
+
|
|
598
|
+
async def read_full(self) -> FullResponse:
|
|
599
|
+
"""Reads the full response content, returning a FullResponse with it.
|
|
600
|
+
|
|
601
|
+
After calling this method, the content iterator on this object will be empty.
|
|
602
|
+
It is expected that this method is called to replace Response with FullResponse
|
|
603
|
+
for full access to the response.
|
|
604
|
+
"""
|
|
605
|
+
|
|
606
|
+
async def close(self) -> None:
|
|
607
|
+
"""Closes the response, releasing any underlying resources.
|
|
608
|
+
|
|
609
|
+
Note that if your code is guaranteed to fully consume the response content,
|
|
610
|
+
it is not necessary to explicitly close the response.
|
|
611
|
+
"""
|
|
612
|
+
|
|
613
|
+
class SyncClient:
|
|
614
|
+
"""A synchronous HTTP client.
|
|
615
|
+
|
|
616
|
+
A client is a lightweight wrapper around a SyncTransport, providing convenience methods
|
|
617
|
+
for common HTTP operations with buffering.
|
|
618
|
+
"""
|
|
619
|
+
|
|
620
|
+
def __init__(self, transport: SyncTransport | None = None) -> None:
|
|
621
|
+
"""Creates a new synchronous HTTP client.
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
transport: The transport to use for requests. If None, the shared default
|
|
625
|
+
transport will be used.
|
|
626
|
+
"""
|
|
627
|
+
|
|
628
|
+
def get(
|
|
629
|
+
self,
|
|
630
|
+
url: str,
|
|
631
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
632
|
+
timeout: float | None = None,
|
|
633
|
+
) -> FullResponse:
|
|
634
|
+
"""Executes a GET HTTP request.
|
|
635
|
+
|
|
636
|
+
Args:
|
|
637
|
+
url: The unencoded request URL.
|
|
638
|
+
headers: The request headers.
|
|
639
|
+
timeout: The timeout for the request in seconds.
|
|
640
|
+
|
|
641
|
+
Raises:
|
|
642
|
+
ConnectionError: If the connection fails.
|
|
643
|
+
TimeoutError: If the request times out.
|
|
644
|
+
"""
|
|
645
|
+
|
|
646
|
+
def post(
|
|
647
|
+
self,
|
|
648
|
+
url: str,
|
|
649
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
650
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
651
|
+
timeout: float | None = None,
|
|
652
|
+
) -> FullResponse:
|
|
653
|
+
"""Executes a POST HTTP request.
|
|
654
|
+
|
|
655
|
+
Args:
|
|
656
|
+
url: The unencoded request URL.
|
|
657
|
+
headers: The request headers.
|
|
658
|
+
content: The request content.
|
|
659
|
+
timeout: The timeout for the request in seconds.
|
|
660
|
+
|
|
661
|
+
Raises:
|
|
662
|
+
ConnectionError: If the connection fails.
|
|
663
|
+
TimeoutError: If the request times out.
|
|
664
|
+
"""
|
|
665
|
+
|
|
666
|
+
def delete(
|
|
667
|
+
self,
|
|
668
|
+
url: str,
|
|
669
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
670
|
+
timeout: float | None = None,
|
|
671
|
+
) -> FullResponse:
|
|
672
|
+
"""Executes a DELETE HTTP request.
|
|
673
|
+
|
|
674
|
+
Args:
|
|
675
|
+
url: The unencoded request URL.
|
|
676
|
+
headers: The request headers.
|
|
677
|
+
timeout: The timeout for the request in seconds.
|
|
678
|
+
|
|
679
|
+
Raises:
|
|
680
|
+
ConnectionError: If the connection fails.
|
|
681
|
+
TimeoutError: If the request times out.
|
|
682
|
+
"""
|
|
683
|
+
|
|
684
|
+
def head(
|
|
685
|
+
self,
|
|
686
|
+
url: str,
|
|
687
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
688
|
+
timeout: float | None = None,
|
|
689
|
+
) -> FullResponse:
|
|
690
|
+
"""Executes a HEAD HTTP request.
|
|
691
|
+
|
|
692
|
+
Args:
|
|
693
|
+
url: The unencoded request URL.
|
|
694
|
+
headers: The request headers.
|
|
695
|
+
timeout: The timeout for the request in seconds.
|
|
696
|
+
|
|
697
|
+
Raises:
|
|
698
|
+
ConnectionError: If the connection fails.
|
|
699
|
+
TimeoutError: If the request times out.
|
|
700
|
+
"""
|
|
701
|
+
|
|
702
|
+
def options(
|
|
703
|
+
self,
|
|
704
|
+
url: str,
|
|
705
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
706
|
+
timeout: float | None = None,
|
|
707
|
+
) -> FullResponse:
|
|
708
|
+
"""Executes a OPTIONS HTTP request.
|
|
709
|
+
|
|
710
|
+
Args:
|
|
711
|
+
url: The unencoded request URL.
|
|
712
|
+
headers: The request headers.
|
|
713
|
+
timeout: The timeout for the request in seconds.
|
|
714
|
+
|
|
715
|
+
Raises:
|
|
716
|
+
ConnectionError: If the connection fails.
|
|
717
|
+
TimeoutError: If the request times out.
|
|
718
|
+
"""
|
|
719
|
+
|
|
720
|
+
def patch(
|
|
721
|
+
self,
|
|
722
|
+
url: str,
|
|
723
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
724
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
725
|
+
timeout: float | None = None,
|
|
726
|
+
) -> FullResponse:
|
|
727
|
+
"""Executes a PATCH HTTP request.
|
|
728
|
+
|
|
729
|
+
Args:
|
|
730
|
+
url: The unencoded request URL.
|
|
731
|
+
headers: The request headers.
|
|
732
|
+
content: The request content.
|
|
733
|
+
timeout: The timeout for the request in seconds.
|
|
734
|
+
|
|
735
|
+
Raises:
|
|
736
|
+
ConnectionError: If the connection fails.
|
|
737
|
+
TimeoutError: If the request times out.
|
|
738
|
+
"""
|
|
739
|
+
|
|
740
|
+
def put(
|
|
741
|
+
self,
|
|
742
|
+
url: str,
|
|
743
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
744
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
745
|
+
timeout: float | None = None,
|
|
746
|
+
) -> FullResponse:
|
|
747
|
+
"""Executes a PUT HTTP request.
|
|
748
|
+
|
|
749
|
+
Args:
|
|
750
|
+
url: The unencoded request URL.
|
|
751
|
+
headers: The request headers.
|
|
752
|
+
content: The request content.
|
|
753
|
+
timeout: The timeout for the request in seconds.
|
|
754
|
+
|
|
755
|
+
Raises:
|
|
756
|
+
ConnectionError: If the connection fails.
|
|
757
|
+
TimeoutError: If the request times out.
|
|
758
|
+
"""
|
|
759
|
+
|
|
760
|
+
def execute(
|
|
761
|
+
self,
|
|
762
|
+
method: str,
|
|
763
|
+
url: str,
|
|
764
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
765
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
766
|
+
timeout: float | None = None,
|
|
767
|
+
) -> FullResponse:
|
|
768
|
+
"""Executes an HTTP request, returning the full buffered response.
|
|
769
|
+
|
|
770
|
+
Args:
|
|
771
|
+
method: The HTTP method.
|
|
772
|
+
url: The unencoded request URL.
|
|
773
|
+
headers: The request headers.
|
|
774
|
+
content: The request content.
|
|
775
|
+
timeout: The timeout for the request in seconds.
|
|
776
|
+
|
|
777
|
+
Raises:
|
|
778
|
+
ConnectionError: If the connection fails.
|
|
779
|
+
TimeoutError: If the request times out.
|
|
780
|
+
"""
|
|
781
|
+
|
|
782
|
+
def stream(
|
|
783
|
+
self,
|
|
784
|
+
method: str,
|
|
785
|
+
url: str,
|
|
786
|
+
headers: Headers | Mapping[str, str] | Iterable[tuple[str, str]] | None = None,
|
|
787
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
788
|
+
timeout: float | None = None,
|
|
789
|
+
) -> SyncResponse:
|
|
790
|
+
"""Executes an HTTP request, allowing the response content to be streamed.
|
|
791
|
+
|
|
792
|
+
Args:
|
|
793
|
+
method: The HTTP method.
|
|
794
|
+
url: The unencoded request URL.
|
|
795
|
+
headers: The request headers.
|
|
796
|
+
content: The request content.
|
|
797
|
+
timeout: The timeout for the request in seconds.
|
|
798
|
+
|
|
799
|
+
Raises:
|
|
800
|
+
ConnectionError: If the connection fails.
|
|
801
|
+
TimeoutError: If the request times out.
|
|
802
|
+
"""
|
|
803
|
+
|
|
804
|
+
class SyncTransport(Protocol):
|
|
805
|
+
"""Protocol for synchronous HTTP transport implementations.
|
|
806
|
+
|
|
807
|
+
The default implementation of SyncTransport is SyncHTTPTransport which issues requests.
|
|
808
|
+
Custom implementations may be useful to:
|
|
809
|
+
|
|
810
|
+
- Mock requests for testing.
|
|
811
|
+
- Add middleware wrapping transports
|
|
812
|
+
"""
|
|
813
|
+
|
|
814
|
+
def execute(self, request: SyncRequest) -> SyncResponse:
|
|
815
|
+
"""Executes a request."""
|
|
816
|
+
|
|
817
|
+
class SyncHTTPTransport:
|
|
818
|
+
"""An HTTP transport implementation using reqwest."""
|
|
819
|
+
|
|
820
|
+
def __init__(
|
|
821
|
+
self,
|
|
822
|
+
*,
|
|
823
|
+
tls_ca_cert: bytes | None = None,
|
|
824
|
+
tls_key: bytes | None = None,
|
|
825
|
+
tls_cert: bytes | None = None,
|
|
826
|
+
http_version: HTTPVersion | None = None,
|
|
827
|
+
timeout: float | None = None,
|
|
828
|
+
connect_timeout: float | None = None,
|
|
829
|
+
read_timeout: float | None = None,
|
|
830
|
+
pool_idle_timeout: float | None = None,
|
|
831
|
+
pool_max_idle_per_host: int | None = None,
|
|
832
|
+
tcp_keepalive_interval: float | None = None,
|
|
833
|
+
enable_gzip: bool = False,
|
|
834
|
+
enable_brotli: bool = False,
|
|
835
|
+
enable_zstd: bool = False,
|
|
836
|
+
use_system_dns: bool = False,
|
|
837
|
+
) -> None:
|
|
838
|
+
"""Creates a new SyncHTTPTransport object.
|
|
839
|
+
|
|
840
|
+
Without any arguments, the transport behaves like a raw, low-level HTTP transport,
|
|
841
|
+
with no timeouts or other higher level behavior. When creating a transport, take care
|
|
842
|
+
to set options to meet your needs. Also consider using get_default_transport instead
|
|
843
|
+
which is preconfigured with reasonable defaults, though does not support custom TLS
|
|
844
|
+
certificates.
|
|
845
|
+
|
|
846
|
+
Args:
|
|
847
|
+
tls_ca_cert: The CA certificate to use to verify the server for TLS connections.
|
|
848
|
+
tls_key: The client private key to identify the client for mTLS connections.
|
|
849
|
+
tls_cert must also be set.
|
|
850
|
+
tls_cert: The client certificate to identify the client for mTLS connections.
|
|
851
|
+
tls_key must also be set.
|
|
852
|
+
http_version: The HTTP version to use for requests. If unset, HTTP/1 is used for
|
|
853
|
+
plaintext and ALPN negotiates the version for TLS connections
|
|
854
|
+
which typically means HTTP/2 if the server supports it.
|
|
855
|
+
timeout: Default timeout for requests in seconds. This is the timeout from
|
|
856
|
+
the start of the request to the end of the response.
|
|
857
|
+
connect_timeout: Timeout for connection establishment in seconds.
|
|
858
|
+
read_timeout: Timeout for each read operation of a request in seconds.
|
|
859
|
+
pool_idle_timeout: Timeout for idle connections in the connection pool in seconds.
|
|
860
|
+
pool_max_idle_per_host: Maximum number of idle connections to keep in the pool per host.
|
|
861
|
+
Defaults to 2.
|
|
862
|
+
tcp_keepalive_interval: Interval for TCP keepalive probes in seconds.
|
|
863
|
+
enable_gzip: Whether to enable gzip decompression for responses.
|
|
864
|
+
enable_brotli: Whether to enable brotli decompression for responses.
|
|
865
|
+
enable_zstd: Whether to enable zstd decompression for responses.
|
|
866
|
+
use_system_dns: Whether to use the system DNS resolver. By default, pyqwest uses an
|
|
867
|
+
asynchronous DNS resolver implemented in Rust, but it can have different
|
|
868
|
+
behavior from system DNS in certain environments. Try enabling this option if
|
|
869
|
+
you have any DNS resolution issues.
|
|
870
|
+
"""
|
|
871
|
+
|
|
872
|
+
def __enter__(self) -> SyncHTTPTransport:
|
|
873
|
+
"""Enters the context manager for the transport to automatically
|
|
874
|
+
close it when leaving.
|
|
875
|
+
"""
|
|
876
|
+
|
|
877
|
+
def __exit__(
|
|
878
|
+
self,
|
|
879
|
+
_exc_type: type[BaseException] | None,
|
|
880
|
+
_exc_value: BaseException | None,
|
|
881
|
+
_traceback: TracebackType | None,
|
|
882
|
+
) -> None:
|
|
883
|
+
"""Exits the context manager for the transport, closing it."""
|
|
884
|
+
|
|
885
|
+
def execute(self, request: SyncRequest) -> SyncResponse:
|
|
886
|
+
"""Executes the given request, returning the response.
|
|
887
|
+
|
|
888
|
+
Args:
|
|
889
|
+
request: The request to execute.
|
|
890
|
+
"""
|
|
891
|
+
|
|
892
|
+
def close(self) -> None:
|
|
893
|
+
"""Closes the transport, releasing any underlying resources."""
|
|
894
|
+
|
|
895
|
+
def get_default_sync_transport() -> SyncHTTPTransport:
|
|
896
|
+
"""Returns the singleton default HTTP transport instance used by synchronous clients that do not
|
|
897
|
+
specify a transport.ult HTTP transport instance used by clients that do not
|
|
898
|
+
specify a transport.
|
|
899
|
+
|
|
900
|
+
The default transport is constructed as follows:
|
|
901
|
+
```
|
|
902
|
+
SyncHTTPTransport(
|
|
903
|
+
connect_timeout=30.0,
|
|
904
|
+
pool_idle_timeout=90.0,
|
|
905
|
+
pool_max_idle_per_host=2,
|
|
906
|
+
tcp_keepalive_interval=30.0,
|
|
907
|
+
enable_gzip: bool = True,
|
|
908
|
+
enable_brotli: bool = True,
|
|
909
|
+
enable_zstd: bool = True,
|
|
910
|
+
)
|
|
911
|
+
```
|
|
912
|
+
"""
|
|
913
|
+
|
|
914
|
+
class SyncRequest:
|
|
915
|
+
"""An HTTP request."""
|
|
916
|
+
|
|
917
|
+
def __init__(
|
|
918
|
+
self,
|
|
919
|
+
method: str,
|
|
920
|
+
url: str,
|
|
921
|
+
headers: Headers | None = None,
|
|
922
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
923
|
+
) -> None:
|
|
924
|
+
"""Creates a new SyncRequest object.
|
|
925
|
+
|
|
926
|
+
Args:
|
|
927
|
+
method: The HTTP method.
|
|
928
|
+
url: The unencoded request URL.
|
|
929
|
+
headers: The request headers.
|
|
930
|
+
content: The request content.
|
|
931
|
+
timeout: The timeout for the request in seconds.
|
|
932
|
+
"""
|
|
933
|
+
|
|
934
|
+
@property
|
|
935
|
+
def method(self) -> str:
|
|
936
|
+
"""Returns the HTTP method of the request."""
|
|
937
|
+
|
|
938
|
+
@property
|
|
939
|
+
def url(self) -> str:
|
|
940
|
+
"""Returns the unencoded request URL."""
|
|
941
|
+
|
|
942
|
+
@property
|
|
943
|
+
def headers(self) -> Headers:
|
|
944
|
+
"""Returns the request headers."""
|
|
945
|
+
|
|
946
|
+
@property
|
|
947
|
+
def content(self) -> Iterator[bytes]:
|
|
948
|
+
"""Returns an iterator over the request content."""
|
|
949
|
+
|
|
950
|
+
class SyncResponse:
|
|
951
|
+
"""An HTTP response."""
|
|
952
|
+
|
|
953
|
+
def __init__(
|
|
954
|
+
self,
|
|
955
|
+
*,
|
|
956
|
+
status: int,
|
|
957
|
+
http_version: HTTPVersion | None = None,
|
|
958
|
+
headers: Headers | None = None,
|
|
959
|
+
content: bytes | Iterable[bytes] | None = None,
|
|
960
|
+
trailers: Headers | None = None,
|
|
961
|
+
) -> None:
|
|
962
|
+
"""Creates a new SyncResponse object.
|
|
963
|
+
|
|
964
|
+
Care must be taken if your service uses trailers and you override content.
|
|
965
|
+
Trailers will not be received without fully consuming the original response content.
|
|
966
|
+
Patterns that wrap the original response content should not have any issue but if
|
|
967
|
+
you replace it completely and need trailers, make sure to still read and discard
|
|
968
|
+
the original content.
|
|
969
|
+
|
|
970
|
+
Args:
|
|
971
|
+
status: The HTTP status code of the response.
|
|
972
|
+
http_version: The HTTP version of the response.
|
|
973
|
+
headers: The response headers.
|
|
974
|
+
content: The response content.
|
|
975
|
+
trailers: The response trailers.
|
|
976
|
+
"""
|
|
977
|
+
|
|
978
|
+
def __enter__(self) -> SyncResponse:
|
|
979
|
+
"""Enters the context manager for the response to automatically
|
|
980
|
+
close it when leaving.
|
|
981
|
+
|
|
982
|
+
Note that if your code is guaranteed to fully consume the response content,
|
|
983
|
+
it is not necessary to explicitly close the response.
|
|
984
|
+
"""
|
|
985
|
+
|
|
986
|
+
def __exit__(
|
|
987
|
+
self,
|
|
988
|
+
_exc_type: type[BaseException] | None,
|
|
989
|
+
_exc_value: BaseException | None,
|
|
990
|
+
_traceback: TracebackType | None,
|
|
991
|
+
) -> None:
|
|
992
|
+
"""Exits the context manager for the response, closing it."""
|
|
993
|
+
|
|
994
|
+
@property
|
|
995
|
+
def status(self) -> int:
|
|
996
|
+
"""Returns the HTTP status code of the response."""
|
|
997
|
+
|
|
998
|
+
@property
|
|
999
|
+
def http_version(self) -> HTTPVersion:
|
|
1000
|
+
"""Returns the HTTP version of the response."""
|
|
1001
|
+
|
|
1002
|
+
@property
|
|
1003
|
+
def headers(self) -> Headers:
|
|
1004
|
+
"""Returns the response headers."""
|
|
1005
|
+
|
|
1006
|
+
@property
|
|
1007
|
+
def content(self) -> Iterator[bytes]:
|
|
1008
|
+
"""Returns an iterator over the response content."""
|
|
1009
|
+
|
|
1010
|
+
@property
|
|
1011
|
+
def trailers(self) -> Headers:
|
|
1012
|
+
"""Returns the response trailers.
|
|
1013
|
+
|
|
1014
|
+
Because trailers complete the response, this will only be filled after fully
|
|
1015
|
+
consuming the content iterator.
|
|
1016
|
+
"""
|
|
1017
|
+
|
|
1018
|
+
def read_full(self) -> FullResponse:
|
|
1019
|
+
"""Reads the full response content, returning a FullResponse with it.
|
|
1020
|
+
|
|
1021
|
+
After calling this method, the content iterator on this object will be empty.
|
|
1022
|
+
It is expected that this method is called to replace Response with FullResponse
|
|
1023
|
+
for full access to the response.
|
|
1024
|
+
"""
|
|
1025
|
+
|
|
1026
|
+
def close(self) -> None:
|
|
1027
|
+
"""Closes the response, releasing any underlying resources.
|
|
1028
|
+
|
|
1029
|
+
Note that if your code is guaranteed to fully consume the response content,
|
|
1030
|
+
it is not necessary to explicitly close the response.
|
|
1031
|
+
"""
|
|
1032
|
+
|
|
1033
|
+
class FullResponse:
|
|
1034
|
+
"""A fully buffered HTTP response."""
|
|
1035
|
+
|
|
1036
|
+
def __init__(
|
|
1037
|
+
self, status: int, headers: Headers, content: bytes, trailers: Headers
|
|
1038
|
+
) -> None:
|
|
1039
|
+
"""Creates a new FullResponse object.
|
|
1040
|
+
|
|
1041
|
+
Args:
|
|
1042
|
+
status: The HTTP status code of the response.
|
|
1043
|
+
headers: The response headers.
|
|
1044
|
+
content: The response content.
|
|
1045
|
+
trailers: The response trailers.
|
|
1046
|
+
"""
|
|
1047
|
+
|
|
1048
|
+
@property
|
|
1049
|
+
def status(self) -> int:
|
|
1050
|
+
"""Returns the HTTP status code of the response."""
|
|
1051
|
+
|
|
1052
|
+
@property
|
|
1053
|
+
def headers(self) -> Headers:
|
|
1054
|
+
"""Returns the response headers."""
|
|
1055
|
+
|
|
1056
|
+
@property
|
|
1057
|
+
def content(self) -> bytes:
|
|
1058
|
+
"""Returns the response content."""
|
|
1059
|
+
|
|
1060
|
+
@property
|
|
1061
|
+
def trailers(self) -> Headers:
|
|
1062
|
+
"""Returns the response trailers."""
|
|
1063
|
+
|
|
1064
|
+
def text(self) -> str:
|
|
1065
|
+
"""Returns the response content decoded as text.
|
|
1066
|
+
|
|
1067
|
+
The encoding for decoding is determined from the content-type header if present,
|
|
1068
|
+
defaulting to UTF-8 otherwise.
|
|
1069
|
+
"""
|
|
1070
|
+
|
|
1071
|
+
def json(self) -> JSON:
|
|
1072
|
+
"""Parses and returns the response content as JSON.
|
|
1073
|
+
|
|
1074
|
+
The content-type header is not checked when using this method.
|
|
1075
|
+
"""
|
|
1076
|
+
|
|
1077
|
+
class StreamErrorCode:
|
|
1078
|
+
NO_ERROR: StreamErrorCode
|
|
1079
|
+
PROTOCOL_ERROR: StreamErrorCode
|
|
1080
|
+
INTERNAL_ERROR: StreamErrorCode
|
|
1081
|
+
FLOW_CONTROL_ERROR: StreamErrorCode
|
|
1082
|
+
SETTINGS_TIMEOUT: StreamErrorCode
|
|
1083
|
+
STREAM_CLOSED: StreamErrorCode
|
|
1084
|
+
FRAME_SIZE_ERROR: StreamErrorCode
|
|
1085
|
+
REFUSED_STREAM: StreamErrorCode
|
|
1086
|
+
CANCEL: StreamErrorCode
|
|
1087
|
+
COMPRESSION_ERROR: StreamErrorCode
|
|
1088
|
+
CONNECT_ERROR: StreamErrorCode
|
|
1089
|
+
ENHANCE_YOUR_CALM: StreamErrorCode
|
|
1090
|
+
INADEQUATE_SECURITY: StreamErrorCode
|
|
1091
|
+
HTTP_1_1_REQUIRED: StreamErrorCode
|
|
1092
|
+
|
|
1093
|
+
class StreamError(Exception):
|
|
1094
|
+
"""An error representing an HTTP/2+ stream error."""
|
|
1095
|
+
|
|
1096
|
+
@property
|
|
1097
|
+
def code(self) -> StreamErrorCode:
|
|
1098
|
+
"""The stream error code."""
|
|
1099
|
+
|
|
1100
|
+
class ReadError(Exception):
|
|
1101
|
+
"""An error representing a read error during response reading."""
|
|
1102
|
+
|
|
1103
|
+
class WriteError(Exception):
|
|
1104
|
+
"""An error representing a write error during request sending."""
|