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 发送的其他请求头,并尝试禁用非必要的头部。