mirror of
https://github.com/fawney19/Aether.git
synced 2026-01-09 19:22:26 +08:00
- 新增 Management Token(访问令牌)功能,支持创建、更新、删除和管理 - 前端添加访问令牌管理页面,支持普通用户和管理员 - 后端实现完整的令牌生命周期管理 API - 添加数据库迁移脚本创建 management_tokens 表 - Nginx 配置添加 gzip 压缩,优化响应传输 - Dialog 组件添加 persistent 属性,防止意外关闭 - 为管理后台 API 添加详细的中文文档注释 - 简化多处类型注解,统一代码风格
158 lines
4.3 KiB
Python
158 lines
4.3 KiB
Python
"""
|
||
Gemini API 专属端点
|
||
|
||
托管 Gemini API 相关路由:
|
||
- /v1beta/models/{model}:generateContent
|
||
- /v1beta/models/{model}:streamGenerateContent
|
||
|
||
注意:
|
||
- Gemini API 的 model 在 URL 路径中,而不是请求体中
|
||
- /v1beta/models (列表) 和 /v1beta/models/{model} (详情) 由 models.py 统一处理
|
||
"""
|
||
|
||
from fastapi import APIRouter, Depends, Request
|
||
from sqlalchemy.orm import Session
|
||
|
||
from src.api.base.pipeline import ApiRequestPipeline
|
||
from src.api.handlers.gemini import build_gemini_adapter
|
||
from src.api.handlers.gemini_cli import build_gemini_cli_adapter
|
||
from src.core.api_format_metadata import get_api_format_definition
|
||
from src.core.enums import APIFormat
|
||
from src.database import get_db
|
||
|
||
# 从配置获取路径前缀
|
||
_gemini_def = get_api_format_definition(APIFormat.GEMINI)
|
||
|
||
router = APIRouter(tags=["Gemini API"], prefix=_gemini_def.path_prefix)
|
||
pipeline = ApiRequestPipeline()
|
||
|
||
|
||
def _is_cli_request(request: Request) -> bool:
|
||
"""
|
||
判断是否为 CLI 请求
|
||
|
||
检查顺序:
|
||
1. x-app header 包含 "cli"
|
||
2. user-agent 包含 "GeminiCLI" 或 "gemini-cli"
|
||
"""
|
||
# 检查 x-app header
|
||
x_app = request.headers.get("x-app", "")
|
||
if "cli" in x_app.lower():
|
||
return True
|
||
|
||
# 检查 user-agent
|
||
user_agent = request.headers.get("user-agent", "")
|
||
user_agent_lower = user_agent.lower()
|
||
if "geminicli" in user_agent_lower or "gemini-cli" in user_agent_lower:
|
||
return True
|
||
|
||
return False
|
||
|
||
|
||
@router.post("/v1beta/models/{model}:generateContent")
|
||
async def generate_content(
|
||
model: str,
|
||
http_request: Request,
|
||
db: Session = Depends(get_db),
|
||
):
|
||
"""
|
||
Gemini generateContent API
|
||
|
||
兼容 Google Gemini API 格式的代理接口(非流式)。
|
||
|
||
**认证方式**:
|
||
- `x-goog-api-key` 请求头,或
|
||
- `?key=` URL 参数
|
||
|
||
**请求格式**:
|
||
```json
|
||
{
|
||
"contents": [{"parts": [{"text": "Hello"}]}]
|
||
}
|
||
```
|
||
|
||
**路径参数**:
|
||
- `model`: 模型名称,如 gemini-2.0-flash
|
||
"""
|
||
# 根据 user-agent 或 x-app header 选择适配器
|
||
if _is_cli_request(http_request):
|
||
adapter = build_gemini_cli_adapter()
|
||
else:
|
||
adapter = build_gemini_adapter()
|
||
|
||
return await pipeline.run(
|
||
adapter=adapter,
|
||
http_request=http_request,
|
||
db=db,
|
||
mode=adapter.mode,
|
||
api_format_hint=adapter.allowed_api_formats[0],
|
||
# 将 model 注入到请求体中,stream 用于内部判断流式模式
|
||
path_params={"model": model, "stream": False},
|
||
)
|
||
|
||
|
||
@router.post("/v1beta/models/{model}:streamGenerateContent")
|
||
async def stream_generate_content(
|
||
model: str,
|
||
http_request: Request,
|
||
db: Session = Depends(get_db),
|
||
):
|
||
"""
|
||
Gemini streamGenerateContent API
|
||
|
||
兼容 Google Gemini API 格式的代理接口(流式)。
|
||
|
||
**认证方式**:
|
||
- `x-goog-api-key` 请求头,或
|
||
- `?key=` URL 参数
|
||
|
||
**路径参数**:
|
||
- `model`: 模型名称,如 gemini-2.0-flash
|
||
|
||
注意: Gemini API 通过 URL 端点区分流式/非流式,不需要在请求体中添加 stream 字段
|
||
"""
|
||
# 根据 user-agent 或 x-app header 选择适配器
|
||
if _is_cli_request(http_request):
|
||
adapter = build_gemini_cli_adapter()
|
||
else:
|
||
adapter = build_gemini_adapter()
|
||
|
||
return await pipeline.run(
|
||
adapter=adapter,
|
||
http_request=http_request,
|
||
db=db,
|
||
mode=adapter.mode,
|
||
api_format_hint=adapter.allowed_api_formats[0],
|
||
# model 注入到请求体,stream 用于内部判断流式模式(不发送到 API)
|
||
path_params={"model": model, "stream": True},
|
||
)
|
||
|
||
|
||
# 兼容 v1 路径(部分 SDK 可能使用 generateContent)
|
||
@router.post("/v1/models/{model}:generateContent")
|
||
async def generate_content_v1(
|
||
model: str,
|
||
http_request: Request,
|
||
db: Session = Depends(get_db),
|
||
):
|
||
"""
|
||
Gemini generateContent API (v1 兼容)
|
||
|
||
v1 版本 API 端点,兼容部分使用旧版路径的 SDK。
|
||
"""
|
||
return await generate_content(model, http_request, db)
|
||
|
||
|
||
@router.post("/v1/models/{model}:streamGenerateContent")
|
||
async def stream_generate_content_v1(
|
||
model: str,
|
||
http_request: Request,
|
||
db: Session = Depends(get_db),
|
||
):
|
||
"""
|
||
Gemini streamGenerateContent API (v1 兼容)
|
||
|
||
v1 版本流式 API 端点,兼容部分使用旧版路径的 SDK。
|
||
"""
|
||
return await stream_generate_content(model, http_request, db)
|