never-primp 1.0.0__cp38-abi3-win_amd64.whl → 1.0.1__cp38-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 never-primp might be problematic. Click here for more details.

never_primp/__init__.py CHANGED
@@ -35,7 +35,9 @@ class Client(RClient):
35
35
  auth_bearer: str | None = None,
36
36
  params: dict[str, str] | None = None,
37
37
  headers: dict[str, str] | None = None,
38
+ ordered_headers: dict[str, str] | None = None,
38
39
  cookie_store: bool | None = True,
40
+ split_cookies: bool | None = False,
39
41
  referer: bool | None = True,
40
42
  proxy: str | None = None,
41
43
  timeout: float | None = 30,
@@ -62,8 +64,16 @@ class Client(RClient):
62
64
  auth_bearer: a string representing the bearer token for bearer token authentication. Default is None.
63
65
  params: a map of query parameters to append to the URL. Default is None.
64
66
  headers: an optional map of HTTP headers to send with requests. Ignored if `impersonate` is set.
67
+ ordered_headers: an optional ordered map of HTTP headers with strict order preservation.
68
+ Takes priority over `headers`. Use this for bypassing anti-bot detection that checks header order.
69
+ Example: {"User-Agent": "...", "Accept": "...", "Accept-Language": "..."}
70
+ Note: Python 3.7+ dict maintains insertion order by default.
65
71
  cookie_store: enable a persistent cookie store. Received cookies will be preserved and included
66
72
  in additional requests. Default is True.
73
+ split_cookies: split cookies into multiple `cookie` headers (HTTP/2 style) instead of a single
74
+ `Cookie` header. Useful for mimicking browser behavior in HTTP/2. Default is False.
75
+ When True: cookie: a=1 \n cookie: b=2 \n cookie: c=3
76
+ When False: Cookie: a=1; b=2; c=3
67
77
  referer: automatic setting of the `Referer` header. Default is True.
68
78
  proxy: proxy URL for HTTP requests, example: "socks5://127.0.0.1:9150". Default is None.
69
79
  timeout: timeout for HTTP requests in seconds. Default is 30.
@@ -131,7 +141,9 @@ class AsyncClient(Client):
131
141
  auth_bearer: str | None = None,
132
142
  params: dict[str, str] | None = None,
133
143
  headers: dict[str, str] | None = None,
144
+ ordered_headers: dict[str, str] | None = None,
134
145
  cookie_store: bool | None = True,
146
+ split_cookies: bool | None = False,
135
147
  referer: bool | None = True,
136
148
  proxy: str | None = None,
137
149
  timeout: float | None = 30,
@@ -150,7 +162,8 @@ class AsyncClient(Client):
150
162
  tcp_keepalive: float | None = None,
151
163
  # Retry mechanism
152
164
  retry_count: int | None = None,
153
- retry_backoff: float | None = None):
165
+ retry_backoff: float | None = None,
166
+ ):
154
167
  super().__init__()
155
168
 
156
169
  async def __aenter__(self) -> AsyncClient:
Binary file
@@ -1,133 +1,133 @@
1
- from __future__ import annotations
2
-
3
- import sys
4
- from typing import Any, Iterator, Literal, TypedDict
5
-
6
- if sys.version_info <= (3, 11):
7
- from typing_extensions import Unpack
8
- else:
9
- from typing import Unpack
10
-
11
- HttpMethod = Literal["GET", "HEAD", "OPTIONS", "DELETE", "POST", "PUT", "PATCH"]
12
- IMPERSONATE = Literal[
13
- "chrome_100", "chrome_101", "chrome_104", "chrome_105", "chrome_106",
14
- "chrome_107", "chrome_108", "chrome_109", "chrome_114", "chrome_116",
15
- "chrome_117", "chrome_118", "chrome_119", "chrome_120", "chrome_123",
16
- "chrome_124", "chrome_126", "chrome_127", "chrome_128", "chrome_129",
17
- "chrome_130", "chrome_131", "chrome_133", "chrome_134", "chrome_135",
18
- "chrome_136", "chrome_137", "chrome_138", "chrome_139",
19
- "chrome_140","chrome_141",
20
- "safari_15.3", "safari_15.5", "safari_15.6.1", "safari_16",
21
- "safari_16.5", "safari_17.0", "safari_17.2.1", "safari_17.4.1",
22
- "safari_17.5", "safari_18", "safari_18.2","safari_18.3","safari_18.3.1","safari_18.5",
23
- "safari_ios_16.5", "safari_ios_17.2", "safari_ios_17.4.1", "safari_ios_18.1.1",
24
- "safari_ipad_18","safari_26","safari_ipad_26","safari_ios_26",
25
- "okhttp_3.9", "okhttp_3.11", "okhttp_3.13", "okhttp_3.14", "okhttp_4.9",
26
- "okhttp_4.10", "okhttp_4.12","okhttp_5",
27
- "edge_101", "edge_122", "edge_127", "edge_131","edge_134",
28
- "opera_116", "opera_117", "opera_118", "opera_119",
29
- "firefox_109", "firefox_117", "firefox_128", "firefox_133", "firefox_135",
30
- "firefox_136", "firefox_139", "firefox_142", "firefox_143", "firefox_android_135",
31
- "firefox_private_135", "firefox_private_136",
32
- "random",
33
- ] # fmt: skip
34
- IMPERSONATE_OS = Literal["android", "ios", "linux", "macos", "windows", "random"]
35
-
36
- class RequestParams(TypedDict, total=False):
37
- auth: tuple[str, str | None] | None
38
- auth_bearer: str | None
39
- params: dict[str, str] | None
40
- headers: dict[str, str] | None
41
- cookies: dict[str, str] | None
42
- timeout: float | None
43
- content: bytes | None
44
- data: dict[str, Any] | None
45
- json: Any | None
46
- files: dict[str, str] | None
47
-
48
- class ClientRequestParams(RequestParams):
49
- impersonate: IMPERSONATE | None
50
- impersonate_os: IMPERSONATE_OS | None
51
- verify: bool | None
52
- ca_cert_file: str | None
53
-
54
- class Response:
55
- @property
56
- def content(self) -> bytes: ...
57
- @property
58
- def cookies(self) -> dict[str, str]: ...
59
- @property
60
- def headers(self) -> dict[str, str]: ...
61
- @property
62
- def status_code(self) -> int: ...
63
- @property
64
- def url(self) -> str: ...
65
- @property
66
- def encoding(self) -> str: ...
67
- @property
68
- def text(self) -> str: ...
69
- def json(self) -> Any: ...
70
- def stream(self) -> Iterator[bytes]: ...
71
- @property
72
- def text_markdown(self) -> str: ...
73
- @property
74
- def text_plain(self) -> str: ...
75
- @property
76
- def text_rich(self) -> str: ...
77
-
78
- class RClient:
79
- def __init__(
80
- self,
81
- auth: tuple[str, str | None] | None = None,
82
- auth_bearer: str | None = None,
83
- params: dict[str, str] | None = None,
84
- headers: dict[str, str] | None = None,
85
- timeout: float | None = None,
86
- cookie_store: bool | None = True,
87
- referer: bool | None = True,
88
- proxy: str | None = None,
89
- impersonate: IMPERSONATE | None = None,
90
- impersonate_os: IMPERSONATE_OS | None = None,
91
- follow_redirects: bool | None = True,
92
- max_redirects: int | None = 20,
93
- verify: bool | None = True,
94
- ca_cert_file: str | None = None,
95
- https_only: bool | None = False,
96
- http2_only: bool | None = False,
97
- ): ...
98
- @property
99
- def headers(self) -> dict[str, str]: ...
100
- @headers.setter
101
- def headers(self, headers: dict[str, str]) -> None: ...
102
- def headers_update(self, headers: dict[str, str]) -> None: ...
103
- def get_cookies(self, url: str) -> dict[str, str]: ...
104
- def set_cookies(self, url: str, cookies: dict[str, str]) -> None: ...
105
- @property
106
- def proxy(self) -> str | None: ...
107
- @proxy.setter
108
- def proxy(self, proxy: str) -> None: ...
109
- @property
110
- def impersonate(self) -> str | None: ...
111
- @impersonate.setter
112
- def impersonate(self, impersonate: IMPERSONATE) -> None: ...
113
- @property
114
- def impersonate_os(self) -> str | None: ...
115
- @impersonate_os.setter
116
- def impersonate_os(self, impersonate: IMPERSONATE_OS) -> None: ...
117
- def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
118
- def get(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
119
- def head(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
120
- def options(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
121
- def delete(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
122
- def post(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
123
- def put(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
124
- def patch(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
125
-
126
- def request(method: HttpMethod, url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
127
- def get(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
128
- def head(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
129
- def options(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
130
- def delete(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
131
- def post(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
132
- def put(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
133
- def patch(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
1
+ from __future__ import annotations
2
+
3
+ import sys
4
+ from typing import Any, Iterator, Literal, TypedDict
5
+
6
+ if sys.version_info <= (3, 11):
7
+ from typing_extensions import Unpack
8
+ else:
9
+ from typing import Unpack
10
+
11
+ HttpMethod = Literal["GET", "HEAD", "OPTIONS", "DELETE", "POST", "PUT", "PATCH"]
12
+ IMPERSONATE = Literal[
13
+ "chrome_100", "chrome_101", "chrome_104", "chrome_105", "chrome_106",
14
+ "chrome_107", "chrome_108", "chrome_109", "chrome_114", "chrome_116",
15
+ "chrome_117", "chrome_118", "chrome_119", "chrome_120", "chrome_123",
16
+ "chrome_124", "chrome_126", "chrome_127", "chrome_128", "chrome_129",
17
+ "chrome_130", "chrome_131", "chrome_133", "chrome_134", "chrome_135",
18
+ "chrome_136", "chrome_137", "chrome_138", "chrome_139",
19
+ "chrome_140","chrome_141",
20
+ "safari_15.3", "safari_15.5", "safari_15.6.1", "safari_16",
21
+ "safari_16.5", "safari_17.0", "safari_17.2.1", "safari_17.4.1",
22
+ "safari_17.5", "safari_18", "safari_18.2","safari_18.3","safari_18.3.1","safari_18.5",
23
+ "safari_ios_16.5", "safari_ios_17.2", "safari_ios_17.4.1", "safari_ios_18.1.1",
24
+ "safari_ipad_18","safari_26","safari_ipad_26","safari_ios_26",
25
+ "okhttp_3.9", "okhttp_3.11", "okhttp_3.13", "okhttp_3.14", "okhttp_4.9",
26
+ "okhttp_4.10", "okhttp_4.12","okhttp_5",
27
+ "edge_101", "edge_122", "edge_127", "edge_131","edge_134",
28
+ "opera_116", "opera_117", "opera_118", "opera_119",
29
+ "firefox_109", "firefox_117", "firefox_128", "firefox_133", "firefox_135",
30
+ "firefox_136", "firefox_139", "firefox_142", "firefox_143", "firefox_android_135",
31
+ "firefox_private_135", "firefox_private_136",
32
+ "random",
33
+ ] # fmt: skip
34
+ IMPERSONATE_OS = Literal["android", "ios", "linux", "macos", "windows", "random"]
35
+
36
+ class RequestParams(TypedDict, total=False):
37
+ auth: tuple[str, str | None] | None
38
+ auth_bearer: str | None
39
+ params: dict[str, str] | None
40
+ headers: dict[str, str] | None
41
+ cookies: dict[str, str] | None
42
+ timeout: float | None
43
+ content: bytes | None
44
+ data: dict[str, Any] | None
45
+ json: Any | None
46
+ files: dict[str, str] | None
47
+
48
+ class ClientRequestParams(RequestParams):
49
+ impersonate: IMPERSONATE | None
50
+ impersonate_os: IMPERSONATE_OS | None
51
+ verify: bool | None
52
+ ca_cert_file: str | None
53
+
54
+ class Response:
55
+ @property
56
+ def content(self) -> bytes: ...
57
+ @property
58
+ def cookies(self) -> dict[str, str]: ...
59
+ @property
60
+ def headers(self) -> dict[str, str]: ...
61
+ @property
62
+ def status_code(self) -> int: ...
63
+ @property
64
+ def url(self) -> str: ...
65
+ @property
66
+ def encoding(self) -> str: ...
67
+ @property
68
+ def text(self) -> str: ...
69
+ def json(self) -> Any: ...
70
+ def stream(self) -> Iterator[bytes]: ...
71
+ @property
72
+ def text_markdown(self) -> str: ...
73
+ @property
74
+ def text_plain(self) -> str: ...
75
+ @property
76
+ def text_rich(self) -> str: ...
77
+
78
+ class RClient:
79
+ def __init__(
80
+ self,
81
+ auth: tuple[str, str | None] | None = None,
82
+ auth_bearer: str | None = None,
83
+ params: dict[str, str] | None = None,
84
+ headers: dict[str, str] | None = None,
85
+ timeout: float | None = None,
86
+ cookie_store: bool | None = True,
87
+ referer: bool | None = True,
88
+ proxy: str | None = None,
89
+ impersonate: IMPERSONATE | None = None,
90
+ impersonate_os: IMPERSONATE_OS | None = None,
91
+ follow_redirects: bool | None = True,
92
+ max_redirects: int | None = 20,
93
+ verify: bool | None = True,
94
+ ca_cert_file: str | None = None,
95
+ https_only: bool | None = False,
96
+ http2_only: bool | None = False,
97
+ ): ...
98
+ @property
99
+ def headers(self) -> dict[str, str]: ...
100
+ @headers.setter
101
+ def headers(self, headers: dict[str, str]) -> None: ...
102
+ def headers_update(self, headers: dict[str, str]) -> None: ...
103
+ def get_cookies(self, url: str) -> dict[str, str]: ...
104
+ def set_cookies(self, url: str, cookies: dict[str, str]) -> None: ...
105
+ @property
106
+ def proxy(self) -> str | None: ...
107
+ @proxy.setter
108
+ def proxy(self, proxy: str) -> None: ...
109
+ @property
110
+ def impersonate(self) -> str | None: ...
111
+ @impersonate.setter
112
+ def impersonate(self, impersonate: IMPERSONATE) -> None: ...
113
+ @property
114
+ def impersonate_os(self) -> str | None: ...
115
+ @impersonate_os.setter
116
+ def impersonate_os(self, impersonate: IMPERSONATE_OS) -> None: ...
117
+ def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
118
+ def get(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
119
+ def head(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
120
+ def options(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
121
+ def delete(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
122
+ def post(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
123
+ def put(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
124
+ def patch(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
125
+
126
+ def request(method: HttpMethod, url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
127
+ def get(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
128
+ def head(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
129
+ def options(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
130
+ def delete(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
131
+ def post(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
132
+ def put(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
133
+ def patch(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...