impit 0.9.0__cp313-cp313t-macosx_11_0_arm64.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.
impit/impit.pyi ADDED
@@ -0,0 +1,1320 @@
1
+ from __future__ import annotations
2
+ from http.cookiejar import CookieJar
3
+ from .cookies import Cookies
4
+
5
+ from typing import Literal, Any
6
+ from collections.abc import Iterator, AsyncIterator
7
+ from contextlib import AbstractAsyncContextManager, AbstractContextManager
8
+
9
+
10
+ Browser = Literal['chrome', 'firefox']
11
+
12
+
13
+ class HTTPError(Exception):
14
+ """Represents an HTTP-related error."""
15
+
16
+
17
+ class RequestError(HTTPError):
18
+ """Represents an error during the request process."""
19
+
20
+
21
+ class TransportError(RequestError):
22
+ """Represents a transport-layer error."""
23
+
24
+
25
+ class TimeoutException(TransportError):
26
+ """Represents a timeout error."""
27
+
28
+
29
+ class ConnectTimeout(TimeoutException):
30
+ """Represents a connection timeout error."""
31
+
32
+
33
+ class ReadTimeout(TimeoutException):
34
+ """Represents a read timeout error."""
35
+
36
+
37
+ class WriteTimeout(TimeoutException):
38
+ """Represents a write timeout error."""
39
+
40
+
41
+ class PoolTimeout(TimeoutException):
42
+ """Represents a connection pool timeout error."""
43
+
44
+
45
+ class NetworkError(TransportError):
46
+ """Represents a network-related error."""
47
+
48
+
49
+ class ConnectError(NetworkError):
50
+ """Represents a connection error."""
51
+
52
+
53
+ class ReadError(NetworkError):
54
+ """Represents a read error."""
55
+
56
+
57
+ class WriteError(NetworkError):
58
+ """Represents a write error."""
59
+
60
+
61
+ class CloseError(NetworkError):
62
+ """Represents an error when closing a connection."""
63
+
64
+
65
+ class ProtocolError(TransportError):
66
+ """Represents a protocol-related error."""
67
+
68
+
69
+ class LocalProtocolError(ProtocolError):
70
+ """Represents a local protocol error."""
71
+
72
+
73
+ class RemoteProtocolError(ProtocolError):
74
+ """Represents a remote protocol error."""
75
+
76
+
77
+ class ProxyError(TransportError):
78
+ """Represents a proxy-related error."""
79
+
80
+
81
+ class UnsupportedProtocol(TransportError):
82
+ """Represents an unsupported protocol error."""
83
+
84
+
85
+ class DecodingError(RequestError):
86
+ """Represents an error during response decoding."""
87
+
88
+
89
+ class TooManyRedirects(RequestError):
90
+ """Represents an error due to excessive redirects."""
91
+
92
+
93
+ class HTTPStatusError(HTTPError):
94
+ """Represents an error related to HTTP status codes."""
95
+
96
+
97
+ class InvalidURL(Exception):
98
+ """Represents an error due to an invalid URL."""
99
+
100
+
101
+ class CookieConflict(Exception):
102
+ """Represents a cookie conflict error."""
103
+
104
+
105
+ class StreamError(Exception):
106
+ """Represents a stream-related error."""
107
+
108
+
109
+ class StreamConsumed(StreamError):
110
+ """Represents an error when a stream is already consumed."""
111
+
112
+
113
+ class ResponseNotRead(StreamError):
114
+ """Represents an error when a response is not read."""
115
+
116
+
117
+ class RequestNotRead(StreamError):
118
+ """Represents an error when a request is not read."""
119
+
120
+
121
+ class StreamClosed(StreamError):
122
+ """Represents an error when a stream is closed."""
123
+
124
+ class Response:
125
+ """Response object returned by impit clients (:class:`Client` or :class:`AsyncClient` instances).
126
+
127
+ When constructed manually (e.g. for testing purposes), the following parameters can be provided:
128
+
129
+ Args:
130
+ status_code: HTTP status code of the response (e.g., 200, 404)
131
+ content: Response body as bytes (or None for empty body)
132
+ headers: Response headers as a dictionary (or None for empty headers)
133
+ default_encoding: Default encoding for the response text. Used only if `content-type` header is not present or does not specify a charset.
134
+ url: Final URL of the response.
135
+ """
136
+
137
+ status_code: int
138
+ """HTTP status code of the response (e.g., 200, 404).
139
+
140
+ .. tip::
141
+
142
+ If the status code indicates an error (4xx or 5xx), you can raise an `HTTPStatusError` exception using the :meth:`raise_for_status` method.
143
+
144
+ .. code-block:: python
145
+
146
+ response = await client.get("https://crawlee.dev")
147
+ print(response.status_code) # 200
148
+ """
149
+
150
+ reason_phrase: str
151
+ """HTTP reason phrase for the response (e.g., 'OK', 'Not Found'). This maps the numerical :attr:`status_code` to a human-readable string.
152
+
153
+ .. code-block:: python
154
+
155
+ response = await client.get("https://crawlee.dev")
156
+ print(response.reason_phrase) # 'OK'
157
+ """
158
+
159
+ http_version: str
160
+ """HTTP version (e.g., 'HTTP/1.1', 'HTTP/2') negotiated for the response during the TLS handshake.
161
+
162
+ .. code-block:: python
163
+
164
+ response = await client.get("https://crawlee.dev")
165
+ print(response.http_version) # 'HTTP/2'
166
+ """
167
+
168
+ headers: dict[str, str]
169
+ """Response headers as a Python dictionary.
170
+
171
+ .. code-block:: python
172
+
173
+ response = await client.get("https://crawlee.dev")
174
+ print(response.headers) # {'content-type': 'text/html; charset=utf-8', ... }
175
+ """
176
+
177
+ text: str
178
+ """Response body as text. Decoded from :attr:`content` using :attr:`encoding`.
179
+
180
+ .. code-block:: python
181
+
182
+ response = await client.get("https://crawlee.dev")
183
+ print(response.text) # '<!DOCTYPE html>...'
184
+ """
185
+
186
+ encoding: str
187
+ """Response content encoding. Determined from `content-type` header or by bytestream prescan. Falls back to 'utf-8' if not found.
188
+
189
+ .. code-block:: python
190
+
191
+ response = await client.get("https://crawlee.dev")
192
+ print(response.encoding) # 'utf-8'
193
+
194
+ This can be used to decode the `Response` body manually. By default, :attr:`text` uses this encoding to decode :attr:`content`.
195
+ """
196
+
197
+ is_redirect: bool
198
+ """`True` if the response is a redirect (has a 3xx status code), `False` otherwise.
199
+
200
+ .. code-block:: python
201
+
202
+ response = await client.get("https://crawlee.dev")
203
+ print(response.is_redirect) # False
204
+ """
205
+
206
+ url: str
207
+ """The final URL of the response. This may differ from the requested URL if redirects were followed (see the `follow_redirects` parameter in :class:`Client` and :class:`AsyncClient`).
208
+
209
+ .. code-block:: python
210
+
211
+ response = await client.get("https://crawlee.dev")
212
+ print(response.url) # 'https://crawlee.dev'
213
+ """
214
+
215
+ content: bytes
216
+ """Contains the response body as bytes. If the response was created with `stream=True`, this will be empty until the content is read using :meth:`read` or :meth:`iter_bytes`.
217
+
218
+ .. code-block:: python
219
+
220
+ response = await client.get("https://crawlee.dev")
221
+ print(response.content) # b'<!DOCTYPE html>...'
222
+ """
223
+
224
+ is_closed: bool
225
+ """
226
+ True if the response has been closed using the :meth:`close` method, `False` otherwise.
227
+
228
+ Closing a response releases any underlying resources (e.g., network connections).
229
+
230
+ .. code-block:: python
231
+
232
+ response = await client.get("https://crawlee.dev")
233
+ print(response.is_closed) # False
234
+ response.close()
235
+ print(response.is_closed) # True
236
+ """
237
+
238
+ is_stream_consumed: bool
239
+ """Whether the response stream has been consumed or closed.
240
+
241
+ If this is `True`, calling :meth:`read` or :meth:`iter_bytes` will raise a :class:`StreamConsumed` or :class:`StreamClosed` error.
242
+
243
+ The read response body is still available in the :attr:`content` attribute.
244
+
245
+ .. code-block:: python
246
+
247
+ response = await client.get("https://crawlee.dev", stream=True)
248
+ print(response.is_stream_consumed) # False
249
+ for chunk in response.iter_bytes():
250
+ pass
251
+ print(response.is_stream_consumed) # True
252
+ # calling response.read() or response.iter_bytes() again will raise StreamConsumed error
253
+ # read the content of the response using response.content
254
+ """
255
+
256
+ def __init__(
257
+ self,
258
+ status_code: int,
259
+ *,
260
+ content: bytes | None = None,
261
+ headers: dict[str, str] | None = None,
262
+ default_encoding: str | None = None,
263
+ url: str | None = None,
264
+ ) -> None:
265
+ """Initialize a Response object.
266
+
267
+ Args:
268
+ status_code: HTTP status code
269
+ content: Response body as bytes
270
+ headers: Response headers as a dictionary
271
+ default_encoding: Default encoding for the response text. Used only if `content-type` header is not present or does not specify a charset.
272
+ url: Final URL of the response
273
+ """
274
+
275
+ def read(self) -> bytes:
276
+ """Read the response content as bytes. Synchronous version of :meth:`aread`.
277
+
278
+ Useful for consuming the entire response body in one go (not chunked).
279
+
280
+ .. code-block:: python
281
+
282
+ with Client() as client:
283
+ with client.stream("GET", "https://example.com/largefile") as response:
284
+ content = response.read()
285
+ process(content) # Process the entire content at once
286
+ """
287
+ def iter_bytes(self) -> Iterator[bytes]:
288
+ """Iterate over the response content in chunks. Synchronous version of :meth:`aiter_bytes`.
289
+
290
+ Useful for streaming large responses without loading the entire content into memory.
291
+ .. code-block:: python
292
+
293
+ with Client() as client:
294
+ with client.stream("GET", "https://example.com/largefile") as response:
295
+ for chunk in response.iter_bytes():
296
+ process(chunk) # Process each chunk as it is received
297
+ """
298
+
299
+ async def aread(self) -> bytes:
300
+ """Asynchronously read the response content as bytes. Asynchronous version of :meth:`read`.
301
+
302
+ Useful for consuming the entire response body in one go (not chunked).
303
+
304
+ .. code-block:: python
305
+
306
+ async with AsyncClient() as client:
307
+ async with client.stream("GET", "https://example.com/largefile") as response:
308
+ content = await response.aread()
309
+ process(content) # Process the entire content at once
310
+ """
311
+
312
+ def aiter_bytes(self) -> AsyncIterator[bytes]:
313
+ """Asynchronously iterate over the response content in chunks. Asynchronous version of :meth:`iter_bytes`.
314
+
315
+ Useful for streaming large responses without loading the entire content into memory.
316
+
317
+ .. code-block:: python
318
+
319
+ async with AsyncClient() as client:
320
+ async with client.stream("GET", "https://example.com/largefile") as response:
321
+ async for chunk in response.aiter_bytes():
322
+ process(chunk) # Process each chunk as it is received
323
+ """
324
+
325
+ def json(self) -> Any:
326
+ """Parse the response content as JSON.
327
+
328
+ .. note::
329
+ This method will raise a `DecodingError` if the response content is not valid JSON.
330
+
331
+ .. code-block:: python
332
+
333
+ response = await client.get("https://api.example.com/data")
334
+ data = response.json()
335
+ print(data) # Parsed JSON data as a Python object (dict, list, etc.)
336
+ """
337
+
338
+ def close(self) -> None:
339
+ """Close the response and release resources.
340
+
341
+ .. warning::
342
+ You should not need to call this method directly.
343
+
344
+ Use the `with` statement to ensure proper resource management when working with synchronous clients.
345
+
346
+ .. code-block:: python
347
+
348
+ with impit.stream('GET', get_httpbin_url('/')) as response:
349
+ assert response.status_code == 200
350
+
351
+ assert response.is_closed is True
352
+ """
353
+
354
+ async def aclose(self) -> None:
355
+ """Asynchronously close the response and release resources.
356
+
357
+ .. note::
358
+ This method is for internal use only.
359
+
360
+ Use the `async with` statement to ensure proper resource management when working with asynchronous clients.
361
+
362
+ .. code-block:: python
363
+
364
+ async with impit.stream('GET', get_httpbin_url('/')) as response:
365
+ assert response.status_code == 200
366
+
367
+ assert response.is_closed is True
368
+ """
369
+
370
+ class Client:
371
+ """Synchronous HTTP client with browser impersonation capabilities.
372
+
373
+ .. note::
374
+ You can reuse the :class:`Client` instance to make multiple requests.
375
+
376
+ All requests made by the same client will share the same configuration, resources (e.g., cookie jar and connection pool), and other settings.
377
+
378
+ Args:
379
+ browser: Browser to impersonate (`"chrome"` or `"firefox"`).
380
+
381
+ If this is `None` (default), no impersonation is performed.
382
+ http3:
383
+
384
+ If set to `True`, Impit will try to connect to the target servers using HTTP/3 protocol (if supported by the server).
385
+
386
+ .. note::
387
+ The HTTP/3 support is experimental and may not work with all servers. The impersonation capabilities are limited when using HTTP/3.
388
+
389
+ proxy:
390
+
391
+ The proxy URL to use for all the requests made by this client.
392
+
393
+ This can be an HTTP, HTTPS, or SOCKS proxy.
394
+ timeout:
395
+ Default request timeout in seconds.
396
+
397
+ This value can be overridden for individual requests.
398
+ verify:
399
+ If set to `False`, impit will not verify SSL certificates.
400
+
401
+ This can be used to ignore TLS errors (e.g., self-signed certificates).
402
+
403
+ True by default.
404
+ default_encoding:
405
+ Default encoding for response.text field (e.g., "utf-8", "cp1252").
406
+
407
+ Overrides `content-type` headers and bytestream prescan.
408
+ follow_redirects:
409
+
410
+ If set to `True` the client will automatically follow HTTP redirects (3xx responses).
411
+
412
+ `False` by default.
413
+ max_redirects:
414
+
415
+ Maximum number of redirects to follow if the `follow_redirects` option is enabled.
416
+
417
+ Default is 20.
418
+ cookie_jar:
419
+
420
+ Cookie jar to store cookies in.
421
+
422
+ This is a `http.cookiejar.CookieJar` instance.
423
+
424
+ By default, :class:`Client` doesn't store cookies between requests.
425
+ cookies: httpx-compatible cookies object.
426
+
427
+ These are the cookies to include in all requests (to the matching servers) made by this client.
428
+ headers: Default HTTP headers to include in requests.
429
+
430
+ These headers will be included in all requests made by this client.
431
+
432
+ Default is an empty dictionary.
433
+ local_address:
434
+
435
+ Local address to bind the client to.
436
+
437
+ Useful for testing purposes or when you want to bind the client to a specific network interface.
438
+ Can be an IP address in the format `xxx.xxx.xxx.xxx` (for IPv4) or `ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff` (for IPv6).
439
+ """
440
+
441
+ def __enter__(self) -> Client:
442
+ """Enter the runtime context related to this object."""
443
+
444
+ def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: object | None) -> None:
445
+ """Exit the runtime context related to this object."""
446
+
447
+
448
+ def __init__(
449
+ self,
450
+ browser: Browser | None = None,
451
+ http3: bool | None = None,
452
+ proxy: str | None = None,
453
+ timeout: float | None = None,
454
+ verify: bool | None = None,
455
+ default_encoding: str | None = None,
456
+ follow_redirects: bool | None = None,
457
+ max_redirects: int | None = None,
458
+ cookie_jar: CookieJar | None = None,
459
+ cookies: Cookies | None = None,
460
+ headers: dict[str, str] | None = None,
461
+ local_address: str | None = None,
462
+ ) -> None:
463
+ """Initialize a synchronous HTTP client.
464
+
465
+ Args:
466
+ browser: Browser to impersonate ("chrome" or "firefox")
467
+ http3: Enable HTTP/3 support
468
+ proxy: Proxy URL to use
469
+ timeout: Default request timeout in seconds
470
+ verify: Verify SSL certificates (set to False to ignore TLS errors)
471
+ default_encoding: Default encoding for response.text field (e.g., "utf-8", "cp1252"). Overrides `content-type`
472
+ header and bytestream prescan.
473
+ follow_redirects: Whether to follow redirects (default: False)
474
+ max_redirects: Maximum number of redirects to follow (default: 20)
475
+ cookie_jar: Cookie jar to store cookies in.
476
+ cookies: httpx-compatible cookies object.
477
+ headers: Default HTTP headers to include in requests.
478
+ local_address: Local address to bind the client to. Useful for testing purposes or when you want to bind the client to a specific network interface.
479
+ Can be an IP address in the format "xxx.xxx.xxx.xxx" (for IPv4) or "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" (for IPv6).
480
+ """
481
+
482
+ def get(
483
+ self,
484
+ url: str,
485
+ content: bytes | bytearray | list[int] | None = None,
486
+ data: dict[str, str] | None = None,
487
+ headers: dict[str, str] | None = None,
488
+ timeout: float | None = None,
489
+ force_http3: bool | None = None,
490
+ ) -> Response:
491
+ """Make a GET request.
492
+
493
+ Args:
494
+ url: URL to request
495
+ content: Raw content to send
496
+ data: Form data to send in request body
497
+ headers: HTTP headers
498
+ timeout: Request timeout in seconds (overrides default timeout)
499
+ force_http3: Force HTTP/3 protocol
500
+ """
501
+
502
+ def post(
503
+ self,
504
+ url: str,
505
+ content: bytes | bytearray | list[int] | None = None,
506
+ data: dict[str, str] | None = None,
507
+ headers: dict[str, str] | None = None,
508
+ timeout: float | None = None,
509
+ force_http3: bool | None = None,
510
+ ) -> Response:
511
+ """Make a POST request.
512
+
513
+ Args:
514
+ url: URL to request
515
+ content: Raw content to send
516
+ data: Form data to send in request body
517
+ headers: HTTP headers
518
+ timeout: Request timeout in seconds (overrides default timeout)
519
+ force_http3: Force HTTP/3 protocol
520
+
521
+ """
522
+
523
+ def put(
524
+ self,
525
+ url: str,
526
+ content: bytes | bytearray | list[int] | None = None,
527
+ data: dict[str, str] | None = None,
528
+ headers: dict[str, str] | None = None,
529
+ timeout: float | None = None,
530
+ force_http3: bool | None = None,
531
+ ) -> Response:
532
+ """Make a PUT request.
533
+
534
+ Args:
535
+ url: URL to request
536
+ content: Raw content to send
537
+ data: Form data to send in request body
538
+ headers: HTTP headers
539
+ timeout: Request timeout in seconds (overrides default timeout)
540
+ force_http3: Force HTTP/3 protocol
541
+ """
542
+
543
+ def patch(
544
+ self,
545
+ url: str,
546
+ content: bytes | bytearray | list[int] | None = None,
547
+ data: dict[str, str] | None = None,
548
+ headers: dict[str, str] | None = None,
549
+ timeout: float | None = None,
550
+ force_http3: bool | None = None,
551
+ ) -> Response:
552
+ """Make a PATCH request.
553
+
554
+ Args:
555
+ url: URL to request
556
+ content: Raw content to send
557
+ data: Form data to send in request body
558
+ headers: HTTP headers
559
+ timeout: Request timeout in seconds (overrides default timeout)
560
+ force_http3: Force HTTP/3 protocol
561
+ """
562
+
563
+ def delete(
564
+ self,
565
+ url: str,
566
+ content: bytes | bytearray | list[int] | None = None,
567
+ data: dict[str, str] | None = None,
568
+ headers: dict[str, str] | None = None,
569
+ timeout: float | None = None,
570
+ force_http3: bool | None = None,
571
+ ) -> Response:
572
+ """Make a DELETE request.
573
+
574
+ Args:
575
+ url: URL to request
576
+ content: Raw content to send
577
+ data: Form data to send in request body
578
+ headers: HTTP headers
579
+ timeout: Request timeout in seconds (overrides default timeout)
580
+ force_http3: Force HTTP/3 protocol
581
+ """
582
+
583
+ def head(
584
+ self,
585
+ url: str,
586
+ content: bytes | bytearray | list[int] | None = None,
587
+ data: dict[str, str] | None = None,
588
+ headers: dict[str, str] | None = None,
589
+ timeout: float | None = None,
590
+ force_http3: bool | None = None,
591
+ ) -> Response:
592
+ """Make a HEAD request.
593
+
594
+ Args:
595
+ url: URL to request
596
+ content: Raw content to send
597
+ data: Form data to send in request body
598
+ headers: HTTP headers
599
+ timeout: Request timeout in seconds (overrides default timeout)
600
+ force_http3: Force HTTP/3 protocol
601
+ """
602
+
603
+ def options(
604
+ self,
605
+ url: str,
606
+ content: bytes | bytearray | list[int] | None = None,
607
+ data: dict[str, str] | None = None,
608
+ headers: dict[str, str] | None = None,
609
+ timeout: float | None = None,
610
+ force_http3: bool | None = None,
611
+ ) -> Response:
612
+ """Make an OPTIONS request.
613
+
614
+ Args:
615
+ url: URL to request
616
+ content: Raw content to send
617
+ data: Form data to send in request body
618
+ headers: HTTP headers
619
+ timeout: Request timeout in seconds (overrides default timeout)
620
+ force_http3: Force HTTP/3 protocol
621
+ """
622
+
623
+ def trace(
624
+ self,
625
+ url: str,
626
+ content: bytes | bytearray | list[int] | None = None,
627
+ data: dict[str, str] | None = None,
628
+ headers: dict[str, str] | None = None,
629
+ timeout: float | None = None,
630
+ force_http3: bool | None = None,
631
+ ) -> Response:
632
+ """Make a TRACE request.
633
+
634
+ Args:
635
+ url: URL to request
636
+ content: Raw content to send
637
+ data: Form data to send in request body
638
+ headers: HTTP headers
639
+ timeout: Request timeout in seconds (overrides default timeout)
640
+ force_http3: Force HTTP/3 protocol
641
+ """
642
+
643
+ def request(
644
+ self,
645
+ method: str,
646
+ url: str,
647
+ content: bytes | bytearray | list[int] | None = None,
648
+ data: dict[str, str] | None = None,
649
+ headers: dict[str, str] | None = None,
650
+ timeout: float | None = None,
651
+ force_http3: bool | None = None,
652
+ stream: bool = False,
653
+ ) -> Response:
654
+ """Make an HTTP request with the specified method.
655
+
656
+ Args:
657
+ method: HTTP method (e.g., "get", "post")
658
+ url: URL to request
659
+ content: Raw content to send
660
+ data: Form data to send in request body
661
+ headers: HTTP headers
662
+ timeout: Request timeout in seconds (overrides default timeout)
663
+ force_http3: Force HTTP/3 protocol
664
+ stream: Whether to return a streaming response (default: False)
665
+ """
666
+
667
+ def stream(
668
+ self,
669
+ method: str,
670
+ url: str,
671
+ content: bytes | bytearray | list[int] | None = None,
672
+ data: dict[str, str] | None = None,
673
+ headers: dict[str, str] | None = None,
674
+ timeout: float | None = None,
675
+ force_http3: bool | None = None,
676
+ ) -> AbstractContextManager[Response]:
677
+ """Make a streaming request with the specified method.
678
+
679
+ This method returns a context manager that yields a streaming :class:`Response` object.
680
+
681
+ See the following example for usage:
682
+
683
+ .. code-block:: python
684
+
685
+ with Client() as client:
686
+ with client.stream("GET", "https://example.com/largefile") as response:
687
+ for chunk in response.iter_bytes():
688
+ process(chunk) # Process each chunk as it is received
689
+
690
+ Args:
691
+ method: HTTP method (e.g., "get", "post")
692
+ url: URL to request
693
+ content: Raw content to send
694
+ data: Form data to send in request body
695
+ headers: HTTP headers
696
+ timeout: Request timeout in seconds (overrides default timeout)
697
+ force_http3: Force HTTP/3 protocol
698
+ """
699
+
700
+
701
+ class AsyncClient:
702
+ """Asynchronous HTTP client with browser impersonation capabilities.
703
+
704
+ .. note::
705
+ You can reuse the :class:`Client` instance to make multiple requests.
706
+
707
+ All requests made by the same client will share the same configuration, resources (e.g., cookie jar and connection pool), and other settings.
708
+
709
+ Args:
710
+ browser: Browser to impersonate (`"chrome"` or `"firefox"`).
711
+
712
+ If this is `None` (default), no impersonation is performed.
713
+ http3:
714
+
715
+ If set to `True`, Impit will try to connect to the target servers using HTTP/3 protocol (if supported by the server).
716
+
717
+ .. note::
718
+ The HTTP/3 support is experimental and may not work with all servers. The impersonation capabilities are limited when using HTTP/3.
719
+
720
+ proxy:
721
+
722
+ The proxy URL to use for all the requests made by this client.
723
+
724
+ This can be an HTTP, HTTPS, or SOCKS proxy.
725
+ timeout:
726
+ Default request timeout in seconds.
727
+
728
+ This value can be overridden for individual requests.
729
+ verify:
730
+ If set to `False`, impit will not verify SSL certificates.
731
+
732
+ This can be used to ignore TLS errors (e.g., self-signed certificates).
733
+
734
+ True by default.
735
+ default_encoding:
736
+ Default encoding for response.text field (e.g., "utf-8", "cp1252").
737
+
738
+ Overrides `content-type` headers and bytestream prescan.
739
+ follow_redirects:
740
+
741
+ If set to `True` the client will automatically follow HTTP redirects (3xx responses).
742
+
743
+ `False` by default.
744
+ max_redirects:
745
+
746
+ Maximum number of redirects to follow if the `follow_redirects` option is enabled.
747
+
748
+ Default is 20.
749
+ cookie_jar:
750
+
751
+ Cookie jar to store cookies in.
752
+
753
+ This is a `http.cookiejar.CookieJar` instance.
754
+
755
+ By default, :class:`Client` doesn't store cookies between requests.
756
+ cookies: httpx-compatible cookies object.
757
+
758
+ These are the cookies to include in all requests (to the matching servers) made by this client.
759
+ headers: Default HTTP headers to include in requests.
760
+
761
+ These headers will be included in all requests made by this client.
762
+
763
+ Default is an empty dictionary.
764
+ local_address:
765
+
766
+ Local address to bind the client to.
767
+
768
+ Useful for testing purposes or when you want to bind the client to a specific network interface.
769
+ Can be an IP address in the format `xxx.xxx.xxx.xxx` (for IPv4) or `ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff` (for IPv6).
770
+ """
771
+
772
+ async def __aenter__(self) -> AsyncClient:
773
+ """Enter the runtime context related to this object."""
774
+
775
+ async def __aexit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: object | None) -> None:
776
+ """Exit the runtime context related to this object."""
777
+
778
+ def __init__(
779
+ self,
780
+ browser: Browser | None = None,
781
+ http3: bool | None = None,
782
+ proxy: str | None = None,
783
+ timeout: float | None = None,
784
+ verify: bool | None = None,
785
+ default_encoding: str | None = None,
786
+ follow_redirects: bool | None = None,
787
+ max_redirects: int | None = None,
788
+ cookie_jar: CookieJar | None = None,
789
+ cookies: Cookies | None = None,
790
+ headers: dict[str, str] | None = None,
791
+ local_address: str | None = None,
792
+ ) -> None:
793
+ """Initialize an asynchronous HTTP client.
794
+
795
+ Args:
796
+ browser: Browser to impersonate ("chrome" or "firefox")
797
+ http3: Enable HTTP/3 support
798
+ proxy: Proxy URL to use
799
+ timeout: Default request timeout in seconds
800
+ verify: Verify SSL certificates (set to False to ignore TLS errors)
801
+ default_encoding: Default encoding for response.text field (e.g., "utf-8", "cp1252"). Overrides `content-type`
802
+ header and bytestream prescan.
803
+ follow_redirects: Whether to follow redirects (default: False)
804
+ max_redirects: Maximum number of redirects to follow (default: 20)
805
+ cookie_jar: Cookie jar to store cookies in.
806
+ cookies: httpx-compatible cookies object.
807
+ headers: Default HTTP headers to include in requests.
808
+ local_address: Local address to bind the client to. Useful for testing purposes or when you want to bind the client to a specific network interface.
809
+ Can be an IP address in the format "xxx.xxx.xxx.xxx" (for IPv4) or "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" (for IPv6).
810
+ """
811
+
812
+ async def get(
813
+ self,
814
+ url: str,
815
+ content: bytes | bytearray | list[int] | None = None,
816
+ data: dict[str, str] | None = None,
817
+ headers: dict[str, str] | None = None,
818
+ timeout: float | None = None,
819
+ force_http3: bool | None = None,
820
+ ) -> Response:
821
+ """Make an asynchronous GET request.
822
+
823
+ Args:
824
+ url: URL to request
825
+ content: Raw content to send
826
+ data: Form data to send in request body
827
+ headers: HTTP headers
828
+ timeout: Request timeout in seconds (overrides default timeout)
829
+ force_http3: Force HTTP/3 protocol
830
+ """
831
+
832
+ async def post(
833
+ self,
834
+ url: str,
835
+ content: bytes | bytearray | list[int] | None = None,
836
+ data: dict[str, str] | None = None,
837
+ headers: dict[str, str] | None = None,
838
+ timeout: float | None = None,
839
+ force_http3: bool | None = None,
840
+ ) -> Response:
841
+ """Make an asynchronous POST request.
842
+
843
+ Args:
844
+ url: URL to request
845
+ content: Raw content to send
846
+ data: Form data to send in request body
847
+ headers: HTTP headers
848
+ timeout: Request timeout in seconds (overrides default timeout)
849
+ force_http3: Force HTTP/3 protocol
850
+
851
+ """
852
+
853
+ async def put(
854
+ self,
855
+ url: str,
856
+ content: bytes | bytearray | list[int] | None = None,
857
+ data: dict[str, str] | None = None,
858
+ headers: dict[str, str] | None = None,
859
+ timeout: float | None = None,
860
+ force_http3: bool | None = None,
861
+ ) -> Response:
862
+ """Make an asynchronous PUT request.
863
+
864
+ Args:
865
+ url: URL to request
866
+ content: Raw content to send
867
+ data: Form data to send in request body
868
+ headers: HTTP headers
869
+ timeout: Request timeout in seconds (overrides default timeout)
870
+ force_http3: Force HTTP/3 protocol
871
+ """
872
+
873
+ async def patch(
874
+ self,
875
+ url: str,
876
+ content: bytes | bytearray | list[int] | None = None,
877
+ data: dict[str, str] | None = None,
878
+ headers: dict[str, str] | None = None,
879
+ timeout: float | None = None,
880
+ force_http3: bool | None = None,
881
+ ) -> Response:
882
+ """Make an asynchronous PATCH request.
883
+
884
+ Args:
885
+ url: URL to request
886
+ content: Raw content to send
887
+ data: Form data to send in request body
888
+ headers: HTTP headers
889
+ timeout: Request timeout in seconds (overrides default timeout)
890
+ force_http3: Force HTTP/3 protocol
891
+ """
892
+
893
+ async def delete(
894
+ self,
895
+ url: str,
896
+ content: bytes | bytearray | list[int] | None = None,
897
+ data: dict[str, str] | None = None,
898
+ headers: dict[str, str] | None = None,
899
+ timeout: float | None = None,
900
+ force_http3: bool | None = None,
901
+ ) -> Response:
902
+ """Make an asynchronous DELETE request.
903
+
904
+ Args:
905
+ url: URL to request
906
+ content: Raw content to send
907
+ data: Form data to send in request body
908
+ headers: HTTP headers
909
+ timeout: Request timeout in seconds (overrides default timeout)
910
+ force_http3: Force HTTP/3 protocol
911
+ """
912
+
913
+ async def head(
914
+ self,
915
+ url: str,
916
+ content: bytes | bytearray | list[int] | None = None,
917
+ data: dict[str, str] | None = None,
918
+ headers: dict[str, str] | None = None,
919
+ timeout: float | None = None,
920
+ force_http3: bool | None = None,
921
+ ) -> Response:
922
+ """Make an asynchronous HEAD request.
923
+
924
+ Args:
925
+ url: URL to request
926
+ content: Raw content to send
927
+ data: Form data to send in request body
928
+ headers: HTTP headers
929
+ timeout: Request timeout in seconds (overrides default timeout)
930
+ force_http3: Force HTTP/3 protocol
931
+ """
932
+
933
+ async def options(
934
+ self,
935
+ url: str,
936
+ content: bytes | bytearray | list[int] | None = None,
937
+ data: dict[str, str] | None = None,
938
+ headers: dict[str, str] | None = None,
939
+ timeout: float | None = None,
940
+ force_http3: bool | None = None,
941
+ ) -> Response:
942
+ """Make an asynchronous OPTIONS request.
943
+
944
+ Args:
945
+ url: URL to request
946
+ content: Raw content to send
947
+ data: Form data to send in request body
948
+ headers: HTTP headers
949
+ timeout: Request timeout in seconds (overrides default timeout)
950
+ force_http3: Force HTTP/3 protocol
951
+ """
952
+
953
+ async def trace(
954
+ self,
955
+ url: str,
956
+ content: bytes | bytearray | list[int] | None = None,
957
+ data: dict[str, str] | None = None,
958
+ headers: dict[str, str] | None = None,
959
+ timeout: float | None = None,
960
+ force_http3: bool | None = None,
961
+ ) -> Response:
962
+ """Make an asynchronous TRACE request.
963
+
964
+ Args:
965
+ url: URL to request
966
+ content: Raw content to send
967
+ data: Form data to send in request body
968
+ headers: HTTP headers
969
+ timeout: Request timeout in seconds (overrides default timeout)
970
+ force_http3: Force HTTP/3 protocol
971
+ """
972
+
973
+ async def request(
974
+ self,
975
+ method: str,
976
+ url: str,
977
+ content: bytes | bytearray | list[int] | None = None,
978
+ data: dict[str, str] | None = None,
979
+ headers: dict[str, str] | None = None,
980
+ timeout: float | None = None,
981
+ force_http3: bool | None = None,
982
+ stream: bool = False,
983
+ ) -> Response:
984
+ """Make an asynchronous HTTP request with the specified method.
985
+
986
+ Args:
987
+ method: HTTP method (e.g., "get", "post")
988
+ url: URL to request
989
+ content: Raw content to send
990
+ data: Form data to send in request body
991
+ headers: HTTP headers
992
+ timeout: Request timeout in seconds (overrides default timeout)
993
+ force_http3: Force HTTP/3 protocol
994
+ stream: Whether to return a streaming response (default: False)
995
+ """
996
+
997
+ def stream(
998
+ self,
999
+ method: str,
1000
+ url: str,
1001
+ content: bytes | bytearray | list[int] | None = None,
1002
+ data: dict[str, str] | None = None,
1003
+ headers: dict[str, str] | None = None,
1004
+ timeout: float | None = None,
1005
+ force_http3: bool | None = None,
1006
+ ) -> AbstractAsyncContextManager[Response]:
1007
+ """Make an asynchronous streaming request with the specified method.
1008
+
1009
+ This method returns a AsyncContextManager that yields a streaming :class:`Response` object.
1010
+
1011
+ See the following example for usage:
1012
+
1013
+ .. code-block:: python
1014
+
1015
+ with Client() as client:
1016
+ with client.stream("GET", "https://example.com/largefile") as response:
1017
+ for chunk in response.iter_bytes():
1018
+ process(chunk) # Process each chunk as it is received
1019
+
1020
+ Args:
1021
+ method: HTTP method (e.g., "get", "post")
1022
+ url: URL to request
1023
+ content: Raw content to send
1024
+ data: Form data to send in request body
1025
+ headers: HTTP headers
1026
+ timeout: Request timeout in seconds (overrides default timeout)
1027
+ force_http3: Force HTTP/3 protocol
1028
+ """
1029
+
1030
+
1031
+ def stream(
1032
+ method: str,
1033
+ url: str,
1034
+ content: bytes | bytearray | list[int] | None = None,
1035
+ data: dict[str, str] | None = None,
1036
+ headers: dict[str, str] | None = None,
1037
+ timeout: float | None = None,
1038
+ force_http3: bool | None = None,
1039
+ follow_redirects: bool | None = None,
1040
+ max_redirects: int | None = None,
1041
+ cookie_jar: CookieJar | None = None,
1042
+ cookies: Cookies | None = None,
1043
+ proxy: str | None = None,
1044
+ ) -> AbstractContextManager[Response]:
1045
+ """Make a streaming request without creating a client instance.
1046
+
1047
+ Args:
1048
+ method: HTTP method (e.g., "get", "post")
1049
+ url: URL to request
1050
+ content: Raw content to send
1051
+ data: Form data to send in request body
1052
+ headers: HTTP headers
1053
+ timeout: Request timeout in seconds
1054
+ force_http3: Force HTTP/3 protocol
1055
+ follow_redirects: Whether to follow redirects (default: False)
1056
+ max_redirects: Maximum number of redirects to follow (default: 20)
1057
+ cookie_jar: Cookie jar to store cookies in.
1058
+ cookies: httpx-compatible cookies object.
1059
+ proxy: Proxy URL to use to make the request.
1060
+
1061
+ Returns:
1062
+ Response object
1063
+ """
1064
+
1065
+ def get(
1066
+ url: str,
1067
+ content: bytes | bytearray | list[int] | None = None,
1068
+ data: dict[str, str] | None = None,
1069
+ headers: dict[str, str] | None = None,
1070
+ timeout: float | None = None,
1071
+ force_http3: bool | None = None,
1072
+ follow_redirects: bool | None = None,
1073
+ max_redirects: int | None = None,
1074
+ cookie_jar: CookieJar | None = None,
1075
+ cookies: Cookies | None = None,
1076
+ proxy: str | None = None,
1077
+ ) -> Response:
1078
+ """Make a GET request without creating a client instance.
1079
+
1080
+ Args:
1081
+ url: URL to request
1082
+ content: Raw content to send
1083
+ data: Form data to send in request body
1084
+ headers: HTTP headers
1085
+ timeout: Request timeout in seconds
1086
+ force_http3: Force HTTP/3 protocol
1087
+ follow_redirects: Whether to follow redirects (default: False)
1088
+ max_redirects: Maximum number of redirects to follow (default: 20)
1089
+ cookie_jar: Cookie jar to store cookies in.
1090
+ cookies: httpx-compatible cookies object.
1091
+ proxy: Proxy URL to use to make the request.
1092
+
1093
+ Returns:
1094
+ Response object
1095
+ """
1096
+
1097
+
1098
+ def post(
1099
+ url: str,
1100
+ content: bytes | bytearray | list[int] | None = None,
1101
+ data: dict[str, str] | None = None,
1102
+ headers: dict[str, str] | None = None,
1103
+ timeout: float | None = None,
1104
+ force_http3: bool | None = None,
1105
+ follow_redirects: bool | None = None,
1106
+ max_redirects: int | None = None,
1107
+ cookie_jar: CookieJar | None = None,
1108
+ cookies: Cookies | None = None,
1109
+ proxy: str | None = None,
1110
+ ) -> Response:
1111
+ """Make a POST request without creating a client instance.
1112
+
1113
+ Args:
1114
+ url: URL to request
1115
+ content: Raw content to send
1116
+ data: Form data to send in request body
1117
+ headers: HTTP headers
1118
+ timeout: Request timeout in seconds
1119
+ force_http3: Force HTTP/3 protocol
1120
+ follow_redirects: Whether to follow redirects (default: False)
1121
+ max_redirects: Maximum number of redirects to follow (default: 20)
1122
+ cookie_jar: Cookie jar to store cookies in.
1123
+ cookies: httpx-compatible cookies object.
1124
+ proxy: Proxy URL to use to make the request.
1125
+
1126
+ Returns:
1127
+ Response object
1128
+ """
1129
+
1130
+
1131
+ def put(
1132
+ url: str,
1133
+ content: bytes | bytearray | list[int] | None = None,
1134
+ data: dict[str, str] | None = None,
1135
+ headers: dict[str, str] | None = None,
1136
+ timeout: float | None = None,
1137
+ force_http3: bool | None = None,
1138
+ follow_redirects: bool | None = None,
1139
+ max_redirects: int | None = None,
1140
+ cookie_jar: CookieJar | None = None,
1141
+ cookies: Cookies | None = None,
1142
+ proxy: str | None = None,
1143
+ ) -> Response:
1144
+ """Make a PUT request without creating a client instance.
1145
+
1146
+ Args:
1147
+ url: URL to request
1148
+ content: Raw content to send
1149
+ data: Form data to send in request body
1150
+ headers: HTTP headers
1151
+ timeout: Request timeout in seconds
1152
+ force_http3: Force HTTP/3 protocol
1153
+ follow_redirects: Whether to follow redirects (default: False)
1154
+ max_redirects: Maximum number of redirects to follow (default: 20)
1155
+ cookie_jar: Cookie jar to store cookies in.
1156
+ cookies: httpx-compatible cookies object.
1157
+ proxy: Proxy URL to use to make the request.
1158
+
1159
+ Returns:
1160
+ Response object
1161
+ """
1162
+
1163
+
1164
+ def patch(
1165
+ url: str,
1166
+ content: bytes | bytearray | list[int] | None = None,
1167
+ data: dict[str, str] | None = None,
1168
+ headers: dict[str, str] | None = None,
1169
+ timeout: float | None = None,
1170
+ force_http3: bool | None = None,
1171
+ follow_redirects: bool | None = None,
1172
+ max_redirects: int | None = None,
1173
+ cookie_jar: CookieJar | None = None,
1174
+ cookies: Cookies | None = None,
1175
+ proxy: str | None = None,
1176
+ ) -> Response:
1177
+ """Make a PATCH request without creating a client instance.
1178
+
1179
+ Args:
1180
+ url: URL to request
1181
+ content: Raw content to send
1182
+ data: Form data to send in request body
1183
+ headers: HTTP headers
1184
+ timeout: Request timeout in seconds
1185
+ force_http3: Force HTTP/3 protocol
1186
+ follow_redirects: Whether to follow redirects (default: False)
1187
+ max_redirects: Maximum number of redirects to follow (default: 20)
1188
+ cookie_jar: Cookie jar to store cookies in.
1189
+ cookies: httpx-compatible cookies object.
1190
+ proxy: Proxy URL to use to make the request.
1191
+
1192
+ Returns:
1193
+ Response object
1194
+ """
1195
+
1196
+
1197
+ def delete(
1198
+ url: str,
1199
+ content: bytes | bytearray | list[int] | None = None,
1200
+ data: dict[str, str] | None = None,
1201
+ headers: dict[str, str] | None = None,
1202
+ timeout: float | None = None,
1203
+ force_http3: bool | None = None,
1204
+ follow_redirects: bool | None = None,
1205
+ max_redirects: int | None = None,
1206
+ cookie_jar: CookieJar | None = None,
1207
+ cookies: Cookies | None = None,
1208
+ proxy: str | None = None,
1209
+ ) -> Response:
1210
+ """Make a DELETE request without creating a client instance.
1211
+
1212
+ Args:
1213
+ url: URL to request
1214
+ content: Raw content to send
1215
+ data: Form data to send in request body
1216
+ headers: HTTP headers
1217
+ timeout: Request timeout in seconds
1218
+ force_http3: Force HTTP/3 protocol
1219
+ follow_redirects: Whether to follow redirects (default: False)
1220
+ max_redirects: Maximum number of redirects to follow (default: 20)
1221
+ cookie_jar: Cookie jar to store cookies in.
1222
+ cookies: httpx-compatible cookies object.
1223
+ proxy: Proxy URL to use to make the request.
1224
+
1225
+ Returns:
1226
+ Response object
1227
+ """
1228
+
1229
+
1230
+ def head(
1231
+ url: str,
1232
+ content: bytes | bytearray | list[int] | None = None,
1233
+ data: dict[str, str] | None = None,
1234
+ headers: dict[str, str] | None = None,
1235
+ timeout: float | None = None,
1236
+ force_http3: bool | None = None,
1237
+ follow_redirects: bool | None = None,
1238
+ max_redirects: int | None = None,
1239
+ cookie_jar: CookieJar | None = None,
1240
+ cookies: Cookies | None = None,
1241
+ proxy: str | None = None,
1242
+ ) -> Response:
1243
+ """Make a HEAD request without creating a client instance.
1244
+
1245
+ Args:
1246
+ url: URL to request
1247
+ content: Raw content to send
1248
+ data: Form data to send in request body
1249
+ headers: HTTP headers
1250
+ timeout: Request timeout in seconds
1251
+ force_http3: Force HTTP/3 protocol
1252
+ follow_redirects: Whether to follow redirects (default: False)
1253
+ max_redirects: Maximum number of redirects to follow (default: 20)
1254
+ cookie_jar: Cookie jar to store cookies in.
1255
+ cookies: httpx-compatible cookies object.
1256
+ proxy: Proxy URL to use to make the request.
1257
+
1258
+ Returns:
1259
+ Response object
1260
+ """
1261
+
1262
+
1263
+ def options(
1264
+ url: str,
1265
+ content: bytes | bytearray | list[int] | None = None,
1266
+ data: dict[str, str] | None = None,
1267
+ headers: dict[str, str] | None = None,
1268
+ timeout: float | None = None,
1269
+ force_http3: bool | None = None,
1270
+ follow_redirects: bool | None = None,
1271
+ max_redirects: int | None = None,
1272
+ cookie_jar: CookieJar | None = None,
1273
+ cookies: Cookies | None = None,
1274
+ proxy: str | None = None,
1275
+ ) -> Response:
1276
+ """Make an OPTIONS request without creating a client instance.
1277
+
1278
+ Args:
1279
+ url: URL to request
1280
+ content: Raw content to send
1281
+ data: Form data to send in request body
1282
+ headers: HTTP headers
1283
+ timeout: Request timeout in seconds (overrides default timeout)
1284
+ force_http3: Force HTTP/3 protocol
1285
+ follow_redirects: Whether to follow redirects (default: False)
1286
+ max_redirects: Maximum number of redirects to follow (default: 20)
1287
+ cookie_jar: Cookie jar to store cookies in.
1288
+ cookies: httpx-compatible cookies object.
1289
+ proxy: Proxy URL to use to make the request.
1290
+ """
1291
+
1292
+
1293
+ def trace(
1294
+ url: str,
1295
+ content: bytes | bytearray | list[int] | None = None,
1296
+ data: dict[str, str] | None = None,
1297
+ headers: dict[str, str] | None = None,
1298
+ timeout: float | None = None,
1299
+ force_http3: bool | None = None,
1300
+ follow_redirects: bool | None = None,
1301
+ max_redirects: int | None = None,
1302
+ cookie_jar: CookieJar | None = None,
1303
+ cookies: Cookies | None = None,
1304
+ proxy: str | None = None,
1305
+ ) -> Response:
1306
+ """Make a TRACE request without creating a client instance.
1307
+
1308
+ Args:
1309
+ url: URL to request
1310
+ content: Raw content to send
1311
+ data: Form data to send in request body
1312
+ headers: HTTP headers
1313
+ timeout: Request timeout in seconds (overrides default timeout)
1314
+ force_http3: Force HTTP/3 protocol
1315
+ follow_redirects: Whether to follow redirects (default: False)
1316
+ max_redirects: Maximum number of redirects to follow (default: 20)
1317
+ cookie_jar: Cookie jar to store cookies in.
1318
+ cookies: httpx-compatible cookies object.
1319
+ proxy: Proxy URL to use to make the request.
1320
+ """