rnet 3.0.0rc2__cp311-abi3-win_amd64.whl → 3.0.0rc4__cp311-abi3-win_amd64.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.
Potentially problematic release.
This version of rnet might be problematic. Click here for more details.
- rnet/__init__.py +1 -3
- rnet/__init__.pyi +806 -596
- rnet/blocking.py +218 -266
- rnet/cookie.py +16 -6
- rnet/emulation.py +6 -3
- rnet/exceptions.py +17 -13
- rnet/header.py +50 -127
- rnet/rnet.pyd +0 -0
- rnet/tls.py +6 -4
- {rnet-3.0.0rc2.dist-info → rnet-3.0.0rc4.dist-info}/METADATA +47 -47
- rnet-3.0.0rc4.dist-info/RECORD +14 -0
- rnet-3.0.0rc4.dist-info/licenses/LICENSE +201 -0
- rnet-3.0.0rc2.dist-info/RECORD +0 -14
- rnet-3.0.0rc2.dist-info/licenses/LICENSE +0 -674
- {rnet-3.0.0rc2.dist-info → rnet-3.0.0rc4.dist-info}/WHEEL +0 -0
rnet/emulation.py
CHANGED
|
@@ -11,7 +11,8 @@ authentic and less likely to be blocked by anti-bot systems.
|
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
13
|
from enum import Enum, auto
|
|
14
|
-
|
|
14
|
+
|
|
15
|
+
__all__ = ["Emulation", "EmulationOS", "EmulationOption"]
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class Emulation(Enum):
|
|
@@ -132,12 +133,12 @@ class EmulationOption:
|
|
|
132
133
|
"""
|
|
133
134
|
|
|
134
135
|
def __init__(
|
|
135
|
-
|
|
136
|
+
self,
|
|
136
137
|
emulation: Emulation,
|
|
137
138
|
emulation_os: EmulationOS | None = None,
|
|
138
139
|
skip_http2: bool | None = None,
|
|
139
140
|
skip_headers: bool | None = None,
|
|
140
|
-
) ->
|
|
141
|
+
) -> None:
|
|
141
142
|
"""
|
|
142
143
|
Create a new emulation configuration.
|
|
143
144
|
|
|
@@ -163,6 +164,7 @@ class EmulationOption:
|
|
|
163
164
|
)
|
|
164
165
|
```
|
|
165
166
|
"""
|
|
167
|
+
...
|
|
166
168
|
|
|
167
169
|
@staticmethod
|
|
168
170
|
def random() -> "EmulationOption":
|
|
@@ -183,3 +185,4 @@ class EmulationOption:
|
|
|
183
185
|
client2 = rnet.Client(emulation=EmulationOption.random())
|
|
184
186
|
```
|
|
185
187
|
"""
|
|
188
|
+
...
|
rnet/exceptions.py
CHANGED
|
@@ -6,6 +6,23 @@ The exceptions are organized into logical categories based on their cause and
|
|
|
6
6
|
severity, making it easier to handle specific types of errors appropriately.
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
+
__all__ = [
|
|
10
|
+
"DNSResolverError",
|
|
11
|
+
"TlsError",
|
|
12
|
+
"ConnectionError",
|
|
13
|
+
"ConnectionResetError",
|
|
14
|
+
"BodyError",
|
|
15
|
+
"BuilderError",
|
|
16
|
+
"DecodingError",
|
|
17
|
+
"StatusError",
|
|
18
|
+
"RequestError",
|
|
19
|
+
"RedirectError",
|
|
20
|
+
"UpgradeError",
|
|
21
|
+
"WebSocketError",
|
|
22
|
+
"URLParseError",
|
|
23
|
+
"TimeoutError",
|
|
24
|
+
]
|
|
25
|
+
|
|
9
26
|
# ========================================
|
|
10
27
|
# Network and System-Level Errors
|
|
11
28
|
# ========================================
|
|
@@ -181,19 +198,6 @@ class URLParseError(Exception):
|
|
|
181
198
|
"""
|
|
182
199
|
|
|
183
200
|
|
|
184
|
-
class MIMEParseError(Exception):
|
|
185
|
-
r"""
|
|
186
|
-
An error occurred while parsing a MIME type.
|
|
187
|
-
|
|
188
|
-
This exception covers failures in parsing or processing
|
|
189
|
-
MIME types and related content type information, such as:
|
|
190
|
-
- Invalid MIME type format
|
|
191
|
-
- Unsupported content types
|
|
192
|
-
- Malformed content-type headers
|
|
193
|
-
- Character set parsing issues
|
|
194
|
-
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
201
|
# ========================================
|
|
198
202
|
# Timeout Errors
|
|
199
203
|
# ========================================
|
rnet/header.py
CHANGED
|
@@ -11,7 +11,9 @@ including proper support for headers that can have multiple values (like
|
|
|
11
11
|
Set-Cookie, Accept-Encoding, etc.).
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
from typing import List, Optional, Tuple
|
|
14
|
+
from typing import Dict, Iterator, List, Optional, Tuple
|
|
15
|
+
|
|
16
|
+
__all__ = ["HeaderMap", "OrigHeaderMap"]
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
class HeaderMap:
|
|
@@ -47,8 +49,8 @@ class HeaderMap:
|
|
|
47
49
|
"""Return the total number of header values (not unique names)."""
|
|
48
50
|
...
|
|
49
51
|
|
|
50
|
-
def __iter__(self) ->
|
|
51
|
-
"""Iterate
|
|
52
|
+
def __iter__(self) -> Iterator[Tuple[bytes, bytes]]:
|
|
53
|
+
"""Iterate all header(name, value) pairs, including duplicates for multiple values."""
|
|
52
54
|
...
|
|
53
55
|
|
|
54
56
|
def __str__(self) -> str:
|
|
@@ -56,8 +58,8 @@ class HeaderMap:
|
|
|
56
58
|
...
|
|
57
59
|
|
|
58
60
|
def __init__(
|
|
59
|
-
|
|
60
|
-
) ->
|
|
61
|
+
self, init: Dict[str, str] | None = None, capacity: int | None = None
|
|
62
|
+
) -> None:
|
|
61
63
|
"""
|
|
62
64
|
Create a new HeaderMap.
|
|
63
65
|
|
|
@@ -97,6 +99,7 @@ class HeaderMap:
|
|
|
97
99
|
Returns:
|
|
98
100
|
True if the header exists, False otherwise
|
|
99
101
|
"""
|
|
102
|
+
...
|
|
100
103
|
|
|
101
104
|
def insert(self, key: str, value: str) -> None:
|
|
102
105
|
r"""
|
|
@@ -109,6 +112,7 @@ class HeaderMap:
|
|
|
109
112
|
key: The header name (case-insensitive)
|
|
110
113
|
value: The header value to set
|
|
111
114
|
"""
|
|
115
|
+
...
|
|
112
116
|
|
|
113
117
|
def append(self, key: str, value: str) -> None:
|
|
114
118
|
r"""
|
|
@@ -122,6 +126,7 @@ class HeaderMap:
|
|
|
122
126
|
key: The header name (case-insensitive)
|
|
123
127
|
value: The header value to append
|
|
124
128
|
"""
|
|
129
|
+
...
|
|
125
130
|
|
|
126
131
|
def remove(self, key: str) -> None:
|
|
127
132
|
r"""
|
|
@@ -133,6 +138,7 @@ class HeaderMap:
|
|
|
133
138
|
Args:
|
|
134
139
|
key: The header name to remove (case-insensitive)
|
|
135
140
|
"""
|
|
141
|
+
...
|
|
136
142
|
|
|
137
143
|
def get(self, key: str, default: Optional[bytes] = None) -> Optional[bytes]:
|
|
138
144
|
r"""
|
|
@@ -149,8 +155,9 @@ class HeaderMap:
|
|
|
149
155
|
Returns:
|
|
150
156
|
The first header value as bytes, or the default value
|
|
151
157
|
"""
|
|
158
|
+
...
|
|
152
159
|
|
|
153
|
-
def get_all(self, key: str) ->
|
|
160
|
+
def get_all(self, key: str) -> Iterator[bytes]:
|
|
154
161
|
r"""
|
|
155
162
|
Get all values for a header name.
|
|
156
163
|
|
|
@@ -164,6 +171,25 @@ class HeaderMap:
|
|
|
164
171
|
Returns:
|
|
165
172
|
An iterator over all header values
|
|
166
173
|
"""
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
def values(self) -> Iterator[bytes]:
|
|
177
|
+
"""
|
|
178
|
+
Iterate over all header values.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
An iterator over all header values as bytes.
|
|
182
|
+
"""
|
|
183
|
+
...
|
|
184
|
+
|
|
185
|
+
def keys(self) -> Iterator[bytes]:
|
|
186
|
+
"""
|
|
187
|
+
Iterate over unique header names.
|
|
188
|
+
|
|
189
|
+
Returns:
|
|
190
|
+
An iterator over unique header names as bytes.
|
|
191
|
+
"""
|
|
192
|
+
...
|
|
167
193
|
|
|
168
194
|
def len(self) -> int:
|
|
169
195
|
"""
|
|
@@ -176,6 +202,7 @@ class HeaderMap:
|
|
|
176
202
|
Returns:
|
|
177
203
|
Total number of header values stored
|
|
178
204
|
"""
|
|
205
|
+
...
|
|
179
206
|
|
|
180
207
|
def keys_len(self) -> int:
|
|
181
208
|
"""
|
|
@@ -187,6 +214,7 @@ class HeaderMap:
|
|
|
187
214
|
Returns:
|
|
188
215
|
Number of unique header names
|
|
189
216
|
"""
|
|
217
|
+
...
|
|
190
218
|
|
|
191
219
|
def is_empty(self) -> bool:
|
|
192
220
|
"""
|
|
@@ -195,6 +223,7 @@ class HeaderMap:
|
|
|
195
223
|
Returns:
|
|
196
224
|
True if no headers are stored, False otherwise
|
|
197
225
|
"""
|
|
226
|
+
...
|
|
198
227
|
|
|
199
228
|
def clear(self) -> None:
|
|
200
229
|
"""
|
|
@@ -203,18 +232,7 @@ class HeaderMap:
|
|
|
203
232
|
After calling this method, the header map will be empty and
|
|
204
233
|
is_empty() will return True.
|
|
205
234
|
"""
|
|
206
|
-
|
|
207
|
-
def items(self) -> "HeaderMapItemsIter":
|
|
208
|
-
r"""
|
|
209
|
-
Get an iterator over all header name-value pairs.
|
|
210
|
-
|
|
211
|
-
Returns an iterator that yields tuples of (name, value) for each
|
|
212
|
-
header value. Headers with multiple values will appear multiple
|
|
213
|
-
times with different values.
|
|
214
|
-
|
|
215
|
-
Returns:
|
|
216
|
-
Iterator over (name, value) tuples
|
|
217
|
-
"""
|
|
235
|
+
...
|
|
218
236
|
|
|
219
237
|
|
|
220
238
|
class OrigHeaderMap:
|
|
@@ -259,33 +277,7 @@ class OrigHeaderMap:
|
|
|
259
277
|
"""
|
|
260
278
|
...
|
|
261
279
|
|
|
262
|
-
def
|
|
263
|
-
"""
|
|
264
|
-
Insert a new header name into the collection.
|
|
265
|
-
|
|
266
|
-
If the map did not previously have this key present, then False is returned.
|
|
267
|
-
If the map did have this key present, the new value is pushed to the end
|
|
268
|
-
of the list of values currently associated with the key. The key is not
|
|
269
|
-
updated, though; this matters for types that can be == without being identical.
|
|
270
|
-
|
|
271
|
-
Args:
|
|
272
|
-
value: The header name to insert.
|
|
273
|
-
|
|
274
|
-
Returns:
|
|
275
|
-
True if the key was newly inserted, False if it already existed.
|
|
276
|
-
"""
|
|
277
|
-
...
|
|
278
|
-
|
|
279
|
-
def extend(self, other: "OrigHeaderMap") -> None:
|
|
280
|
-
"""
|
|
281
|
-
Extends the map with all entries from another OrigHeaderMap, preserving order.
|
|
282
|
-
|
|
283
|
-
Args:
|
|
284
|
-
other: Another OrigHeaderMap to extend from.
|
|
285
|
-
"""
|
|
286
|
-
...
|
|
287
|
-
|
|
288
|
-
def items(self) -> "OrigHeaderMapIter":
|
|
280
|
+
def __iter__(self) -> Iterator[Tuple[bytes, bytes]]:
|
|
289
281
|
"""
|
|
290
282
|
Returns an iterator over the (standard_name, original_name) pairs.
|
|
291
283
|
|
|
@@ -300,97 +292,28 @@ class OrigHeaderMap:
|
|
|
300
292
|
"""
|
|
301
293
|
...
|
|
302
294
|
|
|
303
|
-
|
|
304
|
-
class HeaderMapItemsIter:
|
|
305
|
-
r"""
|
|
306
|
-
Iterator over header name-value pairs in a HeaderMap.
|
|
307
|
-
|
|
308
|
-
Yields tuples of (header_name, header_value) where both are bytes.
|
|
309
|
-
Headers with multiple values will appear as separate tuples.
|
|
310
|
-
"""
|
|
311
|
-
|
|
312
|
-
def __iter__(self) -> "HeaderMapItemsIter":
|
|
313
|
-
"""Return self as iterator."""
|
|
314
|
-
...
|
|
315
|
-
|
|
316
|
-
def __next__(self) -> Optional[Tuple[bytes, bytes]]:
|
|
317
|
-
"""
|
|
318
|
-
Get the next header name-value pair.
|
|
319
|
-
|
|
320
|
-
Returns:
|
|
321
|
-
Tuple of (header_name, header_value) or None when exhausted
|
|
322
|
-
"""
|
|
323
|
-
...
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
class HeaderMapKeysIter:
|
|
327
|
-
r"""
|
|
328
|
-
Iterator over unique header names in a HeaderMap.
|
|
329
|
-
|
|
330
|
-
Yields each unique header name as bytes, regardless of how many
|
|
331
|
-
values each header has.
|
|
332
|
-
"""
|
|
333
|
-
|
|
334
|
-
def __iter__(self) -> "HeaderMapKeysIter":
|
|
335
|
-
"""Return self as iterator."""
|
|
336
|
-
...
|
|
337
|
-
|
|
338
|
-
def __next__(self) -> Optional[bytes]:
|
|
339
|
-
"""
|
|
340
|
-
Get the next unique header name.
|
|
341
|
-
|
|
342
|
-
Returns:
|
|
343
|
-
Header name as bytes, or None when exhausted
|
|
295
|
+
def insert(self, value: str) -> bool:
|
|
344
296
|
"""
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
class HeaderMapValuesIter:
|
|
349
|
-
r"""
|
|
350
|
-
Iterator over header values in a HeaderMap.
|
|
351
|
-
|
|
352
|
-
Yields header values as bytes. When used with get_all(), yields
|
|
353
|
-
all values for a specific header name. When used independently,
|
|
354
|
-
yields all values in the entire map.
|
|
355
|
-
"""
|
|
297
|
+
Insert a new header name into the collection.
|
|
356
298
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
299
|
+
If the map did not previously have this key present, then False is returned.
|
|
300
|
+
If the map did have this key present, the new value is pushed to the end
|
|
301
|
+
of the list of values currently associated with the key. The key is not
|
|
302
|
+
updated, though; this matters for types that can be == without being identical.
|
|
360
303
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
Get the next header value.
|
|
304
|
+
Args:
|
|
305
|
+
value: The header name to insert.
|
|
364
306
|
|
|
365
307
|
Returns:
|
|
366
|
-
|
|
367
|
-
"""
|
|
368
|
-
...
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
class OrigHeaderMapIter:
|
|
372
|
-
"""
|
|
373
|
-
An iterator over the items in an OrigHeaderMap.
|
|
374
|
-
|
|
375
|
-
Yields tuples of (standard_header_name, original_header_name) where:
|
|
376
|
-
- standard_header_name is the normalized header name
|
|
377
|
-
- original_header_name is the header name as originally received/specified
|
|
378
|
-
"""
|
|
379
|
-
|
|
380
|
-
def __iter__(self) -> "OrigHeaderMapIter":
|
|
381
|
-
"""
|
|
382
|
-
Returns the iterator itself.
|
|
308
|
+
True if the key was newly inserted, False if it already existed.
|
|
383
309
|
"""
|
|
384
310
|
...
|
|
385
311
|
|
|
386
|
-
def
|
|
312
|
+
def extend(self, other: "OrigHeaderMap") -> None:
|
|
387
313
|
"""
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
Returns:
|
|
391
|
-
A tuple of (standard_header_name, original_header_name) as bytes.
|
|
314
|
+
Extends the map with all entries from another OrigHeaderMap, preserving order.
|
|
392
315
|
|
|
393
|
-
|
|
394
|
-
|
|
316
|
+
Args:
|
|
317
|
+
other: Another OrigHeaderMap to extend from.
|
|
395
318
|
"""
|
|
396
319
|
...
|
rnet/rnet.pyd
CHANGED
|
Binary file
|
rnet/tls.py
CHANGED
|
@@ -8,7 +8,9 @@ These types are typically used to configure client-side TLS authentication and c
|
|
|
8
8
|
|
|
9
9
|
from enum import Enum, auto
|
|
10
10
|
from pathlib import Path
|
|
11
|
-
from typing import List
|
|
11
|
+
from typing import List
|
|
12
|
+
|
|
13
|
+
__all__ = ["TlsVersion", "Identity", "CertStore", "KeyLogPolicy"]
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
class TlsVersion(Enum):
|
|
@@ -44,7 +46,7 @@ class Identity:
|
|
|
44
46
|
...
|
|
45
47
|
|
|
46
48
|
@staticmethod
|
|
47
|
-
def from_pkcs8_pem(buf: bytes, key: bytes) -> "
|
|
49
|
+
def from_pkcs8_pem(buf: bytes, key: bytes) -> "Identity":
|
|
48
50
|
"""
|
|
49
51
|
Parses a chain of PEM encoded X509 certificates, with the leaf certificate first.
|
|
50
52
|
`key` is a PEM encoded PKCS #8 formatted private key for the leaf certificate.
|
|
@@ -63,11 +65,11 @@ class CertStore:
|
|
|
63
65
|
"""
|
|
64
66
|
|
|
65
67
|
def __init__(
|
|
66
|
-
|
|
68
|
+
self,
|
|
67
69
|
der_certs: List[bytes] | None = None,
|
|
68
70
|
pem_certs: List[str] | None = None,
|
|
69
71
|
default_paths: bool | None = None,
|
|
70
|
-
) ->
|
|
72
|
+
) -> None:
|
|
71
73
|
"""
|
|
72
74
|
Creates a new CertStore.
|
|
73
75
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rnet
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.0rc4
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
@@ -19,7 +19,7 @@ License-File: LICENSE
|
|
|
19
19
|
Summary: A blazing-fast Python HTTP client with TLS fingerprint
|
|
20
20
|
Keywords: http,client,websocket,ja3,ja4
|
|
21
21
|
Author-email: 0x676e67 <gngppz@gmail.com>
|
|
22
|
-
License:
|
|
22
|
+
License: Apache-2.0
|
|
23
23
|
Requires-Python: >=3.11
|
|
24
24
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
25
25
|
Project-URL: Documentation, https://github.com/0x676e67/rnet/blob/main/rnet.pyi
|
|
@@ -36,7 +36,7 @@ Project-URL: Repository, https://github.com/0x676e67/rnet
|
|
|
36
36
|
|
|
37
37
|
> 🚀 Help me work seamlessly with open source sharing by [sponsoring me on GitHub](https://github.com/0x676e67/0x676e67/blob/main/SPONSOR.md)
|
|
38
38
|
|
|
39
|
-
A blazing-fast Python HTTP client with advanced browser fingerprinting that accurately emulates **Chrome**, **Firefox**, **Safari**, **Opera**, and **OkHttp**, with precise
|
|
39
|
+
A blazing-fast Python HTTP client with advanced browser fingerprinting that accurately emulates **Chrome**, **Firefox**, **Safari**, **Opera**, and **OkHttp**, with precise TLS and HTTP2 signatures, and powered by [wreq](https://github.com/0x676e67/wreq) for high performance.
|
|
40
40
|
|
|
41
41
|
## Features
|
|
42
42
|
|
|
@@ -57,10 +57,10 @@ A blazing-fast Python HTTP client with advanced browser fingerprinting that accu
|
|
|
57
57
|
|
|
58
58
|
## Example
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
The following example uses the `asyncio` runtime with `rnet` installed via pip:
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
pip install asyncio rnet==3.0.
|
|
63
|
+
pip install asyncio rnet==3.0.0rc4
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
And then the code:
|
|
@@ -91,7 +91,33 @@ Additional learning resources include:
|
|
|
91
91
|
- [DeepWiki](https://deepwiki.com/0x676e67/rnet)
|
|
92
92
|
- [API Documentation](https://github.com/0x676e67/rnet/blob/main/python/rnet)
|
|
93
93
|
- [Repository Tests](https://github.com/0x676e67/rnet/tree/main/tests)
|
|
94
|
-
- [
|
|
94
|
+
- [Synchronous Examples](https://github.com/0x676e67/rnet/tree/main/python/examples/blocking)
|
|
95
|
+
- [Asynchronous Examples](https://github.com/0x676e67/rnet/tree/main/python/examples)
|
|
96
|
+
- <details>
|
|
97
|
+
<summary>Available OS emulations</summary>
|
|
98
|
+
|
|
99
|
+
| **OS** | **Description** |
|
|
100
|
+
| ----------- | ------------------------------ |
|
|
101
|
+
| **Windows** | Windows (any version) |
|
|
102
|
+
| **MacOS** | macOS (any version) |
|
|
103
|
+
| **Linux** | Linux (any distribution) |
|
|
104
|
+
| **Android** | Android (mobile) |
|
|
105
|
+
| **iOS** | iOS (iPhone/iPad) |
|
|
106
|
+
|
|
107
|
+
</details>
|
|
108
|
+
- <details>
|
|
109
|
+
<summary>Available browser emulations</summary>
|
|
110
|
+
|
|
111
|
+
| **Browser** | **Versions** |
|
|
112
|
+
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137` |
|
|
114
|
+
| **Safari** | `SafariIos17_2`, `SafariIos17_4_1`, `SafariIos16_5`, `Safari15_3`, `Safari15_5`, `Safari15_6_1`, `Safari16`, `Safari16_5`, `Safari17_0`, `Safari17_2_1`, `Safari17_4_1`, `Safari17_5`, `Safari18`, `SafariIPad18`, `Safari18_2`, `SafariIos18_1_1`, `Safari18_3`, `Safari18_3_1`, `Safari18_5` |
|
|
115
|
+
| **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139` |
|
|
116
|
+
| **OkHttp** | `OkHttp3_9`, `OkHttp3_11`, `OkHttp3_13`, `OkHttp3_14`, `OkHttp4_9`, `OkHttp4_10`, `OkHttp4_12`, `OkHttp5` |
|
|
117
|
+
| **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134` |
|
|
118
|
+
| **Opera** | `Opera116`, `Opera117`, `Opera118`, `Opera119` |
|
|
119
|
+
|
|
120
|
+
</details>
|
|
95
121
|
|
|
96
122
|
## Platforms
|
|
97
123
|
|
|
@@ -106,48 +132,39 @@ Additional learning resources include:
|
|
|
106
132
|
|
|
107
133
|
## Building
|
|
108
134
|
|
|
109
|
-
1.
|
|
135
|
+
1. Development
|
|
136
|
+
|
|
137
|
+
Install the BoringSSL build environment by referring to [boring](https://github.com/cloudflare/boring/blob/master/.github/workflows/ci.yml) and [boringssl](https://github.com/google/boringssl/blob/master/BUILDING.md#build-prerequisites).
|
|
110
138
|
|
|
111
139
|
```bash
|
|
140
|
+
# on ubuntu or debian
|
|
141
|
+
sudo apt install -y build-essential cmake perl pkg-config libclang-dev musl-tools git
|
|
112
142
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
|
113
|
-
pip install maturin
|
|
114
|
-
pip install uv
|
|
143
|
+
pip install uv maturin
|
|
115
144
|
|
|
116
145
|
uv venv
|
|
117
146
|
source .venv/bin/activate
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
2. Development
|
|
121
147
|
|
|
122
|
-
|
|
123
|
-
# build and install the package
|
|
148
|
+
# Development
|
|
124
149
|
maturin develop --uv
|
|
125
|
-
python3 examples/client.py
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
3. Compile wheels
|
|
129
150
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
# on ubuntu or debian
|
|
134
|
-
sudo apt-get install build-essential cmake perl pkg-config libclang-dev musl-tools git -y
|
|
151
|
+
# Build wheels
|
|
135
152
|
maturin build --release
|
|
136
153
|
```
|
|
137
154
|
|
|
138
|
-
|
|
155
|
+
2. Musllinux
|
|
139
156
|
|
|
140
157
|
Make sure you have Docker installed. The provided image may be outdated, so you might need to build it yourself. See [rust-cross-musl](https://github.com/0x676e67/toolchain/blob/master/rust-musl-cross/Dockerfile) and the upstream [rust-cross/rust-musl-cross](https://github.com/rust-cross/rust-musl-cross) for reference.
|
|
141
158
|
**Note:** The upstream image does not include some platform-specific linker environment variables; you may need to add these manually.
|
|
142
159
|
|
|
143
160
|
```bash
|
|
161
|
+
bash .github/musl_build.sh i686-unknown-linux-musl
|
|
144
162
|
bash .github/musl_build.sh x86_64-unknown-linux-musl
|
|
145
163
|
bash .github/musl_build.sh aarch64-unknown-linux-musl
|
|
146
164
|
bash .github/musl_build.sh armv7-unknown-linux-musleabihf
|
|
147
|
-
bash .github/musl_build.sh i686-unknown-linux-musl
|
|
148
165
|
```
|
|
149
166
|
|
|
150
|
-
|
|
167
|
+
3. Manylinux
|
|
151
168
|
|
|
152
169
|
For Manylinux compilation, refer to [manylinux](https://github.com/PyO3/maturin?tab=readme-ov-file#manylinux-and-auditwheel).
|
|
153
170
|
|
|
@@ -155,34 +172,17 @@ For Manylinux compilation, refer to [manylinux](https://github.com/PyO3/maturin?
|
|
|
155
172
|
|
|
156
173
|
Outperforms `requests`, `httpx`, `Python-TLS-Client`, and `curl_cffi`. See the [benchmark](https://github.com/0x676e67/rnet/tree/main/python/benchmark) for details. Benchmark data is for reference only—actual performance may vary based on your environment and use case.
|
|
157
174
|
|
|
158
|
-
##
|
|
159
|
-
|
|
160
|
-
For a comprehensive introduction to this library, refer to the [DeepWiki](https://deepwiki.com/0x676e67/rnet) documentation. This AI-generated guide, created by a third party, offers a solid overview and allows interaction with the AI to explore specific APIs.
|
|
161
|
-
|
|
162
|
-
## Emulation
|
|
163
|
-
|
|
164
|
-
In fact, most device models share the same `TLS`/`HTTP2` configuration, with the main difference being the `User-Agent`.
|
|
175
|
+
## License
|
|
165
176
|
|
|
166
|
-
|
|
167
|
-
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
168
|
-
| **Chrome** | `Chrome100`, `Chrome101`, `Chrome104`, `Chrome105`, `Chrome106`, `Chrome107`, `Chrome108`, `Chrome109`, `Chrome110`, `Chrome114`, `Chrome116`, `Chrome117`, `Chrome118`, `Chrome119`, `Chrome120`, `Chrome123`, `Chrome124`, `Chrome126`, `Chrome127`, `Chrome128`, `Chrome129`, `Chrome130`, `Chrome131`, `Chrome132`, `Chrome133`, `Chrome134`, `Chrome135`, `Chrome136`, `Chrome137` |
|
|
169
|
-
| **Safari** | `SafariIos17_2`, `SafariIos17_4_1`, `SafariIos16_5`, `Safari15_3`, `Safari15_5`, `Safari15_6_1`, `Safari16`, `Safari16_5`, `Safari17_0`, `Safari17_2_1`, `Safari17_4_1`, `Safari17_5`, `Safari18`, `SafariIPad18`, `Safari18_2`, `SafariIos18_1_1`, `Safari18_3`, `Safari18_3_1`, `Safari18_5` |
|
|
170
|
-
| **Firefox** | `Firefox109`, `Firefox117`, `Firefox128`, `Firefox133`, `Firefox135`, `FirefoxPrivate135`, `FirefoxAndroid135`, `Firefox136`, `FirefoxPrivate136`, `Firefox139` |
|
|
171
|
-
| **OkHttp** | `OkHttp3_9`, `OkHttp3_11`, `OkHttp3_13`, `OkHttp3_14`, `OkHttp4_9`, `OkHttp4_10`, `OkHttp4_12`, `OkHttp5` |
|
|
172
|
-
| **Edge** | `Edge101`, `Edge122`, `Edge127`, `Edge131`, `Edge134` |
|
|
173
|
-
| **Opera** | `Opera116`, `Opera117`, `Opera118`, `Opera119` |
|
|
177
|
+
Licensed under either of Apache License, Version 2.0 ([LICENSE](./LICENSE) or http://www.apache.org/licenses/LICENSE-2.0).
|
|
174
178
|
|
|
175
|
-
##
|
|
179
|
+
## Contribution
|
|
176
180
|
|
|
177
|
-
|
|
181
|
+
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the [Apache-2.0](./LICENSE) license, shall be licensed as above, without any additional terms or conditions.
|
|
178
182
|
|
|
179
183
|
## Sponsors
|
|
180
184
|
|
|
181
185
|
<a href="https://dashboard.capsolver.com/passport/register?inviteCode=y7CtB_a-3X6d" target="_blank"><img src="https://raw.githubusercontent.com/0x676e67/rnet/main/.github/assets/capsolver.jpg" height="47" width="149"></a>
|
|
182
186
|
|
|
183
187
|
[CapSolver](https://www.capsolver.com/?utm_source=github&utm_medium=banner_repo&utm_campaign=rnet) leverages AI-powered Auto Web Unblock to bypass Captchas effortlessly, providing fast, reliable, and cost-effective data access with seamless integration into Colly, Puppeteer, and Playwright—use code **`RNET`** for a 6% bonus!
|
|
184
|
-
|
|
185
|
-
## License
|
|
186
|
-
|
|
187
|
-
**rnet** © [0x676e67](https://github.com/0x676e67), Released under the [GPL-3.0](https://github.com/0x676e67/rnet/blob/main/LICENSE) License.
|
|
188
188
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
rnet-3.0.0rc4.dist-info/METADATA,sha256=QTRpFhKFzwVHt2zdbZrwCk9vZLfdoCmVWieLaGKvaxI,10326
|
|
2
|
+
rnet-3.0.0rc4.dist-info/WHEEL,sha256=8hEf8NzM1FnmM77AjVt5h8nDuYkN3UqZ79LoIAHXeRE,95
|
|
3
|
+
rnet-3.0.0rc4.dist-info/licenses/LICENSE,sha256=OgFMgRC_5WSQ1t5oy1xTzIRPejYh83apCq2Hf6M74rw,11558
|
|
4
|
+
rnet/__init__.py,sha256=JPNS7ILBkwReCW_CquzHy2TD-cDauG-mGKhatIWOdPE,294
|
|
5
|
+
rnet/__init__.pyi,sha256=1I3k6jp0OjpPsPIgdsAHUpHdC4rRVMeoE2E6qQS7HKY,33827
|
|
6
|
+
rnet/blocking.py,sha256=xtpOtoXXii2erAUQu8t7Gj405Y47PGpONKzByjT4nJY,8998
|
|
7
|
+
rnet/cookie.py,sha256=l0P_3CWQItvBF70egPTMVWXEP5GW0J3WPm0c66q4o1U,3163
|
|
8
|
+
rnet/emulation.py,sha256=aah7urtGIHouc4SqPbmZQ1FxqJZekeqa1MimOA-KsR0,5252
|
|
9
|
+
rnet/exceptions.py,sha256=FSgQr-fHU_KY93ks6Y5rGF-nctDRQJCvwyBo_24qSR4,6072
|
|
10
|
+
rnet/header.py,sha256=vVLquV5IG8tivo_MbEzcZTV48vWIbSZjHgFGVj46flY,10068
|
|
11
|
+
rnet/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
rnet/rnet.pyd,sha256=iJtgdbmRusAsJOzcLN-s1Fbxl9VDiDzXe4c11otum8A,8909824
|
|
13
|
+
rnet/tls.py,sha256=rm8q73tNPr-n26rFp8qDGYPP82tiqNfC7GMB9mDXpXQ,5016
|
|
14
|
+
rnet-3.0.0rc4.dist-info/RECORD,,
|