impit 0.5.0__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 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
 
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
 
@@ -121,63 +121,322 @@ class RequestNotRead(StreamError):
121
121
  class StreamClosed(StreamError):
122
122
  """Represents an error when a stream is closed."""
123
123
 
124
-
125
124
  class Response:
126
- """Response object returned by impit requests."""
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
+ """
127
136
 
128
137
  status_code: int
129
- """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
+ """
130
149
 
131
150
  reason_phrase: str
132
- """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
+ """
133
158
 
134
159
  http_version: str
135
- """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
+ """
136
167
 
137
168
  headers: dict[str, str]
138
- """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
+ """
139
176
 
140
177
  text: str
141
- """Response body as text. Decoded from `content` using `encoding`."""
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
+ """
142
185
 
143
186
  encoding: str
144
- """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
+ """
145
196
 
146
197
  is_redirect: bool
147
- """Whether the response is a redirect"""
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
+ """
148
205
 
149
206
  url: str
150
- """Final URL"""
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
+ """
151
214
 
152
215
  content: bytes
153
- """Response body as 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
+ """
154
223
 
155
224
  is_closed: bool
156
- """Whether the response is closed"""
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
+ """
157
237
 
158
238
  is_stream_consumed: bool
159
- """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
+ """
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
+ """
160
274
 
161
275
  def read(self) -> bytes:
162
- """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).
163
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
+ """
164
287
  def iter_bytes(self) -> Iterator[bytes]:
165
- """Iterate over the response content in chunks."""
166
-
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
+
167
299
  async def aread(self) -> bytes:
168
- """Asynchronously read the response content as bytes."""
169
-
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
+
170
312
  def aiter_bytes(self) -> AsyncIterator[bytes]:
171
- """Asynchronously iterate over the response content in chunks."""
172
-
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
+
173
338
  def close(self) -> None:
174
- """Close the response and release resources."""
175
-
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
+
176
354
  async def aclose(self) -> None:
177
- """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
+ """
178
369
 
179
370
  class Client:
180
- """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
+ """
181
440
 
182
441
  def __enter__(self) -> Client:
183
442
  """Enter the runtime context related to this object."""
@@ -199,6 +458,7 @@ class Client:
199
458
  cookie_jar: CookieJar | None = None,
200
459
  cookies: Cookies | None = None,
201
460
  headers: dict[str, str] | None = None,
461
+ local_address: str | None = None,
202
462
  ) -> None:
203
463
  """Initialize a synchronous HTTP client.
204
464
 
@@ -212,7 +472,11 @@ class Client:
212
472
  header and bytestream prescan.
213
473
  follow_redirects: Whether to follow redirects (default: False)
214
474
  max_redirects: Maximum number of redirects to follow (default: 20)
215
- 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).
216
480
  """
217
481
 
218
482
  def get(
@@ -412,6 +676,17 @@ class Client:
412
676
  ) -> AbstractContextManager[Response]:
413
677
  """Make a streaming request with the specified method.
414
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
+
415
690
  Args:
416
691
  method: HTTP method (e.g., "get", "post")
417
692
  url: URL to request
@@ -420,14 +695,79 @@ class Client:
420
695
  headers: HTTP headers
421
696
  timeout: Request timeout in seconds (overrides default timeout)
422
697
  force_http3: Force HTTP/3 protocol
423
-
424
- Returns:
425
- Response object
426
698
  """
427
699
 
428
700
 
429
701
  class AsyncClient:
430
- """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
+ """
431
771
 
432
772
  async def __aenter__(self) -> AsyncClient:
433
773
  """Enter the runtime context related to this object."""
@@ -448,6 +788,7 @@ class AsyncClient:
448
788
  cookie_jar: CookieJar | None = None,
449
789
  cookies: Cookies | None = None,
450
790
  headers: dict[str, str] | None = None,
791
+ local_address: str | None = None,
451
792
  ) -> None:
452
793
  """Initialize an asynchronous HTTP client.
453
794
 
@@ -461,7 +802,11 @@ class AsyncClient:
461
802
  header and bytestream prescan.
462
803
  follow_redirects: Whether to follow redirects (default: False)
463
804
  max_redirects: Maximum number of redirects to follow (default: 20)
464
- 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).
465
810
  """
466
811
 
