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 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
 
@@ -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 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
+ """
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 `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
+ """
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
- """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
+ """
147
205
 
148
206
  url: str
149
- """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
+ """
150
214
 
151
215
  content: bytes
152
- """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
+ """
153
223
 
154
224
  is_closed: bool
155
- """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
+ """
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.5.3
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
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.9.3)
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.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,,