Files
PerToolBoxServer/backend/main.py
2026-04-01 15:35:27 +08:00

146 lines
3.5 KiB
Python
Raw 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.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
PerToolBox Server - FastAPI 主程序
Copyright (C) 2024 Sea Network Technology Studio
Author: Canglan <admin@sea-studio.top>
License: AGPL v3
API 文档: /api/v1/docs
健康检查: /health
"""
from contextlib import asynccontextmanager
from fastapi import FastAPI, Depends
from fastapi.middleware.cors import CORSMiddleware
from fastapi.openapi.utils import get_openapi
from sqlalchemy.orm import Session
from .config import settings
from .database import engine, Base, get_db
from .middleware.logging import log_requests
from .middleware.rate_limit import setup_rate_limit
from .utils.logger import logger
from .routers.v1 import (
auth_router, user_router, todos_router,
notes_router, tools_router, stats_router
)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""应用生命周期管理"""
logger.info(f"启动 {settings.APP_NAME} v1.0.0")
logger.info(f"环境: {settings.ENVIRONMENT}")
logger.info(f"调试模式: {settings.DEBUG}")
# 创建数据库表
Base.metadata.create_all(bind=engine)
logger.info("数据库表初始化完成")
yield
logger.info("应用关闭")
app = FastAPI(
title=settings.APP_NAME,
description="""
## PerToolBox 个人工具箱 API v1
提供以下功能:
- ✅ 用户认证(手机/邮箱验证码登录)
- ✅ 待办事项管理
- ✅ 便签本
- ✅ 密码生成器
- ✅ 二维码生成
- ✅ 加密工具箱哈希、Base64、URL、AES
- ✅ JSON 校验与格式化
- ✅ 热度统计(页面访问次数)
### 版权信息
- © 2024 Sea Network Technology Studio
- Author: Canglan <admin@sea-studio.top>
- License: AGPL v3
""",
version="1.0.0",
docs_url="/api/v1/docs",
redoc_url="/api/v1/redoc",
openapi_url="/api/v1/openapi.json",
lifespan=lifespan
)
# CORS 配置
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 限流配置
setup_rate_limit(app)
# 日志中间件
app.middleware("http")(log_requests)
# 健康检查
@app.get("/health")
async def health_check(db: Session = Depends(get_db)):
try:
db.execute("SELECT 1")
return {
"status": "healthy",
"database": "connected",
"version": "1.0.0"
}
except Exception as e:
logger.error(f"健康检查失败: {e}")
return {
"status": "unhealthy",
"database": str(e)
}
# 注册路由
app.include_router(auth_router)
app.include_router(user_router)
app.include_router(todos_router)
app.include_router(notes_router)
app.include_router(tools_router)
app.include_router(stats_router)
# 自定义 OpenAPI
def custom_openapi():
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title=settings.APP_NAME,
version="1.0.0",
description=app.description,
routes=app.routes,
)
openapi_schema["info"]["x-copyright"] = "Sea Network Technology Studio"
openapi_schema["info"]["x-author"] = "Canglan <admin@sea-studio.top>"
openapi_schema["info"]["x-license"] = "AGPL v3"
app.openapi_schema = openapi_schema
return app.openapi_schema
app.openapi = custom_openapi
if __name__ == "__main__":
import uvicorn
uvicorn.run(
"backend.main:app",
host="0.0.0.0",
port=8000,
reload=settings.DEBUG
)