Files
nekochatapi/api/qwen.py

75 lines
2.4 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.
import logging
import uuid
import json
from fastapi import APIRouter, HTTPException, status
from fastapi.responses import StreamingResponse
from config import QWEN_API_KEY, QWEN_UPSTREAM_URL
from models import ChatRequest
from utils import convert_prompt_to_messages, standard_sse_generator
router = APIRouter()
logger = logging.getLogger("proxy")
@router.post("/qwen/chat")
async def proxy_qwen_chat(request: ChatRequest):
# 为每个请求生成一个唯一的 ID,方便在日志中追踪
request_id = f"qwen-{uuid.uuid4()}"
# 检查 API Key 是否已在 config.py 中配置
if not QWEN_API_KEY:
raise HTTPException(
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
detail="Qwen API key is not configured.",
)
# 记录从客户端收到的原始请求体
client_request_body = request.model_dump()
logger.debug(
f"[{request_id}] === Qwen New Request ===\n"
f"[{request_id}] Client Request Body:\n"
f"{json.dumps(client_request_body, indent=2, ensure_ascii=False)}"
)
# 将 prompt 格式转换为 API 所需的 messages 格式
messages = convert_prompt_to_messages(request.prompt)
logger.debug(
f"[{request_id}] Agent Transformed Messages:\n"
f"{json.dumps(messages, indent=2, ensure_ascii=False)}"
)
# 构建发送到上游 API 的 payload
payload = {
"model": "qwen-plus", # 指定使用的模型
"messages": messages,
"stream": True,
"temperature": request.temperature,
"top_p": request.top_p,
"max_tokens": request.max_tokens,
}
# 如果客户端请求 web_search=True则为 Qwen 启用网页搜索
if request.web_search is True:
payload["enable_search"] = True
logger.info(f"[{request_id}] Enabled web search for Qwen.")
logger.debug(
f"[{request_id}] Upstream Payload:\n"
f"{json.dumps(payload, indent=2, ensure_ascii=False)}"
)
# 请求头,包含认证信息
headers = {"Authorization": f"Bearer {QWEN_API_KEY}"}
# 返回一个流式响应对象
# standard_sse_generator 会处理与上游的通信和流式数据的转发
return StreamingResponse(
standard_sse_generator(
QWEN_UPSTREAM_URL, payload, headers, "Qwen", request_id
),
media_type="text/event-stream", # 指定 SSE 的 MIME 类型
)