""" 改进版Python FastAPI服务器实现,使用DashScope Python SDK连接阿里云百炼平台API 拆分模块版本 """ import os import json from datetime import datetime, timezone from pathlib import Path import dashscope from dotenv import load_dotenv from fastapi import FastAPI, HTTPException, File, UploadFile, Request from fastapi.responses import JSONResponse # 导入模块 import sys sys.path.append('/home/mt/project/ai-chat-ui/server') from api.chat_routes import ( chat_endpoint_handler, get_models_handler, get_conversations_handler, get_conversation_handler, save_conversation_handler, delete_conversation_handler, upload_file_handler, serve_upload_handler, stop_generation_handler ) from models.chat_models import ChatRequest, ModelInfo from utils.helpers import log_request, log_response from utils.logger import get_logger logger = get_logger() # 加载环境变量 load_dotenv() # 设置 DashScope API 密钥 api_key = os.getenv("ALIYUN_API_KEY") if not api_key: raise ValueError("请在环境变量中设置 ALIYUN_API_KEY") dashscope.api_key = api_key # 创建 FastAPI 应用 app = FastAPI(title="AI Chat API Server (Python)", version="2.0.0") @app.middleware("http") async def logging_middleware(request: Request, call_next): """中间件:记录请求日志并美化输出""" start_time = datetime.now(timezone.utc) client_ip = request.client.host if request.client else 'unknown' # 请求日志 logger.info(f"→ {request.method} {request.url.path} | IP: {client_ip}") response = await call_next(request) process_time = (datetime.now(timezone.utc) - start_time).total_seconds() * 1000 status_emoji = "✅" if response.status_code < 400 else "❌" # 响应日志(包含端点、状态码、耗时) logger.info(f"{status_emoji} {request.method} {request.url.path} | 状态: {response.status_code} | 耗时: {process_time:.0f}ms") # 记录结构化日志(写入日志文件) log_response(response.status_code, process_time) response.headers["X-Process-Time"] = f"{process_time:.2f}ms" return response @app.get("/health") async def health_check(): """健康检查端点""" return {"status": "healthy", "timestamp": datetime.now(timezone.utc).isoformat()} @app.post("/api/chat-ui/chat") async def chat_endpoint(request: Request): """聊天接口 - 与阿里云百炼API兼容的接口""" body = await request.json() return await chat_endpoint_handler(body) @app.get("/api/chat-ui/models") async def get_models(): """获取模型列表""" return await get_models_handler() @app.get("/api/chat-ui/conversations") async def get_conversations(): """获取所有对话""" return await get_conversations_handler() @app.get("/api/chat-ui/conversations/{conversation_id}") async def get_conversation(conversation_id: str): """获取特定对话""" return await get_conversation_handler(conversation_id) @app.post("/api/chat-ui/conversations") async def save_conversation(request: Request): """保存或更新对话""" data = await request.json() return await save_conversation_handler(data) @app.delete("/api/chat-ui/conversations/{conversation_id}") async def delete_conversation(conversation_id: str): """删除对话""" return await delete_conversation_handler(conversation_id) @app.post("/api/chat-ui/upload") async def upload_file(file: UploadFile = File(...)): """文件上传接口""" return await upload_file_handler(file=file) @app.get("/uploads/{filename}") async def serve_upload(filename: str): """提供上传文件的访问""" return serve_upload_handler(filename) @app.post("/api/chat-ui/stop") async def stop_generation(): """停止生成接口""" return await stop_generation_handler() @app.post("/api/chat-ui/stop/{message_id}") async def stop_generation_by_id(message_id: str): """根据消息ID停止生成""" return await stop_generation_handler(message_id) if __name__ == "__main__": import uvicorn port = int(os.getenv("PORT", 8000)) print("="*50) print(f"Python AI Chat Server 启动中...") print(f"监听端口: {port}") print(f"API Key 状态: {'已配置' if api_key else '未配置'}") print("="*50) if not api_key: print("警告: 未在环境变量中检测到 ALIYUN_API_KEY!") print("请在 .env 文件中添加您的百炼 API Key。") else: print("API Key 已检测到。") uvicorn.run(app, host="0.0.0.0", port=port)