Skip to content

Commit 469e261

Browse files
committed
typing: improve
1 parent 5abc8b9 commit 469e261

File tree

2 files changed

+151
-58
lines changed

2 files changed

+151
-58
lines changed

primp/__init__.py

+23-58
Original file line numberDiff line numberDiff line change
@@ -3,53 +3,18 @@
33
import asyncio
44
import sys
55
from functools import partial
6-
from typing import TYPE_CHECKING, Literal, TypedDict
6+
from typing import TYPE_CHECKING, TypedDict
77

88
if sys.version_info <= (3, 11):
99
from typing_extensions import Unpack
1010
else:
1111
from typing import Unpack
1212

13-
from .primp import RClient # type: ignore
1413

15-
if TYPE_CHECKING:
16-
HttpMethod = Literal["GET", "HEAD", "OPTIONS", "DELETE", "POST", "PUT", "PATCH"]
17-
IMPERSONATE = Literal[
18-
"chrome_100", "chrome_101", "chrome_104", "chrome_105", "chrome_106",
19-
"chrome_107", "chrome_108", "chrome_109", "chrome_114", "chrome_116",
20-
"chrome_117", "chrome_118", "chrome_119", "chrome_120", "chrome_123",
21-
"chrome_124", "chrome_126", "chrome_127", "chrome_128", "chrome_129",
22-
"chrome_130", "chrome_131",
23-
"safari_15.3", "safari_15.5", "safari_15.6.1", "safari_16",
24-
"safari_16.5", "safari_17.0", "safari_17.2.1", "safari_17.4.1",
25-
"safari_17.5", "safari_18", "safari_18.2",
26-
"safari_ios_16.5", "safari_ios_17.2", "safari_ios_17.4.1", "safari_ios_18.1.1",
27-
"safari_ipad_18",
28-
"okhttp_3.9", "okhttp_3.11", "okhttp_3.13", "okhttp_3.14", "okhttp_4.9",
29-
"okhttp_4.10", "okhttp_5",
30-
"edge_101", "edge_122", "edge_127", "edge_131",
31-
"firefox_109", "firefox_117", "firefox_128", "firefox_133",
32-
] # fmt: skip
33-
IMPERSONATE_OS = Literal["android", "ios", "linux", "macos", "windows"]
34-
35-
class RequestParams(TypedDict, total=False):
36-
auth: tuple[str, str | None] | None
37-
auth_bearer: str | None
38-
params: dict[str, str] | None
39-
headers: dict[str, str] | None
40-
cookies: dict[str, str] | None
41-
timeout: float | None
42-
content: bytes | None
43-
data: dict[str, str] | None
44-
json: dict[str, str] | None
45-
files: dict[str, str] | None
46-
47-
class ClientRequestParams(RequestParams):
48-
impersonate: IMPERSONATE | None
49-
impersonate_os: IMPERSONATE_OS | None
50-
verify: bool | None
51-
ca_cert_file: str | None
14+
from .primp import RClient
5215

16+
if TYPE_CHECKING:
17+
from .primp import IMPERSONATE, IMPERSONATE_OS, ClientRequestParams, HttpMethod, RequestParams, Response
5318
else:
5419

