gapi-requests-auth 0.1.0__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.
@@ -0,0 +1,3 @@
1
+ from .auth import AKSKAuth
2
+
3
+ __all__ = ["AKSKAuth"]
@@ -0,0 +1,92 @@
1
+ # Created by Ci Song @ Damo of Alibaba at 15:57 2026/2/3 using PyCharm
2
+
3
+ import hashlib
4
+ import hmac
5
+ import time
6
+ import uuid
7
+ from urllib.parse import urlsplit, parse_qs
8
+
9
+ import requests
10
+ from requests.auth import AuthBase
11
+
12
+
13
+ def _coalesce(x):
14
+ return "" if x is None else x
15
+
16
+
17
+ def _sha256_hex_bytes(b: bytes) -> str:
18
+ return hashlib.sha256(b).hexdigest()
19
+
20
+
21
+ class AKSKAuth(AuthBase):
22
+
23
+ def __init__(self, ak: str, sk: str, nonce_factory=None, ts_factory=None):
24
+ self.ak = ak
25
+ self.sk = sk
26
+ self.nonce_factory = nonce_factory or (lambda: uuid.uuid4().hex)
27
+ self.ts_factory = ts_factory or (lambda: str(int(time.time())))
28
+
29
+ def __call__(self, r: requests.PreparedRequest):
30
+ # ---- timestamp:优先用请求里已有的 x-request-ts,否则自动补上
31
+ timestamp = r.headers.get("x-request-ts")
32
+ if not timestamp:
33
+ timestamp = self.ts_factory()
34
+ r.headers["x-request-ts"] = timestamp
35
+
36
+ # ---- nonce:每次请求生成
37
+ nonce = self.nonce_factory()
38
+
39
+ # 放 header
40
+ r.headers.setdefault("x-request-ak", self.ak)
41
+ r.headers.setdefault("x-request-nonce", nonce)
42
+
43
+ # ---- path
44
+ u = urlsplit(r.url)
45
+ path = _coalesce(u.path)
46
+
47
+ # ---- parameters:取 query 参数,按 key 排序;同 key 多值用逗号拼接
48
+ params = parse_qs(u.query, keep_blank_values=True)
49
+
50
+ if not params:
51
+ parameter_string_repr = ""
52
+ else:
53
+ items = []
54
+ for k in sorted(params.keys()):
55
+ v_list = params.get(k) or [""]
56
+ v_joined = ",".join([str(v) for v in v_list])
57
+ items.append(f"{k}={v_joined}")
58
+ parameter_string_repr = "&".join(items)
59
+
60
+ # ---- bodyHash:sha256Hex(coalesce(body))
61
+ body = r.body
62
+ if body is None:
63
+ body_bytes = b""
64
+ elif isinstance(body, bytes):
65
+ body_bytes = body
66
+ else:
67
+ body_bytes = str(body).encode("utf-8")
68
+
69
+ body_hash = _sha256_hex_bytes(body_bytes)
70
+
71
+ # ---- method
72
+ method = (r.method or "").upper()
73
+
74
+ # ---- repr 拼接并整体 lower
75
+ repr_str = (
76
+ f"{path}\n"
77
+ f"{parameter_string_repr}\n"
78
+ f"{body_hash}\n"
79
+ f"{method}\n"
80
+ f"{self.ak}\n"
81
+ f"{nonce}\n"
82
+ f"{timestamp}\n"
83
+ f"{self.sk}"
84
+ ).lower()
85
+
86
+ # ---- HMAC-SHA256(key=sk, msg=repr) 然后对 hmacResult 再 sha256Hex
87
+ hmac_bytes = hmac.new(self.sk.encode("utf-8"), repr_str.encode("utf-8"), hashlib.sha256).digest()
88
+ signature = hashlib.sha256(hmac_bytes).hexdigest()
89
+
90
+ r.headers["Authorization"] = "GAPI-SIMPLE-HMAC-SHA256 " + signature
91
+
92
+ return r
File without changes
@@ -0,0 +1,26 @@
1
+ Metadata-Version: 2.4
2
+ Name: gapi-requests-auth
3
+ Version: 0.1.0
4
+ Summary: Requests AuthBase for GAPI simple AK/SK HMAC signing
5
+ Author-email: 舞舟 <songci.sc@alibaba-inc.com>
6
+ License: MIT
7
+ Requires-Python: >=3.10
8
+ Requires-Dist: requests>=2.31.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ # gapi-requests-auth
12
+
13
+ ## Install
14
+ pip install gapi-requests-auth
15
+
16
+ ## Usage
17
+ ```python
18
+ import requests
19
+ from gapi_requests_auth import AKSKAuth
20
+
21
+ s = requests.Session()
22
+ s.auth = AKSKAuth(ak="xxx", sk="yyy")
23
+
24
+ r = s.get("https://example.com/api?x=1")
25
+ print(r.status_code, r.text)
26
+ ```
@@ -0,0 +1,6 @@
1
+ gapi_requests_auth/__init__.py,sha256=m5AdI1FSEE-qNKiZQBZ5GGkOPqlKSWumYpaw8zwlHN8,50
2
+ gapi_requests_auth/auth.py,sha256=2zjZdRT-WcSfc2PnznEItk7n4pCb_m-SmAWdiezUIt0,2789
3
+ gapi_requests_auth/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ gapi_requests_auth-0.1.0.dist-info/METADATA,sha256=_on4AJGPUtxOzX_tJKhAKAhvvgkogw0gj6sD7c3rmpI,559
5
+ gapi_requests_auth-0.1.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
6
+ gapi_requests_auth-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any