467
812
  async def get(
@@ -502,6 +847,7 @@ class AsyncClient:
502
847
  headers: HTTP headers
503
848
  timeout: Request timeout in seconds (overrides default timeout)
504
849
  force_http3: Force HTTP/3 protocol
850
+
505
851
  """
506
852
 
507
853
  async def put(
@@ -660,6 +1006,17 @@ class AsyncClient:
660
1006
  ) -> AbstractAsyncContextManager[Response]:
661
1007
  """Make an asynchronous streaming request with the specified method.
662
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
+
663
1020
  Args:
664
1021
  method: HTTP method (e.g., "get", "post")
665
1022
  url: URL to request
@@ -671,6 +1028,40 @@ class AsyncClient:
671
1028
  """
672
1029
 
673
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
+
674
1065
  def get(
675
1066
  url: str,
676
1067
  content: bytes | bytearray | list[int] | None = None,
@@ -678,6 +1069,11 @@ def get(
678
1069
  headers: dict[str, str] | None = None,
679
1070
  timeout: float | None = None,
680
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,
681
1077
  ) -> Response:
682
1078
  """Make a GET request without creating a client instance.
683
1079
 
@@ -688,6 +1084,11 @@ def get(
688
1084
  headers: HTTP headers
689
1085
  timeout: Request timeout in seconds
690
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.
691
1092
 
692
1093
  Returns:
693
1094
  Response object
@@ -701,6 +1102,11 @@ def post(
701
1102
  headers: dict[str, str] | None = None,
702
1103
  timeout: float | None = None,
703
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,
704
1110
  ) -> Response:
705
1111
  """Make a POST request without creating a client instance.
706
1112
 
@@ -711,6 +1117,11 @@ def post(
711
1117
  headers: HTTP headers
712
1118
  timeout: Request timeout in seconds
713
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.
714
1125
 
715
1126
  Returns:
716
1127
  Response object
@@ -724,6 +1135,11 @@ def put(
724
1135
  headers: dict[str, str] | None = None,
725
1136
  timeout: float | None = None,
726
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,
727
1143
  ) -> Response:
728
1144
  """Make a PUT request without creating a client instance.
729
1145
 
@@ -734,6 +1150,11 @@ def put(
734
1150
  headers: HTTP headers
735
1151
  timeout: Request timeout in seconds
736
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.
737
1158
 
738
1159
  Returns:
739
1160
  Response object
@@ -747,6 +1168,11 @@ def patch(
747
1168
  headers: dict[str, str] | None = None,
748
1169
  timeout: float | None = None,
749
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,
750
1176
  ) -> Response:
751
1177
  """Make a PATCH request without creating a client instance.
752
1178
 
@@ -757,6 +1183,11 @@ def patch(
757
1183
  headers: HTTP headers
758
1184
  timeout: Request timeout in seconds
759
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.
760
1191
 
761
1192
  Returns:
762
1193
  Response object
@@ -770,6 +1201,11 @@ def delete(
770
1201
  headers: dict[str, str] | None = None,
771
1202
  timeout: float | None = None,
772
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,
773
1209
  ) -> Response:
774
1210
  """Make a DELETE request without creating a client instance.
775
1211
 
@@ -780,6 +1216,11 @@ def delete(
780
1216
  headers: HTTP headers
781
1217
  timeout: Request timeout in seconds
782
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.
783
1224
 
784
1225
  Returns:
785
1226
  Response object
@@ -793,6 +1234,11 @@ def head(
793
1234
  headers: dict[str, str] | None = None,
794
1235
  timeout: float | None = None,
795
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,
796
1242
  ) -> Response:
797
1243
  """Make a HEAD request without creating a client instance.
798
1244
 
@@ -803,6 +1249,11 @@ def head(
803
1249
  headers: HTTP headers
804
1250
  timeout: Request timeout in seconds
805
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.
806
1257
 
807
1258
  Returns:
808
1259
  Response object
@@ -816,6 +1267,11 @@ def options(
816
1267
  headers: dict[str, str] | None = None,
817
1268
  timeout: float | None = None,
818
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,
819
1275
  ) -> Response:
820
1276
  """Make an OPTIONS request without creating a client instance.
821
1277
 
@@ -826,6 +1282,11 @@ def options(
826
1282
  headers: HTTP headers
827
1283
  timeout: Request timeout in seconds (overrides default timeout)
828
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.
829
1290
  """
830
1291
 
831
1292
 
@@ -836,6 +1297,11 @@ def trace(
836
1297
  headers: dict[str, str] | None = None,
837
1298
  timeout: float | None = None,
838
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,
839
1305
  ) -> Response:
840
1306
  """Make a TRACE request without creating a client instance.
841
1307
 
@@ -846,4 +1312,9 @@ def trace(
846
1312
  headers: HTTP headers
847
1313
  timeout: Request timeout in seconds (overrides default timeout)
848
1314
  force_http3: Force HTTP/3 protocol
849
- """
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
+ """
@@ -1,30 +1,35 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: impit
3
- Version: 0.5.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.9
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
- Project-URL: Changelog, https://github.com/apify/impit/blob/master/CHANGELOG.md
22
- Project-URL: Documentation, https://apify.github.io/impit/
22
+ Project-URL: Changelog, https://github.com/apify/impit/blob/master/impit-python/CHANGELOG.md
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.9.2)
2
+ Generator: maturin (1.10.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp312-cp312-musllinux_1_2_aarch64
@@ -1,9 +0,0 @@
1
- impit-0.5.0.dist-info/METADATA,sha256=jAR2pd38pzVyDF5_FcJBLb8wQ0T09Uo4hhlc0EATk2s,2562
2
- impit-0.5.0.dist-info/WHEEL,sha256=yzMofySxBd_sCC6GdUFsLvTUQBdsMACo3giXnMZiTjw,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=e5ARcUXimjYKG2vCwj7P4dlxPEfucUgeaUxIgVWz_BA,12653057
7
- impit/impit.pyi,sha256=zcqv2dQQ6YsH7DrPSxNh0A4_U5yWi0LnNc5eJAxQF4I,25969
8
- impit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- impit-0.5.0.dist-info/RECORD,,