Spaces:
Sleeping
Sleeping
File size: 8,903 Bytes
6a5b28d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# 使用 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 虚拟环境:
```bash
conda create -n airs python=3.9
conda activate airs
```
在项目根目录创建 `requirements.txt` 文件,并添加以下内容:
```
fastapi
uvicorn[standard]
httpx
python-dotenv
```
然后安装依赖:
```bash
pip install -r requirements.txt
```
### 4.2. 配置环境变量
在项目根目录创建 `.env` 文件,并配置代理自身的 API 密钥、Gemini API 密钥和 OpenAI 兼容 API 的 Base URL:
```dotenv
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` 文件,并添加以下代码:
```python
# 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 应用:
```bash
conda activate airs
uvicorn app:app --host 0.0.0.0 --port 7860 --reload
```
应用程序将在 `http://0.0.0.0:7860` 上运行。
## 5. 如何使用代理
### 5.1. 健康检查
您可以通过访问 `/health` 端点来检查代理服务是否正常运行:
```bash
curl -X GET http://0.0.0.0:7860/health
```
预期响应:
```json
{"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` 替换为您的实际代理密钥):
```bash
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` 命令应如下所示:
```bash
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 发送的其他请求头,并尝试禁用非必要的头部。
|