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.
Files changed (19) hide show
  1. {huace_aigc_auth_client-1.1.19/huace_aigc_auth_client.egg-info → huace_aigc_auth_client-1.1.21}/PKG-INFO +1 -1
  2. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/__init__.py +1 -1
  3. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/api_stats_collector.py +16 -10
  4. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/sdk.py +109 -11
  5. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21/huace_aigc_auth_client.egg-info}/PKG-INFO +1 -1
  6. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/pyproject.toml +1 -1
  7. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/LICENSE +0 -0
  8. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/MANIFEST.in +0 -0
  9. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/QUICK_START.txt +0 -0
  10. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/README.md +0 -0
  11. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/legacy_adapter.py +0 -0
  12. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/user_context.py +0 -0
  13. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/webhook.py +0 -0
  14. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client/webhook_flask.py +0 -0
  15. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client.egg-info/SOURCES.txt +0 -0
  16. {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
  17. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/huace_aigc_auth_client.egg-info/requires.txt +0 -0
  18. {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
  19. {huace_aigc_auth_client-1.1.19 → huace_aigc_auth_client-1.1.21}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: huace-aigc-auth-client
3
- Version: 1.1.19
3
+ Version: 1.1.21
4
4
  Summary: 华策AIGC Auth Client - 提供 Token 验证、用户信息获取、权限检查、旧系统接入等功能
5
5
  Author-email: Huace <support@huace.com>
6
6
  License: MIT
@@ -172,4 +172,4 @@ __all__ = [
172
172
  # 用户上下文
173
173
  "get_current_user",
174
174
  ]
175
- __version__ = "1.1.19"
175
+ __version__ = "1.1.21"
@@ -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
- query_string: Optional[str] = None,
70
- error_message: Optional[str] = None
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
- query_string: Optional[str] = None,
221
- error_message: Optional[str] = None
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
- query_string=query_string,
236
- error_message=error_message
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
@@ -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
- query_string: Optional[str] = None,
604
- error_message: Optional[str] = None
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
- query_string=query_string,
617
- error_message=error_message
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, str(request.url.query), "未提供认证信息")
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, str(request.url.query), e.message)
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, str(request.url.query))
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(request.url.query), str(e))
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, request.query_string.decode(), "未提供认证信息")
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, request.query_string.decode(), e.message)
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
- request.query_string.decode()
884
+ None,
885
+ request_params
788
886
  )
789
887
 
790
888
  return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: huace-aigc-auth-client
3
- Version: 1.1.19
3
+ Version: 1.1.21
4
4
  Summary: 华策AIGC Auth Client - 提供 Token 验证、用户信息获取、权限检查、旧系统接入等功能
5
5
  Author-email: Huace <support@huace.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "huace-aigc-auth-client"
7
- version = "1.1.19"
7
+ version = "1.1.21"
8
8
  description = "华策AIGC Auth Client - 提供 Token 验证、用户信息获取、权限检查、旧系统接入等功能"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"