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 )