pixelarraythirdparty 1.1.7__py3-none-any.whl → 1.1.9__py3-none-any.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.
- pixelarraythirdparty/__init__.py +1 -1
- pixelarraythirdparty/unified_login/__init__.py +18 -2
- pixelarraythirdparty/unified_login/unified_login.py +238 -0
- {pixelarraythirdparty-1.1.7.dist-info → pixelarraythirdparty-1.1.9.dist-info}/METADATA +1 -1
- {pixelarraythirdparty-1.1.7.dist-info → pixelarraythirdparty-1.1.9.dist-info}/RECORD +8 -8
- {pixelarraythirdparty-1.1.7.dist-info → pixelarraythirdparty-1.1.9.dist-info}/WHEEL +0 -0
- {pixelarraythirdparty-1.1.7.dist-info → pixelarraythirdparty-1.1.9.dist-info}/licenses/LICENSE +0 -0
- {pixelarraythirdparty-1.1.7.dist-info → pixelarraythirdparty-1.1.9.dist-info}/top_level.txt +0 -0
pixelarraythirdparty/__init__.py
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
|
-
from .unified_login import
|
|
1
|
+
from .unified_login import (
|
|
2
|
+
GoogleLogin,
|
|
3
|
+
WechatLogin,
|
|
4
|
+
GitHubLogin,
|
|
5
|
+
DouyinLogin,
|
|
6
|
+
GitLabLogin,
|
|
7
|
+
SMSLogin,
|
|
8
|
+
EmailLogin,
|
|
9
|
+
)
|
|
2
10
|
|
|
3
|
-
__all__ = [
|
|
11
|
+
__all__ = [
|
|
12
|
+
"GoogleLogin",
|
|
13
|
+
"WechatLogin",
|
|
14
|
+
"GitHubLogin",
|
|
15
|
+
"DouyinLogin",
|
|
16
|
+
"GitLabLogin",
|
|
17
|
+
"SMSLogin",
|
|
18
|
+
"EmailLogin",
|
|
19
|
+
]
|
|
4
20
|
|
|
@@ -14,6 +14,15 @@ class GoogleLogin(AsyncClient):
|
|
|
14
14
|
```
|
|
15
15
|
google = GoogleLogin(api_key="your_api_key")
|
|
16
16
|
user_info, success = await google.login()
|
|
17
|
+
if success:
|
|
18
|
+
access_token = user_info.get("access_token")
|
|
19
|
+
refresh_token = user_info.get("refresh_token")
|
|
20
|
+
|
|
21
|
+
# 使用refresh_token刷新access_token
|
|
22
|
+
if refresh_token:
|
|
23
|
+
token_data, success = await google.refresh_access_token(refresh_token)
|
|
24
|
+
if success:
|
|
25
|
+
new_access_token = token_data.get("access_token")
|
|
17
26
|
```
|
|
18
27
|
"""
|
|
19
28
|
|
|
@@ -88,6 +97,31 @@ class GoogleLogin(AsyncClient):
|
|
|
88
97
|
|
|
89
98
|
return {}, False
|
|
90
99
|
|
|
100
|
+
async def refresh_access_token(self, refresh_token: str) -> Tuple[Dict, bool]:
|
|
101
|
+
"""
|
|
102
|
+
使用refresh_token刷新access_token
|
|
103
|
+
|
|
104
|
+
:param refresh_token: Google OAuth refresh_token
|
|
105
|
+
:return: 包含新的access_token和可能的refresh_token的字典,以及是否成功的布尔值
|
|
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
|
+
```
|
|
115
|
+
"""
|
|
116
|
+
data, success = await self._request(
|
|
117
|
+
"POST",
|
|
118
|
+
"/api/unified-login/google/refresh-token",
|
|
119
|
+
json={"refresh_token": refresh_token},
|
|
120
|
+
)
|
|
121
|
+
if not success:
|
|
122
|
+
return {}, False
|
|
123
|
+
return data, True
|
|
124
|
+
|
|
91
125
|
|
|
92
126
|
class WechatLogin(AsyncClient):
|
|
93
127
|
"""
|
|
@@ -459,3 +493,207 @@ class GitLabLogin(AsyncClient):
|
|
|
459
493
|
await asyncio.sleep(interval)
|
|
460
494
|
|
|
461
495
|
return {}, False
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
class SMSLogin(AsyncClient):
|
|
499
|
+
"""
|
|
500
|
+
短信验证码登录客户端
|
|
501
|
+
|
|
502
|
+
使用示例:
|
|
503
|
+
```
|
|
504
|
+
sms = SMSLogin(api_key="your_api_key")
|
|
505
|
+
# 发送验证码
|
|
506
|
+
state, success = await sms.send_code(phone="13800138000")
|
|
507
|
+
if success:
|
|
508
|
+
# 验证验证码并登录
|
|
509
|
+
user_info, success = await sms.login(state=state, code="123456")
|
|
510
|
+
```
|
|
511
|
+
"""
|
|
512
|
+
|
|
513
|
+
def __init__(self, api_key: str):
|
|
514
|
+
super().__init__(api_key)
|
|
515
|
+
|
|
516
|
+
async def send_code(self, phone: str) -> Tuple[Optional[str], bool]:
|
|
517
|
+
"""
|
|
518
|
+
发送短信验证码
|
|
519
|
+
|
|
520
|
+
:param phone: 手机号码
|
|
521
|
+
:return: (state, success) state用于后续验证验证码
|
|
522
|
+
"""
|
|
523
|
+
data, success = await self._request(
|
|
524
|
+
"POST", "/api/unified-login/sms/send-code", json={"phone": phone}
|
|
525
|
+
)
|
|
526
|
+
if not success:
|
|
527
|
+
return None, False
|
|
528
|
+
state = data.get("state")
|
|
529
|
+
if not state:
|
|
530
|
+
return None, False
|
|
531
|
+
return state, True
|
|
532
|
+
|
|
533
|
+
async def verify_code(self, state: str, code: str) -> Tuple[Optional[str], bool]:
|
|
534
|
+
"""
|
|
535
|
+
验证短信验证码
|
|
536
|
+
|
|
537
|
+
:param state: 发送验证码时返回的state
|
|
538
|
+
:param code: 验证码
|
|
539
|
+
:return: (state, success) state用于后续等待登录结果
|
|
540
|
+
"""
|
|
541
|
+
data, success = await self._request(
|
|
542
|
+
"POST",
|
|
543
|
+
"/api/unified-login/sms/verify-code",
|
|
544
|
+
json={"state": state, "code": code},
|
|
545
|
+
)
|
|
546
|
+
if not success:
|
|
547
|
+
return None, False
|
|
548
|
+
new_state = data.get("state")
|
|
549
|
+
if not new_state:
|
|
550
|
+
return None, False
|
|
551
|
+
return new_state, True
|
|
552
|
+
|
|
553
|
+
async def _wait_for_login(
|
|
554
|
+
self, state: str, timeout: int
|
|
555
|
+
) -> Tuple[Dict, bool]:
|
|
556
|
+
"""
|
|
557
|
+
等待短信登录结果
|
|
558
|
+
|
|
559
|
+
:param state: 验证验证码时返回的state
|
|
560
|
+
:param timeout: 超时时间(秒)
|
|
561
|
+
"""
|
|
562
|
+
interval = 2
|
|
563
|
+
total_checks = max(1, timeout // interval) if timeout > 0 else 1
|
|
564
|
+
|
|
565
|
+
for _ in range(total_checks):
|
|
566
|
+
status, response = await self._request_raw(
|
|
567
|
+
"POST",
|
|
568
|
+
"/api/unified-login/sms/wait-sms-login",
|
|
569
|
+
json={"state": state},
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
if status == 200 and response.get("success") is True:
|
|
573
|
+
return response.get("data", {}), True
|
|
574
|
+
|
|
575
|
+
if status in (400, 408):
|
|
576
|
+
break
|
|
577
|
+
|
|
578
|
+
await asyncio.sleep(interval)
|
|
579
|
+
|
|
580
|
+
return {}, False
|
|
581
|
+
|
|
582
|
+
async def login(
|
|
583
|
+
self, state: str, code: str, timeout: int = 180
|
|
584
|
+
) -> Tuple[Dict, bool]:
|
|
585
|
+
"""
|
|
586
|
+
验证验证码并等待登录结果
|
|
587
|
+
|
|
588
|
+
:param state: 发送验证码时返回的state
|
|
589
|
+
:param code: 验证码
|
|
590
|
+
:param timeout: 等待登录结果的超时时间(秒)
|
|
591
|
+
:return: (用户信息, 是否成功)
|
|
592
|
+
"""
|
|
593
|
+
new_state, success = await self.verify_code(state, code)
|
|
594
|
+
if not success or not new_state:
|
|
595
|
+
return {}, False
|
|
596
|
+
|
|
597
|
+
return await self._wait_for_login(new_state, timeout)
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
class EmailLogin(AsyncClient):
|
|
601
|
+
"""
|
|
602
|
+
邮箱验证码登录客户端
|
|
603
|
+
|
|
604
|
+
使用示例:
|
|
605
|
+
```
|
|
606
|
+
email = EmailLogin(api_key="your_api_key")
|
|
607
|
+
# 发送验证码
|
|
608
|
+
state, success = await email.send_code(email="user@example.com")
|
|
609
|
+
if success:
|
|
610
|
+
# 验证验证码并登录
|
|
611
|
+
user_info, success = await email.login(state=state, code="123456")
|
|
612
|
+
```
|
|
613
|
+
"""
|
|
614
|
+
|
|
615
|
+
def __init__(self, api_key: str):
|
|
616
|
+
super().__init__(api_key)
|
|
617
|
+
|
|
618
|
+
async def send_code(self, email: str) -> Tuple[Optional[str], bool]:
|
|
619
|
+
"""
|
|
620
|
+
发送邮箱验证码
|
|
621
|
+
|
|
622
|
+
:param email: 邮箱地址
|
|
623
|
+
:return: (state, success) state用于后续验证验证码
|
|
624
|
+
"""
|
|
625
|
+
data, success = await self._request(
|
|
626
|
+
"POST", "/api/unified-login/email/send-code", json={"email": email}
|
|
627
|
+
)
|
|
628
|
+
if not success:
|
|
629
|
+
return None, False
|
|
630
|
+
state = data.get("state")
|
|
631
|
+
if not state:
|
|
632
|
+
return None, False
|
|
633
|
+
return state, True
|
|
634
|
+
|
|
635
|
+
async def verify_code(self, state: str, code: str) -> Tuple[Optional[str], bool]:
|
|
636
|
+
"""
|
|
637
|
+
验证邮箱验证码
|
|
638
|
+
|
|
639
|
+
:param state: 发送验证码时返回的state
|
|
640
|
+
:param code: 验证码
|
|
641
|
+
:return: (state, success) state用于后续等待登录结果
|
|
642
|
+
"""
|
|
643
|
+
data, success = await self._request(
|
|
644
|
+
"POST",
|
|
645
|
+
"/api/unified-login/email/verify-code",
|
|
646
|
+
json={"state": state, "code": code},
|
|
647
|
+
)
|
|
648
|
+
if not success:
|
|
649
|
+
return None, False
|
|
650
|
+
new_state = data.get("state")
|
|
651
|
+
if not new_state:
|
|
652
|
+
return None, False
|
|
653
|
+
return new_state, True
|
|
654
|
+
|
|
655
|
+
async def _wait_for_login(
|
|
656
|
+
self, state: str, timeout: int
|
|
657
|
+
) -> Tuple[Dict, bool]:
|
|
658
|
+
"""
|
|
659
|
+
等待邮箱登录结果
|
|
660
|
+
|
|
661
|
+
:param state: 验证验证码时返回的state
|
|
662
|
+
:param timeout: 超时时间(秒)
|
|
663
|
+
"""
|
|
664
|
+
interval = 2
|
|
665
|
+
total_checks = max(1, timeout // interval) if timeout > 0 else 1
|
|
666
|
+
|
|
667
|
+
for _ in range(total_checks):
|
|
668
|
+
status, response = await self._request_raw(
|
|
669
|
+
"POST",
|
|
670
|
+
"/api/unified-login/email/wait-email-login",
|
|
671
|
+
json={"state": state},
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
if status == 200 and response.get("success") is True:
|
|
675
|
+
return response.get("data", {}), True
|
|
676
|
+
|
|
677
|
+
if status in (400, 408):
|
|
678
|
+
break
|
|
679
|
+
|
|
680
|
+
await asyncio.sleep(interval)
|
|
681
|
+
|
|
682
|
+
return {}, False
|
|
683
|
+
|
|
684
|
+
async def login(
|
|
685
|
+
self, state: str, code: str, timeout: int = 180
|
|
686
|
+
) -> Tuple[Dict, bool]:
|
|
687
|
+
"""
|
|
688
|
+
验证验证码并等待登录结果
|
|
689
|
+
|
|
690
|
+
:param state: 发送验证码时返回的state
|
|
691
|
+
:param code: 验证码
|
|
692
|
+
:param timeout: 等待登录结果的超时时间(秒)
|
|
693
|
+
:return: (用户信息, 是否成功)
|
|
694
|
+
"""
|
|
695
|
+
new_state, success = await self.verify_code(state, code)
|
|
696
|
+
if not success or not new_state:
|
|
697
|
+
return {}, False
|
|
698
|
+
|
|
699
|
+
return await self._wait_for_login(new_state, timeout)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
pixelarraythirdparty/__init__.py,sha256=
|
|
1
|
+
pixelarraythirdparty/__init__.py,sha256=QoYi4YotAITkKgOLFe4a1RtY7dP_SXaSz2ArxGuGC-g,582
|
|
2
2
|
pixelarraythirdparty/client.py,sha256=DY8w2DYsoGQ6cZYqT-FfoovmVd3Ry-aJbJls2Cxat8M,2006
|
|
3
3
|
pixelarraythirdparty/cron/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
pixelarraythirdparty/cron/cron.py,sha256=nv4e2hX_UkEJ-kbEARbInU2J6aREyYZ61dZ-4b9UWJI,3146
|
|
@@ -10,12 +10,12 @@ pixelarraythirdparty/product/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
|
|
|
10
10
|
pixelarraythirdparty/product/product.py,sha256=5fgv2Ck860epYXxipY83vePziubCIlocFu43mGt_bhM,7497
|
|
11
11
|
pixelarraythirdparty/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
pixelarraythirdparty/project/project.py,sha256=a8swjckyn4y3NlIx0-tMbcRwDY9woOijGi7lb1wN7Ok,2455
|
|
13
|
-
pixelarraythirdparty/unified_login/__init__.py,sha256=
|
|
14
|
-
pixelarraythirdparty/unified_login/unified_login.py,sha256=
|
|
13
|
+
pixelarraythirdparty/unified_login/__init__.py,sha256=_PeHBsyrPLfcNjbdcsBgQ_75fr1CoRZCNu7S33fsh_Y,291
|
|
14
|
+
pixelarraythirdparty/unified_login/unified_login.py,sha256=Rh0EVxvQkTKOGZN9092JxVeGbD2OQ7L2Zvy4M4BlgXI,21559
|
|
15
15
|
pixelarraythirdparty/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
pixelarraythirdparty/user/user.py,sha256=v018iisB5AQNs7AtrHIGfu8YIorX0vflDClsKrt3ZMU,5898
|
|
17
|
-
pixelarraythirdparty-1.1.
|
|
18
|
-
pixelarraythirdparty-1.1.
|
|
19
|
-
pixelarraythirdparty-1.1.
|
|
20
|
-
pixelarraythirdparty-1.1.
|
|
21
|
-
pixelarraythirdparty-1.1.
|
|
17
|
+
pixelarraythirdparty-1.1.9.dist-info/licenses/LICENSE,sha256=O-g1dUr0U50rSIvmWE9toiVkSgFpVt72_MHITbWvAqA,1067
|
|
18
|
+
pixelarraythirdparty-1.1.9.dist-info/METADATA,sha256=6nk6d65Q13hI39JUzL-MCOS_AyPOSnho1zngzOqY1Lk,993
|
|
19
|
+
pixelarraythirdparty-1.1.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
20
|
+
pixelarraythirdparty-1.1.9.dist-info/top_level.txt,sha256=dzG2Ut8j7noUqj_0ZQjcIDAeHYCh_9WtlxjAxtoyufo,21
|
|
21
|
+
pixelarraythirdparty-1.1.9.dist-info/RECORD,,
|
|
File without changes
|
{pixelarraythirdparty-1.1.7.dist-info → pixelarraythirdparty-1.1.9.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|