impit 0.5.3__cp312-cp312-musllinux_1_2_aarch64.whl → 0.9.0__cp312-cp312-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.
- impit/__init__.py +5 -0
- impit/impit.cpython-312-aarch64-linux-musl.so +0 -0
- impit/impit.pyi +479 -26
- {impit-0.5.3.dist-info → impit-0.9.0.dist-info}/METADATA +10 -5
- impit-0.9.0.dist-info/RECORD +9 -0
- {impit-0.5.3.dist-info → impit-0.9.0.dist-info}/WHEEL +1 -1
- impit.libs/{libgcc_s-e52197c3.so.1 → libgcc_s-39080030.so.1} +0 -0
- impit-0.5.3.dist-info/RECORD +0 -9
impit/__init__.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from importlib import metadata
|
|
1
2
|
from typing import Literal
|
|
2
3
|
|
|
3
4
|
from .cookies import Cookies
|
|
@@ -40,9 +41,12 @@ from .impit import (
|
|
|
40
41
|
patch,
|
|
41
42
|
post,
|
|
42
43
|
put,
|
|
44
|
+
stream,
|
|
43
45
|
trace,
|
|
44
46
|
)
|
|
45
47
|
|
|
48
|
+
__version__ = metadata.version('impit')
|
|
49
|
+
|
|
46
50
|
__all__ = [
|
|
47
51
|
'AsyncClient',
|
|
48
52
|
'Browser',
|
|
@@ -84,6 +88,7 @@ __all__ = [
|
|
|
84
88
|
'patch',
|
|
85
89
|
'post',
|
|
86
90
|
'put',
|
|
91
|
+
'stream',
|
|
87
92
|
'trace',
|
|
88
93
|
]
|
|
89
94
|
|
|
Binary file
|
impit/impit.pyi
CHANGED
|
@@ -2,7 +2,7 @@ from __future__ import annotations
|
|
|
2
2
|
from http.cookiejar import CookieJar
|
|
3
3
|
from .cookies import Cookies
|
|
4
4
|
|
|
5
|
-
from typing import Literal
|
|
5
|
+
from typing import Literal, Any
|
|
6
6
|
from collections.abc import Iterator, AsyncIterator
|
|
7
7
|
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
8
8
|
|
|
@@ -122,40 +122,136 @@ class StreamClosed(StreamError):
|
|
|
122
122
|
"""Represents an error when a stream is closed."""
|
|
123
123
|
|
|
124
124
|
class Response:
|
|
125
|
-
"""Response object returned by impit
|
|
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
|
+
"""
|
|
126
136
|
|
|
127
137
|
status_code: int
|
|
128
|
-
"""HTTP status code (e.g., 200, 404)
|
|
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
|
+
"""
|
|
129
149
|
|
|
130
150
|
reason_phrase: str
|
|
131
|
-
"""HTTP reason phrase (e.g., 'OK', 'Not Found')
|
|
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
|
+
"""
|
|
132
158
|
|
|
133
159
|
http_version: str
|
|
134
|
-
"""HTTP version (e.g., 'HTTP/1.1', 'HTTP/2')
|
|
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
|
+
"""
|
|
135
167
|
|
|
136
168
|
headers: dict[str, str]
|
|
137
|
-
"""Response headers as a dictionary
|
|
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
|
+
"""
|
|
138
176
|
|
|
139
177
|
text: str
|
|
140
|
-
"""Response body as text. Decoded from
|
|
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
|
+
"""
|
|
141
185
|
|
|
142
186
|
encoding: str
|
|
143
|
-
"""Response content encoding
|
|
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
|
+
"""
|
|
144
196
|
|
|
145
197
|
is_redirect: bool
|
|
146
|
-
"""
|
|
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
|
+
"""
|
|
147
205
|
|
|
148
206
|
url: str
|
|
149
|
-
"""
|
|
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
|
+
"""
|
|
150
214
|
|
|
151
215
|
content: bytes
|
|
152
|
-
"""
|
|
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
|
+
"""
|
|
153
223
|
|
|
154
224
|
is_closed: bool
|
|
155
|
-
"""
|
|
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
|
+
"""
|
|
156
237
|
|
|
157
238
|
is_stream_consumed: bool
|
|
158
|
-
"""Whether the response stream has been consumed or closed
|
|
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
|
+
"""
|
|
159
255
|
|
|
160
256
|
def __init__(
|
|
161
257
|
self,
|
|
@@ -177,25 +273,170 @@ class Response:
|
|
|
177
273
|
"""
|
|
178
274
|
|
|
179
275
|
def read(self) -> bytes:
|
|
180
|
-
"""Read the response content as 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).
|
|
181
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
|
+
"""
|
|
182
287
|
def iter_bytes(self) -> Iterator[bytes]:
|
|
183
|
-
"""Iterate over the response content in chunks.
|
|
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
|
+
"""
|
|
184
298
|
|
|
185
299
|
async def aread(self) -> bytes:
|
|
186
|
-
"""Asynchronously read the response content as 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
|
+
"""
|
|
187
311
|
|
|
188
312
|
def aiter_bytes(self) -> AsyncIterator[bytes]:
|
|
189
|
-
"""Asynchronously iterate over the response content in chunks.
|
|
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
|
+
"""
|
|
190
337
|
|
|
191
338
|
def close(self) -> None:
|
|
192
|
-
"""Close the response and release resources.
|
|
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
|
+
"""
|
|
193
353
|
|
|
194
354
|
async def aclose(self) -> None:
|
|
195
|
-
"""Asynchronously close the response and release resources.
|
|
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
|
+
"""
|
|
196
369
|
|
|
197
370
|
class Client:
|
|
198
|
-
"""Synchronous HTTP client with browser impersonation capabilities.
|
|
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
|
+
"""
|
|
199
440
|
|
|
200
441
|
def __enter__(self) -> Client:
|
|
201
442
|
"""Enter the runtime context related to this object."""
|
|
@@ -217,6 +458,7 @@ class Client:
|
|
|
217
458
|
cookie_jar: CookieJar | None = None,
|
|
218
459
|
cookies: Cookies | None = None,
|
|
219
460
|
headers: dict[str, str] | None = None,
|
|
461
|
+
local_address: str | None = None,
|
|
220
462
|
) -> None:
|
|
221
463
|
"""Initialize a synchronous HTTP client.
|
|
222
464
|
|
|
@@ -230,7 +472,11 @@ class Client:
|
|
|
230
472
|
header and bytestream prescan.
|
|
231
473
|
follow_redirects: Whether to follow redirects (default: False)
|
|
232
474
|
max_redirects: Maximum number of redirects to follow (default: 20)
|
|
233
|
-
cookie_jar: Cookie jar to store cookies in
|
|
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).
|
|
234
480
|
"""
|
|
235
481
|
|
|
236
482
|
def get(
|
|
@@ -430,6 +676,17 @@ class Client:
|
|
|
430
676
|
) -> AbstractContextManager[Response]:
|
|
431
677
|
"""Make a streaming request with the specified method.
|
|
432
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
|
+
|
|
433
690
|
Args:
|
|
434
691
|
method: HTTP method (e.g., "get", "post")
|
|
435
692
|
url: URL to request
|
|
@@ -438,14 +695,79 @@ class Client:
|
|
|
438
695
|
headers: HTTP headers
|
|
439
696
|
timeout: Request timeout in seconds (overrides default timeout)
|
|
440
697
|
force_http3: Force HTTP/3 protocol
|
|
441
|
-
|
|
442
|
-
Returns:
|
|
443
|
-
Response object
|
|
444
698
|
"""
|
|
445
699
|
|
|
446
700
|
|
|
447
701
|
class AsyncClient:
|
|
448
|
-
"""Asynchronous HTTP client with browser impersonation capabilities.
|
|
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
|
+
"""
|
|
449
771
|
|
|
450
772
|
async def __aenter__(self) -> AsyncClient:
|
|
451
773
|
"""Enter the runtime context related to this object."""
|
|
@@ -466,6 +788,7 @@ class AsyncClient:
|
|
|
466
788
|
cookie_jar: CookieJar | None = None,
|
|
467
789
|
cookies: Cookies | None = None,
|
|
468
790
|
headers: dict[str, str] | None = None,
|
|
791
|
+
local_address: str | None = None,
|
|
469
792
|
) -> None:
|
|
470
793
|
"""Initialize an asynchronous HTTP client.
|
|
471
794
|
|
|
@@ -479,7 +802,11 @@ class AsyncClient:
|
|
|
479
802
|
header and bytestream prescan.
|
|
480
803
|
follow_redirects: Whether to follow redirects (default: False)
|
|
481
804
|
max_redirects: Maximum number of redirects to follow (default: 20)
|
|
482
|
-
cookie_jar: Cookie jar to store cookies in
|
|
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).
|
|
483
810
|
"""
|
|
484
811
|
|
|
485
812
|
async def get(
|
|
@@ -520,6 +847,7 @@ class AsyncClient:
|
|
|
520
847
|
headers: HTTP headers
|
|
521
848
|
timeout: Request timeout in seconds (overrides default timeout)
|
|
522
849
|
force_http3: Force HTTP/3 protocol
|
|
850
|
+
|
|
523
851
|
"""
|
|
524
852
|
|
|
525
853
|
async def put(
|
|
@@ -678,6 +1006,17 @@ class AsyncClient:
|
|
|
678
1006
|
) -> AbstractAsyncContextManager[Response]:
|
|
679
1007
|
"""Make an asynchronous streaming request with the specified method.
|
|
680
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
|
+
|
|
681
1020
|
Args:
|
|
682
1021
|
method: HTTP method (e.g., "get", "post")
|
|
683
1022
|
url: URL to request
|
|
@@ -689,6 +1028,40 @@ class AsyncClient:
|
|
|
689
1028
|
"""
|
|
690
1029
|
|
|
691
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
|
+
|
|
692
1065
|
def get(
|
|
693
1066
|
url: str,
|
|
694
1067
|
content: bytes | bytearray | list[int] | None = None,
|
|
@@ -696,6 +1069,11 @@ def get(
|
|
|
696
1069
|
headers: dict[str, str] | None = None,
|
|
697
1070
|
timeout: float | None = None,
|
|
698
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,
|
|
699
1077
|
) -> Response:
|
|
700
1078
|
"""Make a GET request without creating a client instance.
|
|
701
1079
|
|
|
@@ -706,6 +1084,11 @@ def get(
|
|
|
706
1084
|
headers: HTTP headers
|
|
707
1085
|
timeout: Request timeout in seconds
|
|
708
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.
|
|
709
1092
|
|
|
710
1093
|
Returns:
|
|
711
1094
|
Response object
|
|
@@ -719,6 +1102,11 @@ def post(
|
|
|
719
1102
|
headers: dict[str, str] | None = None,
|
|
720
1103
|
timeout: float | None = None,
|
|
721
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,
|
|
722
1110
|
) -> Response:
|
|
723
1111
|
"""Make a POST request without creating a client instance.
|
|
724
1112
|
|
|
@@ -729,6 +1117,11 @@ def post(
|
|
|
729
1117
|
headers: HTTP headers
|
|
730
1118
|
timeout: Request timeout in seconds
|
|
731
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.
|
|
732
1125
|
|
|
733
1126
|
Returns:
|
|
734
1127
|
Response object
|
|
@@ -742,6 +1135,11 @@ def put(
|
|
|
742
1135
|
headers: dict[str, str] | None = None,
|
|
743
1136
|
timeout: float | None = None,
|
|
744
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,
|
|
745
1143
|
) -> Response:
|
|
746
1144
|
"""Make a PUT request without creating a client instance.
|
|
747
1145
|
|
|
@@ -752,6 +1150,11 @@ def put(
|
|
|
752
1150
|
headers: HTTP headers
|
|
753
1151
|
timeout: Request timeout in seconds
|
|
754
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.
|
|
755
1158
|
|
|
756
1159
|
Returns:
|
|
757
1160
|
Response object
|
|
@@ -765,6 +1168,11 @@ def patch(
|
|
|
765
1168
|
headers: dict[str, str] | None = None,
|
|
766
1169
|
timeout: float | None = None,
|
|
767
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,
|
|
768
1176
|
) -> Response:
|
|
769
1177
|
"""Make a PATCH request without creating a client instance.
|
|
770
1178
|
|
|
@@ -775,6 +1183,11 @@ def patch(
|
|
|
775
1183
|
headers: HTTP headers
|
|
776
1184
|
timeout: Request timeout in seconds
|
|
777
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.
|
|
778
1191
|
|
|
779
1192
|
Returns:
|
|
780
1193
|
Response object
|
|
@@ -788,6 +1201,11 @@ def delete(
|
|
|
788
1201
|
headers: dict[str, str] | None = None,
|
|
789
1202
|
timeout: float | None = None,
|
|
790
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,
|
|
791
1209
|
) -> Response:
|
|
792
1210
|
"""Make a DELETE request without creating a client instance.
|
|
793
1211
|
|
|
@@ -798,6 +1216,11 @@ def delete(
|
|
|
798
1216
|
headers: HTTP headers
|
|
799
1217
|
timeout: Request timeout in seconds
|
|
800
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.
|
|
801
1224
|
|
|
802
1225
|
Returns:
|
|
803
1226
|
Response object
|
|
@@ -811,6 +1234,11 @@ def head(
|
|
|
811
1234
|
headers: dict[str, str] | None = None,
|
|
812
1235
|
timeout: float | None = None,
|
|
813
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,
|
|
814
1242
|
) -> Response:
|
|
815
1243
|
"""Make a HEAD request without creating a client instance.
|
|
816
1244
|
|
|
@@ -821,6 +1249,11 @@ def head(
|
|
|
821
1249
|
headers: HTTP headers
|
|
822
1250
|
timeout: Request timeout in seconds
|
|
823
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.
|
|
824
1257
|
|
|
825
1258
|
Returns:
|
|
826
1259
|
Response object
|
|
@@ -834,6 +1267,11 @@ def options(
|
|
|
834
1267
|
headers: dict[str, str] | None = None,
|
|
835
1268
|
timeout: float | None = None,
|
|
836
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,
|
|
837
1275
|
) -> Response:
|
|
838
1276
|
"""Make an OPTIONS request without creating a client instance.
|
|
839
1277
|
|
|
@@ -844,6 +1282,11 @@ def options(
|
|
|
844
1282
|
headers: HTTP headers
|
|
845
1283
|
timeout: Request timeout in seconds (overrides default timeout)
|
|
846
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.
|
|
847
1290
|
"""
|
|
848
1291
|
|
|
849
1292
|
|
|
@@ -854,6 +1297,11 @@ def trace(
|
|
|
854
1297
|
headers: dict[str, str] | None = None,
|
|
855
1298
|
timeout: float | None = None,
|
|
856
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,
|
|
857
1305
|
) -> Response:
|
|
858
1306
|
"""Make a TRACE request without creating a client instance.
|
|
859
1307
|
|
|
@@ -864,4 +1312,9 @@ def trace(
|
|
|
864
1312
|
headers: HTTP headers
|
|
865
1313
|
timeout: Request timeout in seconds (overrides default timeout)
|
|
866
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.
|
|
867
1320
|
"""
|
|
@@ -1,30 +1,35 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: impit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
|
+
Classifier: Environment :: Console
|
|
5
6
|
Classifier: Intended Audience :: Developers
|
|
6
7
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
7
8
|
Classifier: Operating System :: OS Independent
|
|
8
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.10
|
|
10
10
|
Classifier: Programming Language :: Python :: 3.11
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.12
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
14
|
Classifier: Topic :: Software Development :: Libraries
|
|
14
15
|
Summary: A library for making HTTP requests through browser impersonation
|
|
15
16
|
Keywords: apify,http,requests,browser,impersonation
|
|
16
17
|
Author: Jindřich Bär
|
|
17
|
-
Requires-Python: >=3.
|
|
18
|
+
Requires-Python: >=3.10
|
|
18
19
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
19
|
-
Project-URL: Homepage, https://apify.github.io/impit/
|
|
20
|
+
Project-URL: Homepage, https://apify.github.io/impit/python
|
|
20
21
|
Project-URL: Apify homepage, https://apify.com
|
|
21
22
|
Project-URL: Changelog, https://github.com/apify/impit/blob/master/impit-python/CHANGELOG.md
|
|
22
|
-
Project-URL: Documentation, https://apify.github.io/impit/
|
|
23
|
+
Project-URL: Documentation, https://apify.github.io/impit/python
|
|
23
24
|
Project-URL: Issue tracker, https://github.com/apify/impit/issues
|
|
24
25
|
Project-URL: Repository, https://github.com/apify/impit
|
|
25
26
|
|
|
26
27
|
# `impit` for Python
|
|
27
28
|
|
|
29
|
+
> This documents the `impit` Python package, which provides bindings for the `impit` library.
|
|
30
|
+
>
|
|
31
|
+
> See documentation for the JavaScript/TypeScript version of `impit` [here](https://apify.github.io/impit/js/).
|
|
32
|
+
|
|
28
33
|
`impit` is a Python package that provides bindings for the [`impit`](https://github.com/apify/impit) library.
|
|
29
34
|
|
|
30
35
|
It allows you to switch the TLS fingerprints and the HTTP headers of your requests, while still using the same API as `httpx` or `requests`.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
impit-0.9.0.dist-info/METADATA,sha256=rUem-pBLg6yAp-5ARgqksLUOut5yrVmou21VKAv3Qy0,2833
|
|
2
|
+
impit-0.9.0.dist-info/WHEEL,sha256=Ybp1oDkJBU8Ab2KYc9w5pff1H2QW76YQNrhpVtngYLU,109
|
|
3
|
+
impit.libs/libgcc_s-39080030.so.1,sha256=fIO6GHOh8Ft9CR0Geu7wSUb9Xnl122iTtrxQQ9TAkTQ,789673
|
|
4
|
+
impit/__init__.py,sha256=uZsD0XMFOt7QwVUgNcnVQkDF85y9n5slxoxR0wim7ug,1664
|
|
5
|
+
impit/cookies.py,sha256=bfNPkMk2Y0bG-RqqMMJxIfvCMZp_fDclYAnSlsCwkIg,7009
|
|
6
|
+
impit/impit.cpython-312-aarch64-linux-musl.so,sha256=AI1xdQe5SzTukDAFyF9dk_lGD0HB7zfv4_w5QrWTh9U,12849873
|
|
7
|
+
impit/impit.pyi,sha256=IxLCuSkx3mHQcwcSS65lveoM5QYvMeJcU-Mhhdelyng,45730
|
|
8
|
+
impit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
impit-0.9.0.dist-info/RECORD,,
|
|
Binary file
|
impit-0.5.3.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
impit-0.5.3.dist-info/METADATA,sha256=XTUilna7o4u2NI0O3-74diGL9_aiZFy_-yj15XnefGU,2575
|
|
2
|
-
impit-0.5.3.dist-info/WHEEL,sha256=77uLsexs5piXr065lkfE-7Z3IZOGhedsFiqWwb7oDTI,108
|
|
3
|
-
impit.libs/libgcc_s-e52197c3.so.1,sha256=vkPW1Auw6CH9Bjk7frmX3hry_1H9c0tRI0Ncyg71WUI,724137
|
|
4
|
-
impit/__init__.py,sha256=NDkCeC_CQn9xqqN2fFSWmvkN9oM-ysMnB1WDkvX-Pbc,1566
|
|
5
|
-
impit/cookies.py,sha256=bfNPkMk2Y0bG-RqqMMJxIfvCMZp_fDclYAnSlsCwkIg,7009
|
|
6
|
-
impit/impit.cpython-312-aarch64-linux-musl.so,sha256=iBaTjfbwfDUu2zuN4mqflWUsXCf3mydfb3mZiuJ63K0,12784201
|
|
7
|
-
impit/impit.pyi,sha256=1tVuu9r6JEQBuyYwdnA8CfJ3yiqsQc9hYQtypJttNtA,26602
|
|
8
|
-
impit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
-
impit-0.5.3.dist-info/RECORD,,
|