import json import os import uuid import time import multiprocessing import sys from contextlib import asynccontextmanager import uvicorn from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from routes.file_manager import router as file_manager_router import logging from utils.log_util.logger import init_with_fastapi # Initialize logger logger = logging.getLogger('app') # Import route modules from routes import chat, files, projects, system, skill_manager @asynccontextmanager async def lifespan(app: FastAPI): """FastAPI 应用生命周期管理""" # 启动时初始化 logger.info("Starting up...") from agent.db_pool_manager import ( init_global_db_pool, get_db_pool_manager, close_global_db_pool ) from agent.checkpoint_manager import ( init_global_checkpointer, close_global_checkpointer ) from agent.chat_history_manager import ( init_chat_history_manager, close_chat_history_manager ) from agent.memori_manager import ( init_global_memori, close_global_memori ) from utils.settings import CHECKPOINT_CLEANUP_ENABLED, MEMORI_ENABLED, MEMORI_API_KEY, CHECKPOINT_DB_URL # 1. 初始化共享的数据库连接池 db_pool_manager = await init_global_db_pool() logger.info("Global DB pool initialized") # 2. 初始化 checkpoint (使用共享连接池) await init_global_checkpointer(db_pool_manager.pool) logger.info("Global checkpointer initialized") # 3. 初始化 chat_history (使用共享连接池) await init_chat_history_manager(db_pool_manager.pool) logger.info("Chat history manager initialized") # 4. 初始化 Memori 长期记忆系统 (如果启用) if MEMORI_ENABLED: try: await init_global_memori( db_pool=db_pool_manager.pool, db_url=CHECKPOINT_DB_URL, api_key=MEMORI_API_KEY ) logger.info("Memori long-term memory initialized") except Exception as e: logger.warning(f"Memori initialization failed (continuing without): {e}") # 5. 启动 checkpoint 清理调度器 if CHECKPOINT_CLEANUP_ENABLED: # 启动时立即执行一次清理 try: result = await db_pool_manager.cleanup_old_checkpoints() logger.info(f"Startup cleanup completed: {result}") except Exception as e: logger.warning(f"Startup cleanup failed (non-fatal): {e}") # 启动定时清理调度器 db_pool_manager.start_cleanup_scheduler() logger.info("Checkpoint cleanup scheduler started") yield # 关闭时清理(按相反顺序) logger.info("Shutting down...") # 关闭 Memori if MEMORI_ENABLED: try: await close_global_memori() logger.info("Memori long-term memory closed") except Exception as e: logger.warning(f"Memori close failed (non-fatal): {e}") await close_chat_history_manager() logger.info("Chat history manager closed") await close_global_checkpointer() logger.info("Global checkpointer closed") await close_global_db_pool() logger.info("Global DB pool closed") app = FastAPI(title="Database Assistant API", version="1.0.0", lifespan=lifespan) init_with_fastapi(app) # 挂载public文件夹为静态文件服务 app.mount("/public", StaticFiles(directory="public"), name="static") # 添加CORS中间件,支持前端页面 app.add_middleware( CORSMiddleware, allow_origins=["*"], # 在生产环境中应该设置为具体的前端域名 allow_credentials=True, allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"], allow_headers=[ "Authorization", "Content-Type", "Accept", "Origin", "User-Agent", "DNT", "Cache-Control", "Range", "X-Requested-With" ], ) # Include all route modules app.include_router(chat.router) app.include_router(files.router) app.include_router(projects.router) app.include_router(system.router) app.include_router(skill_manager.router) # 注册文件管理API路由 app.include_router(file_manager_router) if __name__ == "__main__": # 启动 FastAPI 应用 logger.info("Starting FastAPI server...") logger.info("File Manager API available at: http://localhost:8001/api/v1/files") logger.info("Web Interface available at: http://localhost:8001/public/file-manager.html") uvicorn.run(app, host="0.0.0.0", port=8001)