Spaces:
Sleeping
使用 FastAPI 搭建 Gemini API 转发代理教程
1. 项目简介
本项目旨在搭建一个基于 FastAPI 的通用 API 转发代理,主要用于转发对 Google Gemini API(特别是其 OpenAI 兼容 API)的请求。通过此代理,您可以解决直接访问 Gemini API 可能遇到的地域限制、集中管理 API 密钥以及处理客户端请求头兼容性等问题。
2. 核心功能
- 代理认证:代理自身支持 API 密钥认证,确保只有授权客户端才能使用代理服务。
- 请求转发:接收来自客户端的 HTTP 请求(GET, POST, PUT, DELETE),并将其转发到预配置的目标 API。
- 请求/响应处理:处理请求头、查询参数和请求体,并将目标 API 的响应原封不动地返回给客户端。
- 环境变量配置:支持通过
.env文件配置代理自身的认证密钥 (PROXY_API_KEY)、目标 API 的基 URL (GEMINI_BASE_URL) 和认证信息 (GEMINI_API_KEY)。 - 健康检查:提供一个简单的
/health端点,用于验证代理服务是否正常运行。 - User-Agent 修改:强制将转发请求的
User-Agent头设置为curl/8.7.1,以解决某些客户端(如 Postman)可能遇到的兼容性问题。
3. 技术栈
- Python 3.9+
- FastAPI:高性能 Python Web 框架。
- Uvicorn:ASGI 服务器。
- httpx:异步 HTTP 客户端。
- python-dotenv:环境变量管理。
4. 环境搭建与部署
4.1. 创建虚拟环境并安装依赖
建议使用 conda 或 venv 创建独立的 Python 虚拟环境:
conda create -n airs python=3.9
conda activate airs
在项目根目录创建 requirements.txt 文件,并添加以下内容:
fastapi
uvicorn[standard]
httpx
python-dotenv
然后安装依赖:
pip install -r requirements.txt
4.2. 配置环境变量
在项目根目录创建 .env 文件,并配置代理自身的 API 密钥、Gemini API 密钥和 OpenAI 兼容 API 的 Base URL:
PROXY_API_KEY="YOUR_PROXY_API_KEY"
GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
GEMINI_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai"
请将 YOUR_PROXY_API_KEY 替换为您为代理设置的密钥,将 YOUR_GEMINI_API_KEY 替换为您的实际 Gemini API 密钥。
4.3. app.py 代码实现
创建 app.py 文件,并添加以下代码:
# uvicorn app:app --host 0.0.0.0 --port 7860 --reload
from fastapi import FastAPI, Request, HTTPException, Depends, status
from fastapi.responses import Response
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import httpx
import os
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
# 从环境变量获取代理自身的API密钥
PROXY_API_KEY = os.getenv("PROXY_API_KEY")
# 定义HTTPBearer安全方案
security = HTTPBearer()
# 依赖函数:验证代理的API密钥
def verify_proxy_api_key(credentials: HTTPAuthorizationCredentials = Depends(security)):
if not PROXY_API_KEY or credentials.credentials != PROXY_API_KEY:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid or missing proxy API key",
headers={"WWW-Authenticate": "Bearer"},
)
return credentials.credentials
app = FastAPI(title="Gemini Proxy API")
@app.get("/")
def greet_json():
return {"Hello": "World!"}
# 3. 健康检查接口(可选,用于验证服务是否正常)
@app.get("/health")
async def health_check():
return {"status": "ok", "message": "Proxy service is running."}
# 1. 配置Gemini真实信息
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
GEMINI_BASE_URL = os.getenv("GEMINI_BASE_URL")
print(f"Using Gemini Base URL: {GEMINI_BASE_URL}")
print(f"Using Gemini API Key: {GEMINI_API_KEY}")
# 2. 通用转发接口(匹配Gemini的/predict等端点,路径动态匹配)
@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
async def proxy_gemini(request: Request, path: str, proxy_api_key: str = Depends(verify_proxy_api_key)): # 添加代理认证依赖
# 拼接Gemini真实请求URL
gemini_url = f"{GEMINI_BASE_URL}/{path}"
# 提取客户端请求的headers和body,透传给Gemini
client_headers = dict(request.headers)
# 移除FastAPI自带的Host头,避免Gemini校验报错
client_headers.pop("host", None)
# 将User-Agent改为curl/8.7.1,以模拟curl请求
client_headers["User-Agent"] = "curl/8.7.1"
# 添加Authorization头,用于Gemini的OpenAI兼容API
if GEMINI_API_KEY:
client_headers["Authorization"] = f"Bearer {GEMINI_API_KEY}"
try:
# 读取客户端请求体
client_body = await request.body()
# 使用httpx异步客户端发起请求
async with httpx.AsyncClient() as client:
response = await client.request(
method=request.method,
url=gemini_url,
headers=client_headers,
content=client_body,
timeout=30
)
# 将Gemini的响应透传给客户端
return Response(
content=response.content,
status_code=response.status_code,
headers=dict(response.headers)
)
except httpx.RequestError as e:
raise HTTPException(status_code=500, detail=f"转发请求失败:{str(e)}")
except httpx.HTTPStatusError as e:
raise HTTPException(status_code=e.response.status_code, detail=f"目标API返回错误:{e.response.text}")
except Exception as e:
raise HTTPException(status_code=500, detail=f"转发失败:{str(e)}")
4.4. 运行应用程序
在项目根目录,激活您的虚拟环境并运行 FastAPI 应用:
conda activate airs
uvicorn app:app --host 0.0.0.0 --port 7860 --reload
应用程序将在 http://0.0.0.0:7860 上运行。
5. 如何使用代理
5.1. 健康检查
您可以通过访问 /health 端点来检查代理服务是否正常运行:
curl -X GET http://0.0.0.0:7860/health
预期响应:
{"status":"ok","message":"Proxy service is running."}
5.2. 调用 Gemini OpenAI 兼容 API
要通过代理调用 Gemini 模型(例如 gemini-2.5-flash-preview-05-20),您需要向代理的 /v1/chat/completions 端点发送一个 POST 请求,并在请求体中指定模型名称和消息。同时,您需要在请求头中包含代理自身的 API 密钥。
以下是一个 curl 命令示例(请将 YOUR_PROXY_API_KEY 替换为您的实际代理密钥):
curl -X POST http://0.0.0.0:7860/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_PROXY_API_KEY" \
-d '{
"model": "gemini-2.5-flash-preview-05-20",
"messages": [
{
"role": "user",
"content": "你好,请介绍一下你自己。"
}
],
"temperature": 0.7
}'
如果您将代理部署到 Hugging Face Spaces,例如部署在 https://airsltd-superproxy.hf.space,则 curl 命令应如下所示:
curl -X POST https://airsltd-superproxy.hf.space/v1/chat/completions \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_PROXY_API_KEY' \
--data '{
"model": "gemini-2.5-flash-preview-05-20",
"messages": [
{
"role": "user",
"content": "你好,请介绍一下你自己。"
}
],
"temperature": 0.7
}'
6. 常见问题与解决方案
**代理认证失败 (401 Unauthorized)**:
- 问题:当您尝试调用代理时,收到
401 Unauthorized错误,并提示“Invalid or missing proxy API key”。 - 原因:这表示您没有在请求头中提供正确的
Authorization: Bearer YOUR_PROXY_API_KEY,或者PROXY_API_KEY环境变量未在代理部署环境中正确设置。 - 解决方案:确保您的客户端请求包含正确的
Authorization: Bearer YOUR_PROXY_API_KEY头,并且YOUR_PROXY_API_KEY与.env文件中配置的值一致。如果部署在 Hugging Face Spaces,请确保 Space 的环境变量中已设置PROXY_API_KEY。
- 问题:当您尝试调用代理时,收到
“User location is not supported for the API use.”:此错误来自 Gemini API,表明您的请求源 IP 地址所在的区域不受 Gemini API 支持。这通常发生在本地测试时。部署代理到支持的区域(例如 Hugging Face Spaces)可以解决此问题。
Postman “Error: incorrect header check”:此错误通常是由于 Postman 自动添加的某些请求头与部署环境或代理不兼容。本项目已通过强制设置
User-Agent: curl/8.7.1来尝试解决此问题。如果问题仍然存在,请检查 Postman 发送的其他请求头,并尝试禁用非必要的头部。