148 lines
3.6 KiB
Python
148 lines
3.6 KiB
Python
#!/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
|
||
)
|
||
from sqlalchemy import text
|
||
|
||
|
||
@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:
|
||
# 使用 text() 包裹 SQL 语句
|
||
db.execute(text("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
|
||
) |