初次提交
This commit is contained in:
166
backend/main.py
Normal file
166
backend/main.py
Normal 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
|
||||
)
|
||||
Reference in New Issue
Block a user