5520
class _Unpack:
@@ -122,42 +87,42 @@ def __init__(
12287
"""
12388
super().__init__()
12489

125-
def __enter__(self):
90+
def __enter__(self) -> Client:
12691
return self
12792

12893
def __exit__(self, *args):
12994
del self
13095

131-
def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]):
96+
def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]) -> Response:
13297
return super().request(method=method, url=url, **kwargs)
13398

134-
def get(self, url: str, **kwargs: Unpack[RequestParams]):
99+
def get(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
135100
return self.request(method="GET", url=url, **kwargs)
136101

137-
def head(self, url: str, **kwargs: Unpack[RequestParams]):
102+
def head(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
138103
return self.request(method="HEAD", url=url, **kwargs)
139104

140-
def options(self, url: str, **kwargs: Unpack[RequestParams]):
105+
def options(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
141106
return self.request(method="OPTIONS", url=url, **kwargs)
142107

143-
def delete(self, url: str, **kwargs: Unpack[RequestParams]):
108+
def delete(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
144109
return self.request(method="DELETE", url=url, **kwargs)
145110

146-
def post(self, url: str, **kwargs: Unpack[RequestParams]):
111+
def post(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
147112
return self.request(method="POST", url=url, **kwargs)
148113

149-
def put(self, url: str, **kwargs: Unpack[RequestParams]):
114+
def put(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
150115
return self.request(method="PUT", url=url, **kwargs)
151116

152-
def patch(self, url: str, **kwargs: Unpack[RequestParams]):
117+
def patch(self, url: str, **kwargs: Unpack[RequestParams]) -> Response:
153118
return self.request(method="PATCH", url=url, **kwargs)
154119

155120

156121
class AsyncClient(Client):
157122
def __init__(self, *args, **kwargs):
158123
super().__init__(*args, **kwargs)
159124

160-
async def __aenter__(self):
125+
async def __aenter__(self) -> AsyncClient:
161126
return self
162127

163128
async def __aexit__(self, *args):
@@ -167,28 +132,28 @@ async def _run_sync_asyncio(self, fn, *args, **kwargs):
167132
loop = asyncio.get_running_loop()
168133
return await loop.run_in_executor(None, partial(fn, *args, **kwargs))
169134

170-
async def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]):
135+
async def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
171136
return await self._run_sync_asyncio(super().request, method=method, url=url, **kwargs)
172137

173-
async def get(self, url: str, **kwargs: Unpack[RequestParams]):
138+
async def get(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
174139
return await self.request(method="GET", url=url, **kwargs)
175140

176-
async def head(self, url: str, **kwargs: Unpack[RequestParams]):
141+
async def head(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
177142
return await self.request(method="HEAD", url=url, **kwargs)
178143

179-
async def options(self, url: str, **kwargs: Unpack[RequestParams]):
144+
async def options(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
180145
return await self.request(method="OPTIONS", url=url, **kwargs)
181146

182-
async def delete(self, url: str, **kwargs: Unpack[RequestParams]):
147+
async def delete(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
183148
return await self.request(method="DELETE", url=url, **kwargs)
184149

185-
async def post(self, url: str, **kwargs: Unpack[RequestParams]):
150+
async def post(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
186151
return await self.request(method="POST", url=url, **kwargs)
187152

188-
async def put(self, url: str, **kwargs: Unpack[RequestParams]):
153+
async def put(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
189154
return await self.request(method="PUT", url=url, **kwargs)
190155

191-
async def patch(self, url: str, **kwargs: Unpack[RequestParams]):
156+
async def patch(self, url: str, **kwargs: Unpack[RequestParams]): # type: ignore
192157
return await self.request(method="PATCH", url=url, **kwargs)
193158

194159

@@ -230,7 +195,7 @@ def request(
230195
headers: an optional map of HTTP headers to send with requests. If `impersonate` is set, this will be ignored.
231196
cookies: an optional map of cookies to send with requests as the `Cookie` header.
232197
timeout: the timeout for the request in seconds. Default is 30.
233-
content: he content to send in the request body as bytes. Default is None.
198+
content: the content to send in the request body as bytes. Default is None.
234199
data: the form data to send in the request body. Default is None.
235200
json: a JSON serializable object to send in the request body. Default is None.
236201
files: a map of file fields to file paths to be sent as multipart/form-data. Default is None.

primp/primp.pyi

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
from __future__ import annotations
2+
3+
import sys
4+
from typing import Any, 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",
18+
"safari_15.3", "safari_15.5", "safari_15.6.1", "safari_16",
19+
"safari_16.5", "safari_17.0", "safari_17.2.1", "safari_17.4.1",
20+
"safari_17.5", "safari_18", "safari_18.2",
21+
"safari_ios_16.5", "safari_ios_17.2", "safari_ios_17.4.1", "safari_ios_18.1.1",
22+
"safari_ipad_18",
23+
"okhttp_3.9", "okhttp_3.11", "okhttp_3.13", "okhttp_3.14", "okhttp_4.9",
24+
"okhttp_4.10", "okhttp_5",
25+
"edge_101", "edge_122", "edge_127", "edge_131",
26+
"firefox_109", "firefox_117", "firefox_128", "firefox_133",
27+
] # fmt: skip
28+
IMPERSONATE_OS = Literal["android", "ios", "linux", "macos", "windows"]
29+
30+
class RequestParams(TypedDict, total=False):
31+
auth: tuple[str, str | None] | None
32+
auth_bearer: str | None
33+
params: dict[str, str] | None
34+
headers: dict[str, str] | None
35+
cookies: dict[str, str] | None
36+
timeout: float | None
37+
content: bytes | None
38+
data: dict[str, Any] | None
39+
json: Any | None
40+
files: dict[str, str] | None
41+
42+
class ClientRequestParams(RequestParams):
43+
impersonate: IMPERSONATE | None
44+
impersonate_os: IMPERSONATE_OS | None
45+
verify: bool | None
46+
ca_cert_file: str | None
47+
48+
class Response:
49+
@property
50+
def content(self) -> bytes: ...
51+
@property
52+
def cookies(self) -> dict[str, str]: ...
53+
@property
54+
def headers(self) -> dict[str, str]: ...
55+
@property
56+
def status_code(self) -> int: ...
57+
@property
58+
def url(self) -> str: ...
59+
@property
60+
def encoding(self) -> str: ...
61+
@property
62+
def text(self) -> str: ...
63+
def json(self) -> Any: ...
64+
@property
65+
def text_markdown(self) -> str: ...
66+
@property
67+
def text_plain(self) -> str: ...
68+
@property
69+
def text_rich(self) -> str: ...
70+
71+
class RClient:
72+
def __init__(
73+
self,
74+
auth: tuple[str, str | None] | None = None,
75+
auth_bearer: str | None = None,
76+
params: dict[str, str] | None = None,
77+
headers: dict[str, str] | None = None,
78+
cookies: dict[str, str] | None = None,
79+
timeout: float | None = None,
80+
cookie_store: bool | None = True,
81+
referer: bool | None = True,
82+
proxy: str | None = None,
83+
impersonate: IMPERSONATE | None = None,
84+
impersonate_os: IMPERSONATE_OS | None = None,
85+
follow_redirects: bool | None = True,
86+
max_redirects: int | None = 20,
87+
verify: bool | None = True,
88+
ca_cert_file: str | None = None,
89+
https_only: bool | None = False,
90+
http2_only: bool | None = False,
91+
): ...
92+
@property
93+
def headers(self) -> dict[str, str]: ...
94+
@headers.setter
95+
def headers(self, headers: dict[str, str]) -> None: ...
96+
@property
97+
def cookies(self) -> dict[str, str]: ...
98+
@cookies.setter
99+
def cookies(self, cookies: dict[str, str]) -> None: ...
100+
@property
101+
def proxy(self) -> str | None: ...
102+
@proxy.setter
103+
def proxy(self, proxy: str) -> None: ...
104+
@property
105+
def impersonate(self) -> str | None: ...
106+
@impersonate.setter
107+
def impersonate(self, impersonate: IMPERSONATE) -> None: ...
108+
@property
109+
def impersonate_os(self) -> str | None: ...
110+
@impersonate_os.setter
111+
def impersonate_os(self, impersonate: IMPERSONATE_OS) -> None: ...
112+
def request(self, method: HttpMethod, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
113+
def get(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
114+
def head(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
115+
def options(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
116+
def delete(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
117+
def post(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
118+
def put(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
119+
def patch(self, url: str, **kwargs: Unpack[RequestParams]) -> Response: ...
120+
121+
def request(method: HttpMethod, url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
122+
def get(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
123+
def head(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
124+
def options(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
125+
def delete(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
126+
def post(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
127+
def put(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...
128+
def patch(url: str, **kwargs: Unpack[ClientRequestParams]) -> Response: ...

0 commit comments

Comments
 (0)