初次提交

This commit is contained in:
2025-10-14 20:05:29 +08:00
commit 6e4e48fdd2
673 changed files with 437006 additions and 0 deletions

166
backend/main.py Normal file
View File

@@ -0,0 +1,166 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
import sys
import os
from pathlib import Path
from datetime import datetime
# 处理PyInstaller打包后的资源路径
def get_resource_path(relative_path: str) -> str:
"""获取资源文件的绝对路径,兼容开发环境和打包环境"""
try:
# PyInstaller创建的临时文件夹路径
base_path = sys._MEIPASS
except AttributeError:
# 正常的开发环境
base_path = os.path.dirname(os.path.abspath(__file__))
return os.path.join(base_path, relative_path)
# 确保app模块可以正确导入
def setup_app_imports():
"""设置模块导入路径确保打包后能正确导入app模块"""
current_dir = os.path.dirname(os.path.abspath(__file__))
if current_dir not in sys.path:
sys.path.insert(0, current_dir)
# 如果是打包后的环境添加MEIPASS到sys.path
if hasattr(sys, '_MEIPASS'):
meipass = sys._MEIPASS
if meipass not in sys.path:
sys.path.insert(0, meipass)
# 设置导入路径
setup_app_imports()
from app.core.config import settings
from app.api.v1.endpoints import health, auth, files
# 简单的日志打印函数
def log_info(message):
"""打印INFO级别日志"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] INFO: {message}")
def log_error(message):
"""打印ERROR级别日志"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] ERROR: {message}")
def log_debug(message):
"""打印DEBUG级别日志"""
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] DEBUG: {message}")
from fastapi import Request
import json
async def log_requests_middleware(request: Request, call_next):
"""记录所有API请求的入参不消耗请求体"""
start_time = datetime.now()
# 获取请求基本信息
method = request.method
url = str(request.url)
client_ip = request.client.host if request.client else "unknown"
# 立即打印基本信息
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: === API请求开始 ===")
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 方法: {method}")
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: URL: {url}")
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 客户端IP: {client_ip}")
# 获取查询参数
query_params = dict(request.query_params)
if query_params:
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 查询参数: {query_params}")
else:
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 查询参数: 无")
# 获取请求头信息(只记录非敏感信息)
content_type = request.headers.get("content-type", "")
content_length = request.headers.get("content-length", "")
user_agent = request.headers.get("user-agent", "")
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: Content-Type: {content_type}")
if content_length:
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: Content-Length: {content_length}字节")
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: User-Agent: {user_agent}")
# 注意:这里不读取请求体,避免消耗它
if method in ["POST", "PUT", "PATCH"]:
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 请求体: 将在路由处理函数中记录")
print(f"[{start_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: === 开始处理请求 ===")
# 处理请求
try:
response = await call_next(request)
# 记录响应信息
end_time = datetime.now()
duration = (end_time - start_time).total_seconds()
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: === 请求处理完成 ===")
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 状态码: {response.status_code}")
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: 处理耗时: {duration:.3f}")
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] INFO: === 响应记录完成 ===")
return response
except Exception as e:
end_time = datetime.now()
duration = (end_time - start_time).total_seconds()
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] ERROR: === 请求处理出错 ===")
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] ERROR: 错误: {str(e)}")
print(f"[{end_time.strftime('%Y-%m-%d %H:%M:%S')}] ERROR: 处理耗时: {duration:.3f}")
raise
# 确保logs目录存在
logs_dir = get_resource_path("logs")
os.makedirs(logs_dir, exist_ok=True)
# 打印启动信息
log_info("=== Server Starting ===")
log_info(f"Python version: {sys.version}")
log_info(f"Working directory: {os.getcwd()}")
log_info("Simple print logger configured")
app = FastAPI(
title="云盘应用 API",
description="现代化的云存储Web应用后端API",
version="1.0.0",
docs_url="/docs",
redoc_url="/redoc"
)
# 添加请求日志中间件在CORS之前
app.middleware("http")(log_requests_middleware)
# CORS中间件
app.add_middleware(
CORSMiddleware,
allow_origins=settings.ALLOWED_HOSTS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 包含路由
app.include_router(health.router, prefix="/api/v1", tags=["health"])
app.include_router(auth.router, prefix="/api/v1/auth", tags=["authentication"])
app.include_router(files.router, prefix="/api/v1/files", tags=["files"])
@app.get("/")
async def root():
return {"message": "云盘应用 API", "version": "1.0.1"}
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8002,
reload=True if settings.ENVIRONMENT == "development" else False
)