"""WPS Bot Game - FastAPI主应用""" import logging from fastapi import FastAPI from fastapi.responses import JSONResponse from contextlib import asynccontextmanager import asyncio from config import APP_CONFIG, SESSION_TIMEOUT from core.middleware import ConcurrencyLimitMiddleware from core.database import get_db from routers import callback, health # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """应用生命周期管理""" # 启动时 logger.info("=" * 50) logger.info("WPS Bot Game 启动中...") logger.info("=" * 50) # 初始化数据库 db = get_db() logger.info(f"数据库初始化完成: {db.db_path}") # 启动后台清理任务 cleanup_task = asyncio.create_task(periodic_cleanup()) logger.info("后台清理任务已启动") logger.info("应用启动完成!") yield # 关闭时 logger.info("应用正在关闭...") cleanup_task.cancel() try: await cleanup_task except asyncio.CancelledError: pass db.close() logger.info("应用已关闭") async def periodic_cleanup(): """定期清理过期会话""" while True: try: await asyncio.sleep(300) # 每5分钟执行一次 db = get_db() db.cleanup_old_sessions(SESSION_TIMEOUT) except asyncio.CancelledError: break except Exception as e: logger.error(f"清理任务错误: {e}", exc_info=True) # 创建FastAPI应用 app = FastAPI(**APP_CONFIG, lifespan=lifespan) # 添加并发限制中间件 app.add_middleware(ConcurrencyLimitMiddleware) # 注册路由 app.include_router(callback.router, prefix="/api", tags=["callback"]) app.include_router(health.router, tags=["health"]) @app.get("/") async def root(): """根路径""" return JSONResponse({ "message": "WPS Bot Game API", "version": "1.0.0", "status": "running" }) @app.exception_handler(Exception) async def global_exception_handler(request, exc): """全局异常处理""" logger.error(f"未捕获的异常: {exc}", exc_info=True) return JSONResponse( status_code=500, content={"error": "Internal Server Error", "detail": str(exc)} ) if __name__ == "__main__": import uvicorn uvicorn.run( "app:app", host="0.0.0.0", port=11000, workers=1, limit_concurrency=5, log_level="info" )