huace-aigc-auth-client 1.1.19__tar.gz → 1.1.21__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.
- {huace_aigc_auth_client-1.1.19/huace_aigc_auth_client.egg-info → huace_aigc_auth_client-1.1.21}/PKG-INFO +1 -1
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/__init__.py +1 -1
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/api_stats_collector.py +16 -10
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/sdk.py +109 -11
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21/huace_aigc_auth_client.egg-info}/PKG-INFO +1 -1
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/pyproject.toml +1 -1
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/LICENSE +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/MANIFEST.in +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/QUICK_START.txt +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/README.md +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/legacy_adapter.py +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/user_context.py +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/webhook.py +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/webhook_flask.py +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client.egg-info/SOURCES.txt +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client.egg-info/dependency_links.txt +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client.egg-info/requires.txt +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client.egg-info/top_level.txt +0 -0
- {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/setup.cfg +0 -0
|
@@ -16,6 +16,7 @@ class ApiStatsCollector:
|
|
|
16
16
|
def __init__(
|
|
17
17
|
self,
|
|
18
18
|
api_url: str,
|
|
19
|
+
app_id: str,
|
|
19
20
|
app_secret: str,
|
|
20
21
|
token: str,
|
|
21
22
|
batch_size: int = 10,
|
|
@@ -27,6 +28,7 @@ class ApiStatsCollector:
|
|
|
27
28
|
|
|
28
29
|
Args:
|
|
29
30
|
api_url: 统计接口 URL(如:http://auth.example.com/api/sdk/stats/report/batch)
|
|
31
|
+
app_id: 应用 ID
|
|
30
32
|
app_secret: 应用密钥
|
|
31
33
|
token: 用户访问令牌
|
|
32
34
|
batch_size: 批量提交大小
|
|
@@ -34,6 +36,7 @@ class ApiStatsCollector:
|
|
|
34
36
|
enabled: 是否启用
|
|
35
37
|
"""
|
|
36
38
|
self.api_url = api_url.rstrip('/')
|
|
39
|
+
self.app_id = app_id
|
|
37
40
|
self.app_secret = app_secret
|
|
38
41
|
self.token = token
|
|
39
42
|
self.batch_size = batch_size
|
|
@@ -66,8 +69,8 @@ class ApiStatsCollector:
|
|
|
66
69
|
api_method: str,
|
|
67
70
|
status_code: int,
|
|
68
71
|
response_time: float,
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
error_message: Optional[str] = None,
|
|
73
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
71
74
|
):
|
|
72
75
|
"""
|
|
73
76
|
收集接口统计数据
|
|
@@ -77,8 +80,8 @@ class ApiStatsCollector:
|
|
|
77
80
|
api_method: 请求方法
|
|
78
81
|
status_code: 状态码
|
|
79
82
|
response_time: 响应时间(秒)
|
|
80
|
-
query_string: 查询字符串
|
|
81
83
|
error_message: 错误信息
|
|
84
|
+
request_params: 请求参数(包含 headers, query_params, view_params, request_body, form_params)
|
|
82
85
|
"""
|
|
83
86
|
if not self.enabled:
|
|
84
87
|
return
|
|
@@ -89,8 +92,8 @@ class ApiStatsCollector:
|
|
|
89
92
|
'api_method': api_method,
|
|
90
93
|
'status_code': status_code,
|
|
91
94
|
'response_time': response_time,
|
|
92
|
-
'query_string': query_string,
|
|
93
95
|
'error_message': error_message,
|
|
96
|
+
'request_params': request_params,
|
|
94
97
|
'timestamp': datetime.utcnow().isoformat()
|
|
95
98
|
}
|
|
96
99
|
self.queue.put_nowait(stat_data)
|
|
@@ -138,6 +141,7 @@ class ApiStatsCollector:
|
|
|
138
141
|
|
|
139
142
|
try:
|
|
140
143
|
headers = {
|
|
144
|
+
'X-App-Id': self.app_id,
|
|
141
145
|
'X-App-Secret': self.app_secret,
|
|
142
146
|
'Authorization': f'Bearer {self.token}',
|
|
143
147
|
'Content-Type': 'application/json'
|
|
@@ -167,6 +171,7 @@ _global_collector: Optional[ApiStatsCollector] = None
|
|
|
167
171
|
|
|
168
172
|
def init_api_stats_collector(
|
|
169
173
|
api_url: str,
|
|
174
|
+
app_id: str,
|
|
170
175
|
app_secret: str,
|
|
171
176
|
token: str,
|
|
172
177
|
batch_size: int = 10,
|
|
@@ -178,6 +183,7 @@ def init_api_stats_collector(
|
|
|
178
183
|
|
|
179
184
|
Args:
|
|
180
185
|
api_url: 统计接口 URL
|
|
186
|
+
app_id: 应用 ID
|
|
181
187
|
app_secret: 应用密钥
|
|
182
188
|
token: 用户访问令牌
|
|
183
189
|
batch_size: 批量提交大小
|
|
@@ -190,6 +196,7 @@ def init_api_stats_collector(
|
|
|
190
196
|
global _global_collector
|
|
191
197
|
_global_collector = ApiStatsCollector(
|
|
192
198
|
api_url=api_url,
|
|
199
|
+
app_id=app_id,
|
|
193
200
|
app_secret=app_secret,
|
|
194
201
|
token=token,
|
|
195
202
|
batch_size=batch_size,
|
|
@@ -217,8 +224,8 @@ def collect_api_stat(
|
|
|
217
224
|
api_method: str,
|
|
218
225
|
status_code: int,
|
|
219
226
|
response_time: float,
|
|
220
|
-
|
|
221
|
-
|
|
227
|
+
error_message: Optional[str] = None,
|
|
228
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
222
229
|
):
|
|
223
230
|
"""
|
|
224
231
|
快捷方法:收集接口统计数据
|
|
@@ -232,8 +239,8 @@ def collect_api_stat(
|
|
|
232
239
|
api_method=api_method,
|
|
233
240
|
status_code=status_code,
|
|
234
241
|
response_time=response_time,
|
|
235
|
-
|
|
236
|
-
|
|
242
|
+
error_message=error_message,
|
|
243
|
+
request_params=request_params
|
|
237
244
|
)
|
|
238
245
|
|
|
239
246
|
|
|
@@ -274,8 +281,7 @@ def collect_api_stat(
|
|
|
274
281
|
api_path=request.url.path,
|
|
275
282
|
api_method=request.method,
|
|
276
283
|
status_code=response.status_code,
|
|
277
|
-
response_time=response_time
|
|
278
|
-
query_string=str(request.url.query)
|
|
284
|
+
response_time=response_time
|
|
279
285
|
)
|
|
280
286
|
|
|
281
287
|
return response
|
{huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/sdk.py
RENAMED
|
@@ -585,6 +585,7 @@ class AuthMiddleware:
|
|
|
585
585
|
from .api_stats_collector import init_api_stats_collector
|
|
586
586
|
self.stats_collector = init_api_stats_collector(
|
|
587
587
|
api_url=self.stats_api_url,
|
|
588
|
+
app_id=self.client.app_id,
|
|
588
589
|
app_secret=self.client.app_secret,
|
|
589
590
|
token=token,
|
|
590
591
|
batch_size=10,
|
|
@@ -594,14 +595,103 @@ class AuthMiddleware:
|
|
|
594
595
|
except Exception as e:
|
|
595
596
|
logger.warning(f"初始化统计收集器失败: {e}")
|
|
596
597
|
|
|
598
|
+
@staticmethod
|
|
599
|
+
def _collect_flask_request_params(request) -> Dict[str, Any]:
|
|
600
|
+
"""
|
|
601
|
+
收集 Flask 请求的所有参数
|
|
602
|
+
|
|
603
|
+
Args:
|
|
604
|
+
request: Flask request 对象
|
|
605
|
+
|
|
606
|
+
Returns:
|
|
607
|
+
包含 headers, query_params, view_params, request_body, form_params 的字典
|
|
608
|
+
"""
|
|
609
|
+
try:
|
|
610
|
+
params = {
|
|
611
|
+
"headers": dict(request.headers),
|
|
612
|
+
"query_params": request.args.to_dict(flat=False),
|
|
613
|
+
"view_params": request.view_args or {},
|
|
614
|
+
"request_body": None,
|
|
615
|
+
"form_params": None
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
# 获取请求体(JSON 或文本)
|
|
619
|
+
if request.is_json:
|
|
620
|
+
try:
|
|
621
|
+
params["request_body"] = request.get_json(silent=True)
|
|
622
|
+
except Exception:
|
|
623
|
+
pass
|
|
624
|
+
elif request.data:
|
|
625
|
+
try:
|
|
626
|
+
params["request_body"] = request.data.decode('utf-8')
|
|
627
|
+
except Exception:
|
|
628
|
+
params["request_body"] = str(request.data)
|
|
629
|
+
|
|
630
|
+
# 获取表单数据
|
|
631
|
+
if request.form:
|
|
632
|
+
params["form_params"] = request.form.to_dict(flat=False)
|
|
633
|
+
|
|
634
|
+
return params
|
|
635
|
+
except Exception as e:
|
|
636
|
+
logger.warning(f"收集Flask请求参数失败: {e}")
|
|
637
|
+
return {}
|
|
638
|
+
|
|
639
|
+
@staticmethod
|
|
640
|
+
async def _collect_fastapi_request_params(request) -> Dict[str, Any]:
|
|
641
|
+
"""
|
|
642
|
+
收集 FastAPI 请求的所有参数
|
|
643
|
+
|
|
644
|
+
Args:
|
|
645
|
+
request: FastAPI Request 对象
|
|
646
|
+
|
|
647
|
+
Returns:
|
|
648
|
+
包含 headers, query_params, view_params, request_body, form_params 的字典
|
|
649
|
+
"""
|
|
650
|
+
try:
|
|
651
|
+
params = {
|
|
652
|
+
"headers": dict(request.headers),
|
|
653
|
+
"query_params": dict(request.query_params),
|
|
654
|
+
"view_params": dict(request.path_params),
|
|
655
|
+
"request_body": None,
|
|
656
|
+
"form_params": None
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
# 获取请求体
|
|
660
|
+
content_type = request.headers.get("content-type", "")
|
|
661
|
+
|
|
662
|
+
if "application/json" in content_type:
|
|
663
|
+
try:
|
|
664
|
+
params["request_body"] = await request.json()
|
|
665
|
+
except Exception:
|
|
666
|
+
pass
|
|
667
|
+
elif "application/x-www-form-urlencoded" in content_type or "multipart/form-data" in content_type:
|
|
668
|
+
try:
|
|
669
|
+
form = await request.form()
|
|
670
|
+
params["form_params"] = {k: v for k, v in form.items()}
|
|
671
|
+
except Exception:
|
|
672
|
+
pass
|
|
673
|
+
else:
|
|
674
|
+
# 尝试读取原始body
|
|
675
|
+
try:
|
|
676
|
+
body = await request.body()
|
|
677
|
+
if body:
|
|
678
|
+
params["request_body"] = body.decode('utf-8')
|
|
679
|
+
except Exception:
|
|
680
|
+
pass
|
|
681
|
+
|
|
682
|
+
return params
|
|
683
|
+
except Exception as e:
|
|
684
|
+
logger.warning(f"收集FastAPI请求参数失败: {e}")
|
|
685
|
+
return {}
|
|
686
|
+
|
|
597
687
|
def _collect_stats(
|
|
598
688
|
self,
|
|
599
689
|
api_path: str,
|
|
600
690
|
api_method: str,
|
|
601
691
|
status_code: int,
|
|
602
692
|
response_time: float,
|
|
603
|
-
|
|
604
|
-
|
|
693
|
+
error_message: Optional[str] = None,
|
|
694
|
+
request_params: Optional[Dict[str, Any]] = None
|
|
605
695
|
):
|
|
606
696
|
"""收集接口统计"""
|
|
607
697
|
if not self.enable_stats or not self.stats_collector:
|
|
@@ -613,8 +703,8 @@ class AuthMiddleware:
|
|
|
613
703
|
api_method=api_method,
|
|
614
704
|
status_code=status_code,
|
|
615
705
|
response_time=response_time,
|
|
616
|
-
|
|
617
|
-
|
|
706
|
+
error_message=error_message,
|
|
707
|
+
request_params=request_params
|
|
618
708
|
)
|
|
619
709
|
except Exception:
|
|
620
710
|
pass # 静默失败
|
|
@@ -649,6 +739,9 @@ class AuthMiddleware:
|
|
|
649
739
|
|
|
650
740
|
path = request.url.path
|
|
651
741
|
start_time = time.time()
|
|
742
|
+
|
|
743
|
+
# 收集请求参数
|
|
744
|
+
request_params = await self._collect_fastapi_request_params(request) if self.enable_stats else None
|
|
652
745
|
|
|
653
746
|
# 检查是否跳过
|
|
654
747
|
if self._should_skip(path):
|
|
@@ -661,7 +754,7 @@ class AuthMiddleware:
|
|
|
661
754
|
if not token:
|
|
662
755
|
logger.warning("AuthMiddleware未提供认证信息")
|
|
663
756
|
response_time = time.time() - start_time
|
|
664
|
-
self._collect_stats(path, request.method, 401, response_time,
|
|
757
|
+
self._collect_stats(path, request.method, 401, response_time, "未提供认证信息", request_params)
|
|
665
758
|
return JSONResponse(
|
|
666
759
|
status_code=401,
|
|
667
760
|
content={"code": 401, "message": "未提供认证信息", "data": None}
|
|
@@ -687,7 +780,7 @@ class AuthMiddleware:
|
|
|
687
780
|
except AigcAuthError as e:
|
|
688
781
|
logger.error(f"AuthMiddleware认证失败: {e.message}")
|
|
689
782
|
response_time = time.time() - start_time
|
|
690
|
-
self._collect_stats(path, request.method, 401, response_time,
|
|
783
|
+
self._collect_stats(path, request.method, 401, response_time, e.message, request_params)
|
|
691
784
|
return JSONResponse(
|
|
692
785
|
status_code=401,
|
|
693
786
|
content={"code": e.code, "message": e.message, "data": None}
|
|
@@ -697,11 +790,11 @@ class AuthMiddleware:
|
|
|
697
790
|
try:
|
|
698
791
|
response = await call_next(request)
|
|
699
792
|
response_time = time.time() - start_time
|
|
700
|
-
self._collect_stats(path, request.method, response.status_code, response_time,
|
|
793
|
+
self._collect_stats(path, request.method, response.status_code, response_time, None, request_params)
|
|
701
794
|
return response
|
|
702
795
|
except Exception as e:
|
|
703
796
|
response_time = time.time() - start_time
|
|
704
|
-
self._collect_stats(path, request.method, 500, response_time, str(
|
|
797
|
+
self._collect_stats(path, request.method, 500, response_time, str(e), request_params)
|
|
705
798
|
raise
|
|
706
799
|
finally:
|
|
707
800
|
clear_current_user()
|
|
@@ -720,6 +813,9 @@ class AuthMiddleware:
|
|
|
720
813
|
path = request.path
|
|
721
814
|
# 记录开始时间到 g 对象
|
|
722
815
|
g.start_time = time.time()
|
|
816
|
+
|
|
817
|
+
# 收集请求参数
|
|
818
|
+
g.request_params = self._collect_flask_request_params(request) if self.enable_stats else None
|
|
723
819
|
|
|
724
820
|
# 检查是否跳过
|
|
725
821
|
if self._should_skip(path):
|
|
@@ -732,7 +828,7 @@ class AuthMiddleware:
|
|
|
732
828
|
if not token:
|
|
733
829
|
logger.warning("AuthMiddleware未提供认证信息")
|
|
734
830
|
response_time = time.time() - g.start_time
|
|
735
|
-
self._collect_stats(path, request.method, 401, response_time,
|
|
831
|
+
self._collect_stats(path, request.method, 401, response_time, "未提供认证信息", g.request_params)
|
|
736
832
|
return jsonify({
|
|
737
833
|
"code": 401,
|
|
738
834
|
"message": "未提供认证信息",
|
|
@@ -754,7 +850,7 @@ class AuthMiddleware:
|
|
|
754
850
|
except AigcAuthError as e:
|
|
755
851
|
logger.error(f"AuthMiddleware认证失败: {e.message}")
|
|
756
852
|
response_time = time.time() - g.start_time
|
|
757
|
-
self._collect_stats(path, request.method, 401, response_time,
|
|
853
|
+
self._collect_stats(path, request.method, 401, response_time, e.message, g.request_params)
|
|
758
854
|
return jsonify({
|
|
759
855
|
"code": e.code,
|
|
760
856
|
"message": e.message,
|
|
@@ -779,12 +875,14 @@ class AuthMiddleware:
|
|
|
779
875
|
|
|
780
876
|
if hasattr(g, 'start_time'):
|
|
781
877
|
response_time = time.time() - g.start_time
|
|
878
|
+
request_params = getattr(g, 'request_params', None)
|
|
782
879
|
self._collect_stats(
|
|
783
880
|
request.path,
|
|
784
881
|
request.method,
|
|
785
882
|
response.status_code,
|
|
786
883
|
response_time,
|
|
787
|
-
|
|
884
|
+
None,
|
|
885
|
+
request_params
|
|
788
886
|
)
|
|
789
887
|
|
|
790
888
|
return response
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/webhook.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|