Files
get_wechat/chatlog_fastAPI/services/http_client.py
yuanzhipeng 646efa132e ```
feat(api): 添加万川平台模型配置获取和同步功能

- 新增 getWanchuanModelConfig 函数,按模型编码获取平台模型配置
- 新增 syncWanchuanModelToSettings 函数,从万川平台拉取模型配置并写入后端 AI 设置
- 支持按用途分多个模型编码(generic/vision/voice)分别同步配置
- 配置失败时跳过对应字段,不影响其他模型同步

feat(settings): 重构AI模型配置界面支持多模块分组

- 将AI配置按话题分析、报告生成、视觉、语音四个模块分组展示
- 每个模块独立配置接口地址、密钥和模型名称
- 添加从万川平台获取配置的按钮和同步功能
- 优化配置状态指示和错误提示信息

refactor(config): 扩展AI配置支持独立的语音视觉报告网关

- 新增 voice_base_url/voice_api_key 配置项
- 新增 vision_base_url/vision_api_key 配置项
- 新增 summary_base_url/summary_api_key 配置项
- 留空时回退到 ai_base_url/ai_api_key 兼容单网关场景

refactor(http): 统一使用共享HTTP客户端减少连接开销

- 替换各处 httpx.AsyncClient 为 shared_client
- 在 lifespan 中正确关闭共享客户端资源
- 优化 get_current_wxid 和 health 检查中的HTTP请求

refactor(ai): 按用途缓存AI客户端支持不同网关配置

- 重构 get_openai_client 支持按(base_url, api_key)缓存
- 新增 get_client_for 函数按用途获取对应客户端
- 支持语音、视觉、报告等不同用途使用独立网关和密钥
```
2026-06-24 20:34:10 +08:00

47 lines
1.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""共享的 httpx.AsyncClient。
历史问题:后端每次访问 chatlog.exe127.0.0.1:5030都新建一个 AsyncClient
用完即关,没有 keep-alive。打开一个群聊会瞬间产生几十条短连接图片代理、
头像查询等),在 Windows 上会堆积 TIME_WAIT / 耗尽临时端口,导致“用一会儿就卡”。
这里改为全后端共享一个带连接池的 client复用 keep-alive 连接,连接建立开销
和端口占用都大幅下降。在 lifespan 关闭时统一释放。
"""
from __future__ import annotations
import httpx
_client: httpx.AsyncClient | None = None
def shared_client() -> httpx.AsyncClient:
"""返回进程级共享的 AsyncClient惰性创建
- trust_env=False与原各处调用保持一致不读系统代理避免本地回环被代理拦截。
- follow_redirects=True媒体/文件接口需要;普通 api 调用无重定向,无副作用。
- limits保持 keep-alive 连接,避免每请求新建连接。
单次请求可通过 client.get(..., timeout=...) 覆盖超时。
"""
global _client
if _client is None or _client.is_closed:
_client = httpx.AsyncClient(
trust_env=False,
follow_redirects=True,
timeout=httpx.Timeout(30.0, connect=5.0),
limits=httpx.Limits(
max_keepalive_connections=32,
max_connections=128,
keepalive_expiry=30.0,
),
)
return _client
async def close_shared_client() -> None:
"""在应用关闭时释放共享 client。"""
global _client
if _client is not None and not _client.is_closed:
await _client.aclose()
_client = None