pixelarraythirdparty 1.1.9__tar.gz → 1.2.0__tar.gz
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.
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/PKG-INFO +1 -1
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/__init__.py +1 -1
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/client.py +28 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/feedback/feedback.py +8 -1
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/order/order.py +33 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/unified_login/unified_login.py +166 -106
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/user/user.py +0 -3
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/PKG-INFO +1 -1
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pyproject.toml +1 -1
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/LICENSE +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/MANIFEST.in +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/cron/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/cron/cron.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/feedback/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/order/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/product/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/product/product.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/project/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/project/project.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/unified_login/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/user/__init__.py +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/SOURCES.txt +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/dependency_links.txt +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/requires.txt +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/top_level.txt +0 -0
- {pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/setup.cfg +0 -0
|
@@ -4,6 +4,12 @@ from typing import Dict, Any, Tuple
|
|
|
4
4
|
|
|
5
5
|
class AsyncClient:
|
|
6
6
|
def __init__(self, api_key: str):
|
|
7
|
+
"""
|
|
8
|
+
description:
|
|
9
|
+
初始化异步客户端
|
|
10
|
+
parameters:
|
|
11
|
+
api_key(str): API密钥,用于身份验证
|
|
12
|
+
"""
|
|
7
13
|
self.base_url = "https://thirdparty.pixelarrayai.com"
|
|
8
14
|
self.api_key = api_key
|
|
9
15
|
self.headers = {
|
|
@@ -14,6 +20,17 @@ class AsyncClient:
|
|
|
14
20
|
async def _request(
|
|
15
21
|
self, method: str, url: str, **kwargs
|
|
16
22
|
) -> Tuple[Dict[str, Any], bool]:
|
|
23
|
+
"""
|
|
24
|
+
description:
|
|
25
|
+
发送异步HTTP请求的通用方法
|
|
26
|
+
parameters:
|
|
27
|
+
method(str): HTTP方法,如"GET"、"POST"、"PUT"、"DELETE"等
|
|
28
|
+
url(str): 请求URL路径(相对于base_url)
|
|
29
|
+
**kwargs: 其他请求参数,如json、params、headers等
|
|
30
|
+
return:
|
|
31
|
+
data(Dict[str, Any]): 响应数据字典,如果请求失败则返回空字典
|
|
32
|
+
success(bool): 请求是否成功
|
|
33
|
+
"""
|
|
17
34
|
# 如果kwargs中有headers,则合并headers
|
|
18
35
|
headers = self.headers.copy()
|
|
19
36
|
if "headers" in kwargs:
|
|
@@ -38,6 +55,17 @@ class AsyncClient:
|
|
|
38
55
|
async def _request_raw(
|
|
39
56
|
self, method: str, url: str, **kwargs
|
|
40
57
|
) -> Tuple[int, Dict[str, Any]]:
|
|
58
|
+
"""
|
|
59
|
+
description:
|
|
60
|
+
发送异步HTTP请求的原始方法,返回完整的HTTP状态码和响应数据
|
|
61
|
+
parameters:
|
|
62
|
+
method(str): HTTP方法,如"GET"、"POST"、"PUT"、"DELETE"等
|
|
63
|
+
url(str): 请求URL路径(相对于base_url)
|
|
64
|
+
**kwargs: 其他请求参数,如json、params、headers等
|
|
65
|
+
return:
|
|
66
|
+
status_code(int): HTTP状态码
|
|
67
|
+
data(Dict[str, Any]): 响应数据字典,如果解析失败则返回空字典
|
|
68
|
+
"""
|
|
41
69
|
headers = self.headers.copy()
|
|
42
70
|
if "headers" in kwargs:
|
|
43
71
|
headers.update(kwargs["headers"])
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/feedback/feedback.py
RENAMED
|
@@ -68,7 +68,14 @@ class FeedbackManagerAsync(AsyncClient):
|
|
|
68
68
|
file_type: str,
|
|
69
69
|
):
|
|
70
70
|
"""
|
|
71
|
-
|
|
71
|
+
description:
|
|
72
|
+
内部方法:上传文件到OSS
|
|
73
|
+
parameters:
|
|
74
|
+
feedback_id(int): 反馈ID
|
|
75
|
+
file_data(Union[str, BinaryIO, bytes]): 文件数据,可以是文件路径、文件对象或字节数据
|
|
76
|
+
file_type(str): 文件类型,可选值:"image"(图片)、"video"(视频)
|
|
77
|
+
return:
|
|
78
|
+
success(bool): 上传是否成功
|
|
72
79
|
"""
|
|
73
80
|
# 读取文件数据
|
|
74
81
|
file_content = None
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/order/order.py
RENAMED
|
@@ -43,6 +43,39 @@ class OrderManagerAsync(AsyncClient):
|
|
|
43
43
|
return {}, False
|
|
44
44
|
return data, True
|
|
45
45
|
|
|
46
|
+
async def create_order_v2(
|
|
47
|
+
self,
|
|
48
|
+
product_id: str,
|
|
49
|
+
body: str = None,
|
|
50
|
+
remark: str = None,
|
|
51
|
+
payment_channel: str = "WECHAT",
|
|
52
|
+
):
|
|
53
|
+
"""
|
|
54
|
+
description:
|
|
55
|
+
创建订单并直接返回支付二维码(V2,推荐)。
|
|
56
|
+
相比旧流程(create_order + generate_qr_code),该接口一次请求完成下单和二维码链接生成。
|
|
57
|
+
parameters:
|
|
58
|
+
product_id(str): 产品ID
|
|
59
|
+
body(str): 商品描述
|
|
60
|
+
remark(str): 订单备注
|
|
61
|
+
payment_channel(str): 支付渠道,可选值:"WECHAT"、"ALIPAY"、"PAYPAL"
|
|
62
|
+
return:
|
|
63
|
+
data(dict): 返回数据
|
|
64
|
+
- order(dict): 订单信息(字段同 create_order 返回)
|
|
65
|
+
- qr_code_url(str): 支付二维码图片URL
|
|
66
|
+
success(bool): 操作是否成功
|
|
67
|
+
"""
|
|
68
|
+
data = {
|
|
69
|
+
"product_id": product_id,
|
|
70
|
+
"body": body,
|
|
71
|
+
"remark": remark,
|
|
72
|
+
"payment_channel": payment_channel,
|
|
73
|
+
}
|
|
74
|
+
data, success = await self._request("POST", "/api/orders/create_v2", json=data)
|
|
75
|
+
if not success:
|
|
76
|
+
return {}, False
|
|
77
|
+
return data, True
|
|
78
|
+
|
|
46
79
|
async def list_order(
|
|
47
80
|
self,
|
|
48
81
|
page: int = 1,
|
|
@@ -30,6 +30,13 @@ class GoogleLogin(AsyncClient):
|
|
|
30
30
|
super().__init__(api_key)
|
|
31
31
|
|
|
32
32
|
async def _get_auth_url(self) -> Tuple[Optional[Dict[str, str]], bool]:
|
|
33
|
+
"""
|
|
34
|
+
description:
|
|
35
|
+
获取Google OAuth授权URL
|
|
36
|
+
return:
|
|
37
|
+
auth_data(dict, optional): 授权数据字典,包含auth_url和state
|
|
38
|
+
success(bool): 是否成功
|
|
39
|
+
"""
|
|
33
40
|
data, success = await self._request(
|
|
34
41
|
"POST", "/api/unified-login/google/auth-url"
|
|
35
42
|
)
|
|
@@ -42,10 +49,13 @@ class GoogleLogin(AsyncClient):
|
|
|
42
49
|
|
|
43
50
|
async def login(self, timeout: int = 180) -> Tuple[Dict, bool]:
|
|
44
51
|
"""
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
52
|
+
description:
|
|
53
|
+
仿 Supabase CLI 的一键登录流程:打开浏览器完成授权,终端端轮询等待登录结果
|
|
54
|
+
parameters:
|
|
55
|
+
timeout(int, optional): 等待用户完成授权的超时时间(秒),默认为180
|
|
56
|
+
return:
|
|
57
|
+
user_info(dict): 用户信息字典
|
|
58
|
+
success(bool): 是否成功
|
|
49
59
|
"""
|
|
50
60
|
auth_data, success = await self._get_auth_url()
|
|
51
61
|
if not success or not auth_data:
|
|
@@ -77,6 +87,16 @@ class GoogleLogin(AsyncClient):
|
|
|
77
87
|
async def _wait_for_google_login(
|
|
78
88
|
self, state: str, timeout: int
|
|
79
89
|
) -> Tuple[Dict, bool]:
|
|
90
|
+
"""
|
|
91
|
+
description:
|
|
92
|
+
等待Google登录结果,轮询检查登录状态
|
|
93
|
+
parameters:
|
|
94
|
+
state(str): 登录状态标识
|
|
95
|
+
timeout(int): 超时时间(秒)
|
|
96
|
+
return:
|
|
97
|
+
user_info(dict): 用户信息字典
|
|
98
|
+
success(bool): 是否成功
|
|
99
|
+
"""
|
|
80
100
|
interval = 2
|
|
81
101
|
total_checks = max(1, timeout // interval) if timeout > 0 else 1
|
|
82
102
|
|
|
@@ -99,19 +119,13 @@ class GoogleLogin(AsyncClient):
|
|
|
99
119
|
|
|
100
120
|
async def refresh_access_token(self, refresh_token: str) -> Tuple[Dict, bool]:
|
|
101
121
|
"""
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
google = GoogleLogin(api_key="your_api_key")
|
|
110
|
-
token_data, success = await google.refresh_access_token(refresh_token="your_refresh_token")
|
|
111
|
-
if success:
|
|
112
|
-
new_access_token = token_data.get("access_token")
|
|
113
|
-
new_refresh_token = token_data.get("refresh_token") # 可能为None
|
|
114
|
-
```
|
|
122
|
+
description:
|
|
123
|
+
使用refresh_token刷新access_token
|
|
124
|
+
parameters:
|
|
125
|
+
refresh_token(str): Google OAuth refresh_token
|
|
126
|
+
return:
|
|
127
|
+
token_data(dict): 包含新的access_token和可能的refresh_token的字典
|
|
128
|
+
success(bool): 是否成功
|
|
115
129
|
"""
|
|
116
130
|
data, success = await self._request(
|
|
117
131
|
"POST",
|
|
@@ -146,9 +160,13 @@ class WechatLogin(AsyncClient):
|
|
|
146
160
|
|
|
147
161
|
async def _get_auth_url(self, login_type: str = "desktop") -> Tuple[Optional[Dict[str, str]], bool]:
|
|
148
162
|
"""
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
:
|
|
163
|
+
description:
|
|
164
|
+
获取微信授权URL
|
|
165
|
+
parameters:
|
|
166
|
+
login_type(str, optional): 登录类型,desktop表示PC端扫码登录,mobile表示微信公众号登录,默认为desktop
|
|
167
|
+
return:
|
|
168
|
+
auth_data(dict, optional): 授权数据字典,包含auth_url和state
|
|
169
|
+
success(bool): 是否成功
|
|
152
170
|
"""
|
|
153
171
|
if login_type == "mobile":
|
|
154
172
|
# 微信公众号OAuth登录(手机端)
|
|
@@ -167,20 +185,14 @@ class WechatLogin(AsyncClient):
|
|
|
167
185
|
|
|
168
186
|
async def login(self, login_type: str = "desktop", timeout: int = 180) -> Tuple[Dict, bool]:
|
|
169
187
|
"""
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
wechat = WechatLogin(api_key="your_api_key")
|
|
179
|
-
# PC端扫码登录
|
|
180
|
-
user_info, success = await wechat.login(login_type="desktop")
|
|
181
|
-
# 微信公众号登录(手机端)
|
|
182
|
-
user_info, success = await wechat.login(login_type="mobile")
|
|
183
|
-
```
|
|
188
|
+
description:
|
|
189
|
+
仿 Supabase CLI 的一键登录流程:打开浏览器完成授权,终端端轮询等待登录结果
|
|
190
|
+
parameters:
|
|
191
|
+
login_type(str, optional): 登录类型,desktop表示PC端扫码登录,mobile表示微信公众号登录,默认为desktop
|
|
192
|
+
timeout(int, optional): 等待用户完成授权的超时时间(秒),默认为180
|
|
193
|
+
return:
|
|
194
|
+
user_info(dict): 用户信息字典
|
|
195
|
+
success(bool): 是否成功
|
|
184
196
|
"""
|
|
185
197
|
auth_data, success = await self._get_auth_url(login_type)
|
|
186
198
|
if not success or not auth_data:
|
|
@@ -197,6 +209,14 @@ class WechatLogin(AsyncClient):
|
|
|
197
209
|
return await self._wait_for_wechat_login(state, timeout, login_type)
|
|
198
210
|
|
|
199
211
|
def _extract_state(self, auth_url: Optional[str]) -> Optional[str]:
|
|
212
|
+
"""
|
|
213
|
+
description:
|
|
214
|
+
从授权URL中提取state参数
|
|
215
|
+
parameters:
|
|
216
|
+
auth_url(str, optional): 授权URL
|
|
217
|
+
return:
|
|
218
|
+
state(str, optional): state参数值,如果提取失败则返回None
|
|
219
|
+
"""
|
|
200
220
|
if not auth_url:
|
|
201
221
|
return None
|
|
202
222
|
try:
|
|
@@ -213,11 +233,15 @@ class WechatLogin(AsyncClient):
|
|
|
213
233
|
self, state: str, timeout: int, login_type: str = "desktop"
|
|
214
234
|
) -> Tuple[Dict, bool]:
|
|
215
235
|
"""
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
:
|
|
219
|
-
|
|
220
|
-
|
|
236
|
+
description:
|
|
237
|
+
等待微信登录结果,轮询检查登录状态
|
|
238
|
+
parameters:
|
|
239
|
+
state(str): 登录状态标识
|
|
240
|
+
timeout(int): 超时时间(秒)
|
|
241
|
+
login_type(str, optional): 登录类型,desktop表示PC端扫码登录,mobile表示微信公众号登录,默认为desktop
|
|
242
|
+
return:
|
|
243
|
+
user_info(dict): 用户信息字典
|
|
244
|
+
success(bool): 是否成功
|
|
221
245
|
"""
|
|
222
246
|
interval = 2
|
|
223
247
|
total_checks = max(1, timeout // interval) if timeout > 0 else 1
|
|
@@ -261,6 +285,13 @@ class GitHubLogin(AsyncClient):
|
|
|
261
285
|
super().__init__(api_key)
|
|
262
286
|
|
|
263
287
|
async def _get_auth_url(self) -> Tuple[Optional[Dict[str, str]], bool]:
|
|
288
|
+
"""
|
|
289
|
+
description:
|
|
290
|
+
获取GitHub OAuth授权URL
|
|
291
|
+
return:
|
|
292
|
+
auth_data(dict, optional): 授权数据字典,包含auth_url和state
|
|
293
|
+
success(bool): 是否成功
|
|
294
|
+
"""
|
|
264
295
|
data, success = await self._request(
|
|
265
296
|
"POST", "/api/unified-login/github/auth-url"
|
|
266
297
|
)
|
|
@@ -273,10 +304,13 @@ class GitHubLogin(AsyncClient):
|
|
|
273
304
|
|
|
274
305
|
async def login(self, timeout: int = 180) -> Tuple[Dict, bool]:
|
|
275
306
|
"""
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
307
|
+
description:
|
|
308
|
+
仿 Supabase CLI 的一键登录流程:打开浏览器完成授权,终端端轮询等待登录结果
|
|
309
|
+
parameters:
|
|
310
|
+
timeout(int, optional): 等待用户完成授权的超时时间(秒),默认为180
|
|
311
|
+
return:
|
|
312
|
+
user_info(dict): 用户信息字典
|
|
313
|
+
success(bool): 是否成功
|
|
280
314
|
"""
|
|
281
315
|
auth_data, success = await self._get_auth_url()
|
|
282
316
|
if not success or not auth_data:
|
|
@@ -293,6 +327,14 @@ class GitHubLogin(AsyncClient):
|
|
|
293
327
|
return await self._wait_for_github_login(state, timeout)
|
|
294
328
|
|
|
295
329
|
def _extract_state(self, auth_url: Optional[str]) -> Optional[str]:
|
|
330
|
+
"""
|
|
331
|
+
description:
|
|
332
|
+
从授权URL中提取state参数
|
|
333
|
+
parameters:
|
|
334
|
+
auth_url(str, optional): 授权URL
|
|
335
|
+
return:
|
|
336
|
+
state(str, optional): state参数值,如果提取失败则返回None
|
|
337
|
+
"""
|
|
296
338
|
if not auth_url:
|
|
297
339
|
return None
|
|
298
340
|
try:
|
|
@@ -308,6 +350,16 @@ class GitHubLogin(AsyncClient):
|
|
|
308
350
|
async def _wait_for_github_login(
|
|
309
351
|
self, state: str, timeout: int
|
|
310
352
|
) -> Tuple[Dict, bool]:
|
|
353
|
+
"""
|
|
354
|
+
description:
|
|
355
|
+
等待GitHub登录结果,轮询检查登录状态
|
|
356
|
+
parameters:
|
|
357
|
+
state(str): 登录状态标识
|
|
358
|
+
timeout(int): 超时时间(秒)
|
|
359
|
+
return:
|
|
360
|
+
user_info(dict): 用户信息字典
|
|
361
|
+
success(bool): 是否成功
|
|
362
|
+
"""
|
|
311
363
|
interval = 2
|
|
312
364
|
total_checks = max(1, timeout // interval) if timeout > 0 else 1
|
|
313
365
|
|
|
@@ -344,6 +396,13 @@ class DouyinLogin(AsyncClient):
|
|
|
344
396
|
super().__init__(api_key)
|
|
345
397
|
|
|
346
398
|
async def _get_auth_url(self) -> Tuple[Optional[Dict[str, str]], bool]:
|
|
399
|
+
"""
|
|
400
|
+
description:
|
|
401
|
+
获取抖音OAuth授权URL
|
|
402
|
+
return:
|
|
403
|
+
auth_data(dict, optional): 授权数据字典,包含auth_url和state
|
|
404
|
+
success(bool): 是否成功
|
|
405
|
+
"""
|
|
347
406
|
data, success = await self._request(
|
|
348
407
|
"POST", "/api/unified-login/douyin/auth-url"
|
|
349
408
|
)
|
|
@@ -356,10 +415,13 @@ class DouyinLogin(AsyncClient):
|
|
|
356
415
|
|
|
357
416
|
async def login(self, timeout: int = 180) -> Tuple[Dict, bool]:
|
|
358
417
|
"""
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
418
|
+
description:
|
|
419
|
+
仿 Supabase CLI 的一键登录流程:打开浏览器完成授权,终端端轮询等待登录结果
|
|
420
|
+
parameters:
|
|
421
|
+
timeout(int, optional): 等待用户完成授权的超时时间(秒),默认为180
|
|
422
|
+
return:
|
|
423
|
+
user_info(dict): 用户信息字典
|
|
424
|
+
success(bool): 是否成功
|
|
363
425
|
"""
|
|
364
426
|
auth_data, success = await self._get_auth_url()
|
|
365
427
|
if not success or not auth_data:
|
|
@@ -376,6 +438,14 @@ class DouyinLogin(AsyncClient):
|
|
|
376
438
|
return await self._wait_for_douyin_login(state, timeout)
|
|
377
439
|
|
|
378
440
|
def _extract_state(self, auth_url: Optional[str]) -> Optional[str]:
|
|
441
|
+
"""
|
|
442
|
+
description:
|
|
443
|
+
从授权URL中提取state参数
|
|
444
|
+
parameters:
|
|
445
|
+
auth_url(str, optional): 授权URL
|
|
446
|
+
return:
|
|
447
|
+
state(str, optional): state参数值,如果提取失败则返回None
|
|
448
|
+
"""
|
|
379
449
|
if not auth_url:
|
|
380
450
|
return None
|
|
381
451
|
try:
|
|
@@ -391,6 +461,16 @@ class DouyinLogin(AsyncClient):
|
|
|
391
461
|
async def _wait_for_douyin_login(
|
|
392
462
|
self, state: str, timeout: int
|
|
393
463
|
) -> Tuple[Dict, bool]:
|
|
464
|
+
"""
|
|
465
|
+
description:
|
|
466
|
+
等待抖音登录结果,轮询检查登录状态
|
|
467
|
+
parameters:
|
|
468
|
+
state(str): 登录状态标识
|
|
469
|
+
timeout(int): 超时时间(秒)
|
|
470
|
+
return:
|
|
471
|
+
user_info(dict): 用户信息字典
|
|
472
|
+
success(bool): 是否成功
|
|
473
|
+
"""
|
|
394
474
|
interval = 2
|
|
395
475
|
total_checks = max(1, timeout // interval) if timeout > 0 else 1
|
|
396
476
|
|
|
@@ -503,60 +583,50 @@ class SMSLogin(AsyncClient):
|
|
|
503
583
|
```
|
|
504
584
|
sms = SMSLogin(api_key="your_api_key")
|
|
505
585
|
# 发送验证码
|
|
506
|
-
|
|
586
|
+
success = await sms.send_code(phone="13800138000")
|
|
507
587
|
if success:
|
|
508
588
|
# 验证验证码并登录
|
|
509
|
-
user_info, success = await sms.login(
|
|
589
|
+
user_info, success = await sms.login(phone="13800138000", code="123456")
|
|
510
590
|
```
|
|
511
591
|
"""
|
|
512
592
|
|
|
513
593
|
def __init__(self, api_key: str):
|
|
514
594
|
super().__init__(api_key)
|
|
515
595
|
|
|
516
|
-
async def send_code(self, phone: str) ->
|
|
596
|
+
async def send_code(self, phone: str) -> bool:
|
|
517
597
|
"""
|
|
518
598
|
发送短信验证码
|
|
519
599
|
|
|
520
600
|
:param phone: 手机号码
|
|
521
|
-
:return:
|
|
601
|
+
:return: success 是否成功
|
|
522
602
|
"""
|
|
523
603
|
data, success = await self._request(
|
|
524
604
|
"POST", "/api/unified-login/sms/send-code", json={"phone": phone}
|
|
525
605
|
)
|
|
526
|
-
|
|
527
|
-
return None, False
|
|
528
|
-
state = data.get("state")
|
|
529
|
-
if not state:
|
|
530
|
-
return None, False
|
|
531
|
-
return state, True
|
|
606
|
+
return bool(success)
|
|
532
607
|
|
|
533
|
-
async def verify_code(self,
|
|
608
|
+
async def verify_code(self, phone: str, code: str) -> bool:
|
|
534
609
|
"""
|
|
535
610
|
验证短信验证码
|
|
536
611
|
|
|
537
|
-
:param
|
|
612
|
+
:param phone: 手机号码
|
|
538
613
|
:param code: 验证码
|
|
539
|
-
:return:
|
|
614
|
+
:return: success 是否成功
|
|
540
615
|
"""
|
|
541
|
-
|
|
616
|
+
_, success = await self._request(
|
|
542
617
|
"POST",
|
|
543
618
|
"/api/unified-login/sms/verify-code",
|
|
544
|
-
json={"
|
|
619
|
+
json={"phone": phone, "code": code},
|
|
545
620
|
)
|
|
546
|
-
|
|
547
|
-
return None, False
|
|
548
|
-
new_state = data.get("state")
|
|
549
|
-
if not new_state:
|
|
550
|
-
return None, False
|
|
551
|
-
return new_state, True
|
|
621
|
+
return bool(success)
|
|
552
622
|
|
|
553
623
|
async def _wait_for_login(
|
|
554
|
-
self,
|
|
624
|
+
self, phone: str, timeout: int
|
|
555
625
|
) -> Tuple[Dict, bool]:
|
|
556
626
|
"""
|
|
557
627
|
等待短信登录结果
|
|
558
628
|
|
|
559
|
-
:param
|
|
629
|
+
:param phone: 手机号码
|
|
560
630
|
:param timeout: 超时时间(秒)
|
|
561
631
|
"""
|
|
562
632
|
interval = 2
|
|
@@ -566,7 +636,7 @@ class SMSLogin(AsyncClient):
|
|
|
566
636
|
status, response = await self._request_raw(
|
|
567
637
|
"POST",
|
|
568
638
|
"/api/unified-login/sms/wait-sms-login",
|
|
569
|
-
json={"
|
|
639
|
+
json={"phone": phone},
|
|
570
640
|
)
|
|
571
641
|
|
|
572
642
|
if status == 200 and response.get("success") is True:
|
|
@@ -580,21 +650,21 @@ class SMSLogin(AsyncClient):
|
|
|
580
650
|
return {}, False
|
|
581
651
|
|
|
582
652
|
async def login(
|
|
583
|
-
self,
|
|
653
|
+
self, phone: str, code: str, timeout: int = 180
|
|
584
654
|
) -> Tuple[Dict, bool]:
|
|
585
655
|
"""
|
|
586
656
|
验证验证码并等待登录结果
|
|
587
657
|
|
|
588
|
-
:param
|
|
658
|
+
:param phone: 手机号码
|
|
589
659
|
:param code: 验证码
|
|
590
660
|
:param timeout: 等待登录结果的超时时间(秒)
|
|
591
661
|
:return: (用户信息, 是否成功)
|
|
592
662
|
"""
|
|
593
|
-
|
|
594
|
-
if not success
|
|
663
|
+
success = await self.verify_code(phone, code)
|
|
664
|
+
if not success:
|
|
595
665
|
return {}, False
|
|
596
666
|
|
|
597
|
-
return await self._wait_for_login(
|
|
667
|
+
return await self._wait_for_login(phone, timeout)
|
|
598
668
|
|
|
599
669
|
|
|
600
670
|
class EmailLogin(AsyncClient):
|
|
@@ -605,60 +675,50 @@ class EmailLogin(AsyncClient):
|
|
|
605
675
|
```
|
|
606
676
|
email = EmailLogin(api_key="your_api_key")
|
|
607
677
|
# 发送验证码
|
|
608
|
-
|
|
678
|
+
success = await email.send_code(email="user@example.com")
|
|
609
679
|
if success:
|
|
610
680
|
# 验证验证码并登录
|
|
611
|
-
user_info, success = await email.login(
|
|
681
|
+
user_info, success = await email.login(email="user@example.com", code="123456")
|
|
612
682
|
```
|
|
613
683
|
"""
|
|
614
684
|
|
|
615
685
|
def __init__(self, api_key: str):
|
|
616
686
|
super().__init__(api_key)
|
|
617
687
|
|
|
618
|
-
async def send_code(self, email: str) ->
|
|
688
|
+
async def send_code(self, email: str) -> bool:
|
|
619
689
|
"""
|
|
620
690
|
发送邮箱验证码
|
|
621
691
|
|
|
622
692
|
:param email: 邮箱地址
|
|
623
|
-
:return:
|
|
693
|
+
:return: success 是否成功
|
|
624
694
|
"""
|
|
625
|
-
|
|
695
|
+
_, success = await self._request(
|
|
626
696
|
"POST", "/api/unified-login/email/send-code", json={"email": email}
|
|
627
697
|
)
|
|
628
|
-
|
|
629
|
-
return None, False
|
|
630
|
-
state = data.get("state")
|
|
631
|
-
if not state:
|
|
632
|
-
return None, False
|
|
633
|
-
return state, True
|
|
698
|
+
return bool(success)
|
|
634
699
|
|
|
635
|
-
async def verify_code(self,
|
|
700
|
+
async def verify_code(self, email: str, code: str) -> bool:
|
|
636
701
|
"""
|
|
637
702
|
验证邮箱验证码
|
|
638
703
|
|
|
639
|
-
:param
|
|
704
|
+
:param email: 邮箱地址
|
|
640
705
|
:param code: 验证码
|
|
641
|
-
:return:
|
|
706
|
+
:return: success 是否成功
|
|
642
707
|
"""
|
|
643
|
-
|
|
708
|
+
_, success = await self._request(
|
|
644
709
|
"POST",
|
|
645
710
|
"/api/unified-login/email/verify-code",
|
|
646
|
-
json={"
|
|
711
|
+
json={"email": email, "code": code},
|
|
647
712
|
)
|
|
648
|
-
|
|
649
|
-
return None, False
|
|
650
|
-
new_state = data.get("state")
|
|
651
|
-
if not new_state:
|
|
652
|
-
return None, False
|
|
653
|
-
return new_state, True
|
|
713
|
+
return bool(success)
|
|
654
714
|
|
|
655
715
|
async def _wait_for_login(
|
|
656
|
-
self,
|
|
716
|
+
self, email: str, timeout: int
|
|
657
717
|
) -> Tuple[Dict, bool]:
|
|
658
718
|
"""
|
|
659
719
|
等待邮箱登录结果
|
|
660
720
|
|
|
661
|
-
:param
|
|
721
|
+
:param email: 邮箱地址
|
|
662
722
|
:param timeout: 超时时间(秒)
|
|
663
723
|
"""
|
|
664
724
|
interval = 2
|
|
@@ -668,7 +728,7 @@ class EmailLogin(AsyncClient):
|
|
|
668
728
|
status, response = await self._request_raw(
|
|
669
729
|
"POST",
|
|
670
730
|
"/api/unified-login/email/wait-email-login",
|
|
671
|
-
json={"
|
|
731
|
+
json={"email": email},
|
|
672
732
|
)
|
|
673
733
|
|
|
674
734
|
if status == 200 and response.get("success") is True:
|
|
@@ -682,18 +742,18 @@ class EmailLogin(AsyncClient):
|
|
|
682
742
|
return {}, False
|
|
683
743
|
|
|
684
744
|
async def login(
|
|
685
|
-
self,
|
|
745
|
+
self, email: str, code: str, timeout: int = 180
|
|
686
746
|
) -> Tuple[Dict, bool]:
|
|
687
747
|
"""
|
|
688
748
|
验证验证码并等待登录结果
|
|
689
749
|
|
|
690
|
-
:param
|
|
750
|
+
:param email: 邮箱地址
|
|
691
751
|
:param code: 验证码
|
|
692
752
|
:param timeout: 等待登录结果的超时时间(秒)
|
|
693
753
|
:return: (用户信息, 是否成功)
|
|
694
754
|
"""
|
|
695
|
-
|
|
696
|
-
if not success
|
|
755
|
+
success = await self.verify_code(email, code)
|
|
756
|
+
if not success:
|
|
697
757
|
return {}, False
|
|
698
758
|
|
|
699
|
-
return await self._wait_for_login(
|
|
759
|
+
return await self._wait_for_login(email, timeout)
|
|
File without changes
|
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/cron/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/feedback/__init__.py
RENAMED
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/order/__init__.py
RENAMED
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/product/__init__.py
RENAMED
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/product/product.py
RENAMED
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/project/__init__.py
RENAMED
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/project/project.py
RENAMED
|
File without changes
|
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty/user/__init__.py
RENAMED
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{pixelarraythirdparty-1.1.9 → pixelarraythirdparty-1.2.0}/pixelarraythirdparty.egg-info/requires.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|