Files
WPSBot/app.py

142 lines
3.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""WPS Bot Game - FastAPI主应用"""
import logging
import argparse
import os
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from contextlib import asynccontextmanager
import asyncio
from config import APP_CONFIG, SESSION_TIMEOUT, SetWebhookURL, GetWebhookURL
from core.middleware import ConcurrencyLimitMiddleware
from core.database import get_db
from routers import callback, health, private
# 配置日志
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.include_router(private.router, prefix="/api", tags=["private"])
@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)}
)
def parse_args():
"""解析命令行参数"""
parser = argparse.ArgumentParser(description='WPS Bot Game')
parser.add_argument('--webhook-url', '-w',
help='WPS Webhook URL')
parser.add_argument('--host', '-H',
default='0.0.0.0',
help='服务器主机地址 (默认: 0.0.0.0)')
parser.add_argument('--port', '-p',
type=int, default=11000,
help='服务器端口 (默认: 11000)')
parser.add_argument('--workers',
type=int, default=1,
help='工作进程数 (默认: 1)')
parser.add_argument('--log-level',
default='info',
choices=['debug', 'info', 'warning', 'error'],
help='日志级别 (默认: info)')
return parser.parse_args()
if __name__ == "__main__":
import uvicorn
# 解析命令行参数
args = parse_args()
# 如果提供了webhook URL设置环境变量
if args.webhook_url:
SetWebhookURL(args.webhook_url)
logger.info(f"设置Webhook URL: {args.webhook_url}")
# 启动服务器
uvicorn.run(
"app:app",
host=args.host,
port=args.port,
workers=args.workers,
limit_concurrency=5,
log_level=args.log_level
)