# 导入必要的库 import os import time import base64 from dotenv import load_dotenv from fastapi import FastAPI, Request, HTTPException, Depends, status from fastapi.responses import HTMLResponse, JSONResponse, RedirectResponse from fastapi.staticfiles import StaticFiles # from fastapi.templating import Jinja2Templates # 如果前端是纯静态 HTML+JS,则不需要 from fastapi import APIRouter # 导入 APIRouter from typing import List, Dict, Any, Optional # 导入类型提示 import logging # 导入日志库 import asyncio # 导入 asyncio # 导入自定义模块 from app.api.auth import get_auth_token # 从 auth 模块导入认证依赖,更改为 get_auth_token from app.api.metrics import service_metrics, call_records, MAX_RECORDS, get_current_metrics, get_current_records # 从 metrics 模块导入指标和记录获取函数 from app.api.gemini_proxy import router as gemini_proxy_router # 导入 gemini_proxy 模块 from app.api.metrics import router as metrics_router # 导入 metrics 模块的路由器 # 加载环境变量 load_dotenv() # 强制将日志级别设置为 DEBUG,以便调试认证问题 log_level = logging.WARNING # 配置日志 logging.basicConfig(level=log_level, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) # 禁用或调整 Uvicorn 自身的访问日志,避免过多 INFO 级别输出 # Uvicorn 默认使用 'uvicorn.access' 和 'uvicorn.error' # 可以通过修改其 logger 级别来控制 uvicorn_access_logger = logging.getLogger("uvicorn.access") uvicorn_access_logger.setLevel(logging.WARNING) # 让 Uvicorn 的访问日志级别与应用日志级别一致 uvicorn_error_logger = logging.getLogger("uvicorn.error") uvicorn_error_logger.setLevel(logging.ERROR) # 错误日志保持 ERROR 级别 # 初始化 FastAPI 应用 app = FastAPI(title="Gemini Cookies Proxy", description="基于 Gemini cookies 的代理中转服务") # 挂载静态文件目录 app.mount("/static", StaticFiles(directory="app/static"), name="static") # 配置模板引擎 (如果需要服务器端渲染 HTML) # templates = Jinja2Templates(directory="app/static") # 如果前端是纯静态 HTML+JS,则不需要 # 包含 gemini_proxy 模块的路由器 app.include_router(gemini_proxy_router, prefix="/v1", dependencies=[Depends(get_auth_token)]) # 更改为 get_auth_token # 包含 metrics 模块的路由器 app.include_router(metrics_router, prefix="/v1", dependencies=[Depends(get_auth_token)]) # 更改为 get_auth_token # 示例:简单的根路由,重定向到登录页面或主页面 @app.get("/", include_in_schema=False) async def read_root(): # 重定向到登录页面 return RedirectResponse(url="/static/login.html") # 健康检查接口,现在带 /v1 前缀,并需要认证令牌认证 @app.get("/v1/health", dependencies=[Depends(get_auth_token)]) # 更改为 get_auth_token async def health_check_v1(): # 重命名函数以避免冲突 """ 健康检查接口,返回服务状态。 """ return JSONResponse(content={"status": "ok"}) # 根路径健康检查接口,不带任何依赖,用于初步验证服务是否运行 @app.get("/health") async def health_check_root(): """ 根路径健康检查接口,返回服务状态。 """ return JSONResponse(content={"status": "ok", "message": "Root health check successful"}) # 处理 favicon.ico 请求 @app.get("/favicon.ico", include_in_schema=False) async def get_favicon(): return RedirectResponse(url="/static/favicon.ico") # 启动命令示例 (在 Dockerfile 中使用) # uvicorn main:app --host 0.0.0.0 --port $PORT