Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, HTTPException | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from utils.validators import ChatRequest, ChatResponse | |
| from utils.logger import log | |
| from modules.travel_assistant import TravelAssistant | |
| import traceback | |
| # --- FastAPI 应用设置 --- | |
| app = FastAPI( | |
| title="Modular Travel Assistant API", | |
| description="一个采用模块化和分层架构的旅行助手API", | |
| version="2.0.0", | |
| docs_url="/docs", | |
| redoc_url="/redoc" | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # --- 全局服务实例 --- | |
| try: | |
| log.info("🔄 开始初始化 Travel Assistant 服务...") | |
| assistant = TravelAssistant() | |
| SERVICE_READY = True | |
| log.info("🚀 FastAPI 应用启动成功,服务已就绪。") | |
| except Exception as e: | |
| assistant = None | |
| SERVICE_READY = False | |
| log.critical(f"💥 FATAL: 服务初始化失败: {e}") | |
| log.critical(f"💥 错误详情: {traceback.format_exc()}") | |
| # --- API 端点 --- | |
| async def root(): | |
| """根路径 - 提供基本信息""" | |
| ai_available = False | |
| if SERVICE_READY and assistant and hasattr(assistant, 'ai_model'): | |
| ai_available = assistant.ai_model.is_available() | |
| return { | |
| "message": "Travel Assistant API", | |
| "version": "2.0.0", | |
| "status": "ready" if SERVICE_READY else "degraded", | |
| "ai_model_status": "available" if ai_available else "unavailable", | |
| "docs": "/docs", | |
| "health": "/health" | |
| } | |
| async def health_check(): | |
| """健康检查端点""" | |
| if SERVICE_READY and assistant: | |
| ai_available = assistant.ai_model.is_available() if hasattr(assistant.ai_model, 'is_available') else False | |
| return { | |
| "status": "healthy" if ai_available else "degraded", | |
| "service_ready": True, | |
| "ai_model_available": ai_available, | |
| "components": { | |
| "config": True, | |
| "knowledge_base": len(assistant.kb.knowledge) > 0 if hasattr(assistant, 'kb') else False, | |
| "ai_model": ai_available, | |
| "session_manager": True | |
| } | |
| } | |
| else: | |
| return JSONResponse( | |
| status_code=503, | |
| content={ | |
| "status": "unhealthy", | |
| "service_ready": False, | |
| "ai_model_available": False | |
| } | |
| ) | |
| async def chat_endpoint(request: ChatRequest): | |
| """主要的聊天API端点""" | |
| if not SERVICE_READY or not assistant: | |
| raise HTTPException( | |
| status_code=503, | |
| detail="Service Unavailable: Backend assistant failed to initialize." | |
| ) | |
| try: | |
| log.info(f"收到聊天请求: {request.message[:50]}...") | |
| reply, session_id, status_info, history = assistant.chat( | |
| request.message, | |
| request.session_id, | |
| request.history or [] | |
| ) | |
| log.info(f"聊天响应生成成功,会话ID: {session_id}") | |
| return ChatResponse( | |
| reply=reply, | |
| session_id=session_id, | |
| status_info=status_info, | |
| history=history | |
| ) | |
| except Exception as e: | |
| log.error(f"❌ Chat endpoint error: {e}", exc_info=True) | |
| raise HTTPException( | |
| status_code=500, | |
| detail="Internal Server Error: Failed to process chat request." | |
| ) | |
| async def reset_session(session_id: str): | |
| """重置会话端点""" | |
| if not SERVICE_READY or not assistant: | |
| raise HTTPException( | |
| status_code=503, | |
| detail="Service Unavailable" | |
| ) | |
| try: | |
| assistant.session_manager.reset(session_id) | |
| log.info(f"会话重置成功: {session_id}") | |
| return { | |
| "message": "Session reset successfully", | |
| "session_id": session_id, | |
| "status": "success" | |
| } | |
| except Exception as e: | |
| log.error(f"❌ Reset session error: {e}") | |
| raise HTTPException( | |
| status_code=500, | |
| detail="Failed to reset session" | |
| ) | |
| # --- 全局异常处理 --- | |
| async def global_exception_handler(request, exc): | |
| """全局异常处理器""" | |
| log.error(f"❌ 未处理的异常: {exc}", exc_info=True) | |
| return JSONResponse( | |
| status_code=500, | |
| content={"detail": "Internal server error", "message": "请稍后重试"} | |
| ) | |
| # HuggingFace Spaces 和本地运行配置 | |
| if __name__ == "__main__": | |
| import uvicorn | |
| log.info("🔧 本地开发模式启动...") | |
| uvicorn.run( | |
| app, | |
| host="0.0.0.0", | |
| port=7860, | |
| reload=True, | |
| log_level="info" | |
| ) |