Files
WPSBot/app.py
2025-10-28 13:00:35 +08:00

108 lines
2.6 KiB
Python

"""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"
)