huace-aigc-auth-client 1.1.34__py3-none-any.whl → 1.1.35__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.
@@ -67,7 +67,13 @@ from .api_stats_collector import (
67
67
 
68
68
  from .auth_request import (
69
69
  auth_request,
70
- async_auth_httpx_request
70
+ auth_request_get,
71
+ auth_request_post,
72
+ AuthSession,
73
+ async_auth_httpx_request,
74
+ async_auth_httpx_request_get,
75
+ async_auth_httpx_request_post,
76
+ AsyncAuthClient,
71
77
  )
72
78
 
73
79
  from .legacy_adapter import (
@@ -215,6 +221,12 @@ __all__ = [
215
221
  "stop_api_stats_collector",
216
222
  # 认证请求封装
217
223
  "auth_request",
224
+ "auth_request_get",
225
+ "auth_request_post",
226
+ "AuthSession",
218
227
  "async_auth_httpx_request",
228
+ "async_auth_httpx_request_get",
229
+ "async_auth_httpx_request_post",
230
+ "AsyncAuthClient",
219
231
  ]
220
- __version__ = "1.1.34"
232
+ __version__ = "1.1.35"
@@ -29,6 +29,80 @@ def setLogger(log):
29
29
  global logger
30
30
  logger = log
31
31
 
32
+ def _report_stats(
33
+ url: str,
34
+ method: str,
35
+ response: Optional[Response],
36
+ response_time: float,
37
+ error_message: Optional[str],
38
+ request_context: Optional[Dict[str, Any]],
39
+ headers: Optional[Dict[str, str]],
40
+ params: Optional[Dict[str, Any]],
41
+ json_data: Optional[Dict[str, Any]],
42
+ form_data: Optional[Union[Dict[str, Any], str, bytes]]
43
+ ):
44
+ """
45
+ 上报统计信息到远程服务
46
+
47
+ Args:
48
+ url: 请求 URL
49
+ method: HTTP 方法
50
+ response: 响应对象
51
+ response_time: 响应时间
52
+ error_message: 错误信息
53
+ request_context: 请求上下文
54
+ params: 查询参数
55
+ json_data: JSON 数据
56
+ form_data: 表单数据
57
+ """
58
+ try:
59
+ # 获取统计收集器
60
+ collector = get_api_stats_collector()
61
+ if not collector:
62
+ return
63
+
64
+ # 获取 token
65
+ token = request_context.get('token') if request_context else None
66
+ if not token:
67
+ return
68
+
69
+ # 解析 URL 获取路径
70
+ from urllib.parse import urlparse
71
+ parsed_url = urlparse(url)
72
+ api_path = parsed_url.path or '/'
73
+ # 带上协议和域名
74
+ api_path = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path or '/'}"
75
+
76
+ # 获取状态码
77
+ status_code = response.status_code if response else 500
78
+
79
+ # 构建请求参数(与 api_stats_collector 格式一致)
80
+ request_params = {
81
+ 'query_params': params or {},
82
+ 'headers': headers
83
+ }
84
+
85
+ # 添加请求体数据
86
+ if json_data:
87
+ request_params['request_body'] = json_data
88
+ elif isinstance(form_data, dict):
89
+ request_params['form_params'] = form_data
90
+
91
+ # 收集统计
92
+ collector.collect(
93
+ api_path=api_path,
94
+ api_method=method.upper(),
95
+ status_code=status_code,
96
+ response_time=response_time,
97
+ token=token,
98
+ error_message=error_message,
99
+ request_params=request_params
100
+ )
101
+
102
+ except Exception as e:
103
+ # 静默失败,不影响主流程
104
+ logger.debug(f"统计上报失败: {e}")
105
+
32
106
  def auth_request(
33
107
  method: str,
34
108
  url: str,
@@ -173,80 +247,195 @@ def auth_request(
173
247
  form_data=data
174
248
  )
175
249
 
250
+ def auth_request_get(
251
+ url: str,
252
+ params: Optional[Dict[str, Any]] = None,
253
+ headers: Optional[Dict[str, str]] = None,
254
+ **kwargs
255
+ ) -> Response:
256
+ """
257
+ GET 请求快捷方法
258
+
259
+ Args:
260
+ url: 请求 URL
261
+ params: URL 查询参数
262
+ headers: 请求头
263
+ **kwargs: 其他 auth_request 支持的参数
264
+
265
+ Returns:
266
+ Response: 响应对象
267
+ """
268
+ return auth_request('GET', url, params=params, headers=headers, **kwargs)
176
269
 
177
- def _report_stats(
270
+ def auth_request_post(
178
271
  url: str,
179
- method: str,
180
- response: Optional[Response],
181
- response_time: float,
182
- error_message: Optional[str],
183
- request_context: Optional[Dict[str, Any]],
184
- headers: Optional[Dict[str, str]],
185
- params: Optional[Dict[str, Any]],
186
- json_data: Optional[Dict[str, Any]],
187
- form_data: Optional[Union[Dict[str, Any], str, bytes]]
188
- ):
272
+ data: Optional[Union[Dict[str, Any], str, bytes]] = None,
273
+ json: Optional[Dict[str, Any]] = None,
274
+ params: Optional[Dict[str, Any]] = None,
275
+ headers: Optional[Dict[str, str]] = None,
276
+ **kwargs
277
+ ) -> Response:
189
278
  """
190
- 上报统计信息到远程服务
279
+ POST 请求快捷方法
191
280
 
192
281
  Args:
193
282
  url: 请求 URL
194
- method: HTTP 方法
195
- response: 响应对象
196
- response_time: 响应时间
197
- error_message: 错误信息
198
- request_context: 请求上下文
199
- params: 查询参数
200
- json_data: JSON 数据
201
- form_data: 表单数据
283
+ data: 请求体数据 (form-data 或 raw)
284
+ json: JSON 请求体数据
285
+ params: URL 查询参数
286
+ headers: 请求头
287
+ **kwargs: 其他 auth_request 支持的参数
288
+
289
+ Returns:
290
+ Response: 响应对象
202
291
  """
203
- try:
204
- # 获取统计收集器
205
- collector = get_api_stats_collector()
206
- if not collector:
207
- return
208
-
209
- # 获取 token
210
- token = request_context.get('token') if request_context else None
211
- if not token:
212
- return
213
-
214
- # 解析 URL 获取路径
215
- from urllib.parse import urlparse
216
- parsed_url = urlparse(url)
217
- api_path = parsed_url.path or '/'
218
- # 带上协议和域名
219
- api_path = f"{parsed_url.scheme}://{parsed_url.netloc}{parsed_url.path or '/'}"
292
+ return auth_request('POST', url, data=data, json=json, params=params, headers=headers, **kwargs)
293
+
294
+
295
+ # ============ Session 封装(支持连接池) ============
296
+
297
+ class AuthSession(requests.Session):
298
+ """
299
+ 认证 Session 类(支持连接池)
300
+
301
+ 继承 requests.Session,自动添加认证信息和统计上报
302
+ 支持连接池,提升性能
303
+
304
+ 使用示例:
305
+ from huace_aigc_auth_client import AuthSession, set_request_context
306
+
307
+ # 设置请求上下文
308
+ set_request_context(
309
+ app_id='your-app-id',
310
+ app_secret='your-app-secret',
311
+ token='user-token'
312
+ )
220
313
 
221
- # 获取状态码
222
- status_code = response.status_code if response else 500
314
+ # 创建 Session(自动启用连接池)
315
+ with AuthSession() as session:
316
+ # GET 请求
317
+ response = session.get('https://api.example.com/users')
318
+
319
+ # POST 请求
320
+ response = session.post(
321
+ 'https://api.example.com/users',
322
+ json={'name': 'John'}
323
+ )
324
+ """
325
+
326
+ def request(
327
+ self,
328
+ method: str,
329
+ url: str,
330
+ params: Optional[Dict[str, Any]] = None,
331
+ data: Optional[Union[Dict[str, Any], str, bytes]] = None,
332
+ headers: Optional[Dict[str, str]] = None,
333
+ cookies: Optional[Dict[str, str]] = None,
334
+ files: Optional[Dict[str, Any]] = None,
335
+ auth: Optional[tuple] = None,
336
+ timeout: Optional[Union[float, tuple]] = None,
337
+ allow_redirects: bool = True,
338
+ proxies: Optional[Dict[str, str]] = None,
339
+ hooks: Optional[Dict[str, Any]] = None,
340
+ stream: bool = False,
341
+ verify: Optional[Union[bool, str]] = None,
342
+ cert: Optional[Union[str, tuple]] = None,
343
+ json: Optional[Dict[str, Any]] = None,
344
+ ) -> Response:
345
+ """
346
+ 重写 request 方法,添加认证信息和统计上报
347
+ """
348
+ # 初始化 headers
349
+ if headers is None:
350
+ headers = {}
351
+ else:
352
+ headers = headers.copy()
223
353
 
224
- # 构建请求参数(与 api_stats_collector 格式一致)
225
- request_params = {
226
- 'query_params': params or {},
227
- 'headers': headers
228
- }
354
+ # request_context 获取认证信息
355
+ request_context = get_request_context()
229
356
 
230
- # 添加请求体数据
231
- if json_data:
232
- request_params['request_body'] = json_data
233
- elif isinstance(form_data, dict):
234
- request_params['form_params'] = form_data
357
+ if request_context:
358
+ # 添加应用ID
359
+ app_id = request_context.get('app_id')
360
+ if app_id is not None:
361
+ headers['X-App-ID'] = str(app_id)
362
+
363
+ # 添加应用密钥
364
+ app_secret = request_context.get('app_secret')
365
+ if app_secret:
366
+ headers['X-App-Secret'] = app_secret
367
+
368
+ # 添加认证令牌
369
+ token = request_context.get('token')
370
+ if token:
371
+ headers['Authorization'] = f'Bearer {token}'
372
+
373
+ # 添加客户端IP
374
+ ip_address = request_context.get('ip_address')
375
+ if ip_address:
376
+ headers['x-real-ip'] = ip_address
377
+
378
+ # 添加 User Agent
379
+ user_agent = request_context.get('user_agent')
380
+ if user_agent:
381
+ headers['user-agent'] = user_agent
382
+
383
+ # 添加追踪ID
384
+ trace_id = request_context.get('trace_id')
385
+ if trace_id:
386
+ headers['X-Trace-ID'] = trace_id
235
387
 
236
- # 收集统计
237
- collector.collect(
238
- api_path=api_path,
239
- api_method=method.upper(),
240
- status_code=status_code,
241
- response_time=response_time,
242
- token=token,
243
- error_message=error_message,
244
- request_params=request_params
245
- )
388
+ # 记录开始时间
389
+ start_time = time.time()
390
+ response = None
391
+ error_message = None
246
392
 
247
- except Exception as e:
248
- # 静默失败,不影响主流程
249
- logger.debug(f"统计上报失败: {e}")
393
+ try:
394
+ # 调用父类的 request 方法
395
+ logger.info(f"AuthSession 发起请求: {method} {url} with headers={headers}")
396
+ response = super().request(
397
+ method=method,
398
+ url=url,
399
+ params=params,
400
+ data=data,
401
+ headers=headers,
402
+ cookies=cookies,
403
+ files=files,
404
+ auth=auth,
405
+ timeout=timeout,
406
+ allow_redirects=allow_redirects,
407
+ proxies=proxies,
408
+ hooks=hooks,
409
+ stream=stream,
410
+ verify=verify,
411
+ cert=cert,
412
+ json=json,
413
+ )
414
+ logger.info(f"AuthSession 请求响应: {method} {url} 状态码: {response.status_code}")
415
+ return response
416
+
417
+ except Exception as e:
418
+ error_message = str(e)
419
+ logger.error(f"AuthSession 请求失败: {method} {url} 错误: {error_message}")
420
+ raise
421
+
422
+ finally:
423
+ # 计算响应时间
424
+ response_time = time.time() - start_time
425
+
426
+ # 上报统计信息
427
+ _report_stats(
428
+ url=url,
429
+ method=method,
430
+ response=response,
431
+ response_time=response_time,
432
+ error_message=error_message,
433
+ request_context=request_context,
434
+ headers=headers,
435
+ params=params,
436
+ json_data=json,
437
+ form_data=data
438
+ )
250
439
 
251
440
 
252
441
  # ============ HTTPX 异步请求封装 ============
@@ -387,7 +576,50 @@ if HTTPX_AVAILABLE:
387
576
  form_data=data
388
577
  )
389
578
 
579
+ async def async_auth_httpx_request_get(
580
+ url: str,
581
+ params: Optional[Dict[str, Any]] = None,
582
+ headers: Optional[Dict[str, str]] = None,
583
+ **kwargs
584
+ ) -> httpx.Response:
585
+ """
586
+ 异步 GET 请求快捷方法
587
+
588
+ Args:
589
+ url: 请求 URL
590
+ params: URL 查询参数
591
+ headers: 请求头
592
+ **kwargs: 其他 async_auth_httpx_request 支持的参数
593
+
594
+ Returns:
595
+ httpx.Response: 响应对象
596
+ """
597
+ return await async_auth_httpx_request('GET', url, params=params, headers=headers, **kwargs)
390
598
 
599
+ async def async_auth_httpx_request_post(
600
+ url: str,
601
+ data: Optional[Union[Dict[str, Any], str, bytes]] = None,
602
+ json: Optional[Dict[str, Any]] = None,
603
+ params: Optional[Dict[str, Any]] = None,
604
+ headers: Optional[Dict[str, str]] = None,
605
+ **kwargs
606
+ ) -> httpx.Response:
607
+ """
608
+ 异步 POST 请求快捷方法
609
+
610
+ Args:
611
+ url: 请求 URL
612
+ data: 请求体数据 (form-data 或 raw)
613
+ json: JSON 请求体数据
614
+ params: URL 查询参数
615
+ headers: 请求头
616
+ **kwargs: 其他 async_auth_httpx_request 支持的参数
617
+
618
+ Returns:
619
+ httpx.Response: 响应对象
620
+ """
621
+ return await async_auth_httpx_request('POST', url, data=data, json=json, params=params, headers=headers, **kwargs)
622
+
391
623
  class AsyncAuthClient:
392
624
  """
393
625
  异步认证客户端(httpx.AsyncClient 包装)
@@ -591,7 +823,51 @@ if HTTPX_AVAILABLE:
591
823
  print(response.json())
592
824
 
593
825
 
594
- 2. 带参数的请求:
826
+ 2. 使用 AuthSession(支持连接池,推荐):
827
+
828
+ from huace_aigc_auth_client.auth_request import AuthSession
829
+ from huace_aigc_auth_client.user_context import set_request_context
830
+
831
+ # 设置请求上下文
832
+ set_request_context(
833
+ app_id='your-app-id',
834
+ app_secret='your-app-secret',
835
+ token='user-access-token'
836
+ )
837
+
838
+ # 使用 AuthSession(自动启用连接池)
839
+ with AuthSession() as session:
840
+ # GET 请求
841
+ response = session.get('https://api.example.com/users', params={'page': 1})
842
+ print(response.json())
843
+
844
+ # POST 请求
845
+ response = session.post(
846
+ 'https://api.example.com/users',
847
+ json={'name': 'John', 'email': 'john@example.com'}
848
+ )
849
+ print(response.json())
850
+
851
+ # 多个请求复用同一个连接池,性能更好
852
+ for i in range(10):
853
+ response = session.get(f'https://api.example.com/items/{i}')
854
+
855
+
856
+ 3. 不使用上下文管理器的 AuthSession:
857
+
858
+ from huace_aigc_auth_client.auth_request import AuthSession
859
+
860
+ # 创建 Session
861
+ session = AuthSession()
862
+
863
+ try:
864
+ response = session.get('https://api.example.com/users')
865
+ print(response.json())
866
+ finally:
867
+ session.close() # 手动关闭
868
+
869
+
870
+ 4. 带参数的请求:
595
871
 
596
872
  # GET 请求带查询参数
597
873
  response = auth_request(
@@ -615,7 +891,7 @@ if HTTPX_AVAILABLE:
615
891
  )
616
892
 
617
893
 
618
- 3. 覆盖默认 headers:
894
+ 5. 覆盖默认 headers:
619
895
 
620
896
  # 可以手动指定 headers,会与自动添加的 headers 合并
621
897
  response = auth_request(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: huace-aigc-auth-client
3
- Version: 1.1.34
3
+ Version: 1.1.35
4
4
  Summary: 华策AIGC Auth Client - 提供 Token 验证、用户信息获取、权限检查、旧系统接入等功能
5
5
  Author-email: Huace <support@huace.com>
6
6
  License: MIT
@@ -1,13 +1,13 @@
1
- huace_aigc_auth_client/__init__.py,sha256=ZrHUpyhR2qKqo9RJ39C2s7C3PeriyYvNvQMxtH7N6C8,6020
1
+ huace_aigc_auth_client/__init__.py,sha256=d1YC-9M_saTbdMEaMvDtzT-gDHc5wep2667pZsCKrag,6337
2
2
  huace_aigc_auth_client/api_stats_collector.py,sha256=ADpjpHXMqn80YI4UltWHbzAO_szykU9ZCvwXgBRWFIM,11046
3
- huace_aigc_auth_client/auth_request.py,sha256=wc23_Lz0ounJ0HSN0e49lfTKNEio80FbWXTKFaOrw8g,22684
3
+ huace_aigc_auth_client/auth_request.py,sha256=Xlg1hq5jgXv5gUhOeh2ks0GtE05d4D9lrGZigxfB1o0,31486
4
4
  huace_aigc_auth_client/legacy_adapter.py,sha256=TVCBAKejE2z2HQFsEwDW8LMiaIkXNfz3Mxv6_E-UJFY,24102
5
5
  huace_aigc_auth_client/sdk.py,sha256=rproo913OAi37wz_rMYgxzP3F1YyY3nc5e35JS5WvoY,37751
6
6
  huace_aigc_auth_client/user_context.py,sha256=IqdX6Xd2jJwvij6Hc2qWAFWj5pn3wHqk0RBsaXKLP8g,6795
7
7
  huace_aigc_auth_client/webhook.py,sha256=XQZYEbMoqIdqZWCGSTcedeDKJpDbUVSq5g08g-6Qucg,4124
8
8
  huace_aigc_auth_client/webhook_flask.py,sha256=Iosu4dBtRhQZM_ytn-bn82MpVsyOiV28FBnt7Tfh31U,7225
9
- huace_aigc_auth_client-1.1.34.dist-info/licenses/LICENSE,sha256=z7dgC7KljhBLNvKjN15391nMj3aLt0gbud8-Yf1F8EQ,1063
10
- huace_aigc_auth_client-1.1.34.dist-info/METADATA,sha256=8AlHIfXy0YxAZ9Z20Qcsq5sv7svOHjGY0rJp6cmJRvg,32415
11
- huace_aigc_auth_client-1.1.34.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
12
- huace_aigc_auth_client-1.1.34.dist-info/top_level.txt,sha256=kbv0nQ6PQ0JVneWPH7O2AbtlJnP7AjvFJ6JjM6ZEBxo,23
13
- huace_aigc_auth_client-1.1.34.dist-info/RECORD,,
9
+ huace_aigc_auth_client-1.1.35.dist-info/licenses/LICENSE,sha256=z7dgC7KljhBLNvKjN15391nMj3aLt0gbud8-Yf1F8EQ,1063
10
+ huace_aigc_auth_client-1.1.35.dist-info/METADATA,sha256=5eRkyxueBTCBuqUI-IAx22mcnL8-_eOe_mnaZuC09ZE,32415
11
+ huace_aigc_auth_client-1.1.35.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
12
+ huace_aigc_auth_client-1.1.35.dist-info/top_level.txt,sha256=kbv0nQ6PQ0JVneWPH7O2AbtlJnP7AjvFJ6JjM6ZEBxo,23
13
+ huace_aigc_auth_client-1.1.35.dist-info/RECORD,,