geqintan commited on
Commit
6a5b28d
·
1 Parent(s): 1376244
.clinerules CHANGED
@@ -1,9 +1,11 @@
1
  # 自定义指令
2
  CUSTOM_INSTRUCTIONS = """
3
  # 自动激活conda环境
4
- # 在每次会话开始时,自动激活名为 'airs' 的conda环境。
5
  # 这确保了所有后续的Python相关命令都在正确的环境中执行。
6
- conda activate airs
 
 
7
  """
8
 
9
 
 
1
  # 自定义指令
2
  CUSTOM_INSTRUCTIONS = """
3
  # 自动激活conda环境
4
+ # 在每次会话开始时,自动检查当前conda环境。如果不是 'airs',则激活它。
5
  # 这确保了所有后续的Python相关命令都在正确的环境中执行。
6
+ if [ -z "$CONDA_DEFAULT_ENV" ] || [ "$CONDA_DEFAULT_ENV" != "airs" ]; then
7
+ conda activate airs
8
+ fi
9
  """
10
 
11
 
app.py CHANGED
@@ -1,13 +1,31 @@
1
  # uvicorn app:app --host 0.0.0.0 --port 7860 --reload
2
 
3
- from fastapi import FastAPI, Request, HTTPException
4
  from fastapi.responses import Response # 导入Response
 
5
  import httpx # 使用httpx替代requests,因为requests是同步的,而FastAPI是异步的
6
  import os
7
  from dotenv import load_dotenv
8
 
9
- # 加载环境变量(存储Gemini API密钥)
10
  load_dotenv()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  app = FastAPI(title="Gemini Proxy API")
12
 
13
  @app.get("/")
@@ -27,7 +45,7 @@ print(f"Using Gemini API Key: {GEMINI_API_KEY}")
27
 
28
  # 2. 通用转发接口(匹配Gemini的/predict等端点,路径动态匹配)
29
  @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
30
- async def proxy_gemini(request: Request, path: str):
31
  # 拼接Gemini真实请求URL
32
  gemini_url = f"{GEMINI_BASE_URL}/{path}"
33
 
 
1
  # uvicorn app:app --host 0.0.0.0 --port 7860 --reload
2
 
3
+ from fastapi import FastAPI, Request, HTTPException, Depends, status
4
  from fastapi.responses import Response # 导入Response
5
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials # 导入HTTPBearer和HTTPAuthorizationCredentials
6
  import httpx # 使用httpx替代requests,因为requests是同步的,而FastAPI是异步的
7
  import os
8
  from dotenv import load_dotenv
9
 
10
+ # 加载环境变量
11
  load_dotenv()
12
+
13
+ # 从环境变量获取代理自身的API密钥
14
+ PROXY_API_KEY = os.getenv("PROXY_API_KEY")
15
+
16
+ # 定义HTTPBearer安全方案
17
+ security = HTTPBearer()
18
+
19
+ # 依赖函数:验证代理的API密钥
20
+ def verify_proxy_api_key(credentials: HTTPAuthorizationCredentials = Depends(security)):
21
+ if not PROXY_API_KEY or credentials.credentials != PROXY_API_KEY:
22
+ raise HTTPException(
23
+ status_code=status.HTTP_401_UNAUTHORIZED,
24
+ detail="Invalid or missing proxy API key",
25
+ headers={"WWW-Authenticate": "Bearer"},
26
+ )
27
+ return credentials.credentials
28
+
29
  app = FastAPI(title="Gemini Proxy API")
30
 
31
  @app.get("/")
 
45
 
46
  # 2. 通用转发接口(匹配Gemini的/predict等端点,路径动态匹配)
47
  @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
48
+ async def proxy_gemini(request: Request, path: str, proxy_api_key: str = Depends(verify_proxy_api_key)): # 添加代理认证依赖
49
  # 拼接Gemini真实请求URL
50
  gemini_url = f"{GEMINI_BASE_URL}/{path}"
51
 
articles/fastapi-gemini-proxy-tutorial.md ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 使用 FastAPI 搭建 Gemini API 转发代理教程
2
+
3
+ ## 1. 项目简介
4
+
5
+ 本项目旨在搭建一个基于 FastAPI 的通用 API 转发代理,主要用于转发对 Google Gemini API(特别是其 OpenAI 兼容 API)的请求。通过此代理,您可以解决直接访问 Gemini API 可能遇到的地域限制、集中管理 API 密钥以及处理客户端请求头兼容性等问题。
6
+
7
+ ## 2. 核心功能
8
+
9
+ * **代理认证**:代理自身支持 API 密钥认证,确保只有授权客户端才能使用代理服务。
10
+ * **请求转发**:接收来自客户端的 HTTP 请求(GET, POST, PUT, DELETE),并将其转发到预配置的目标 API。
11
+ * **请求/响应处理**:处理请求头、查询参数和请求体,并将目标 API 的响应原封不动地返回给客户端。
12
+ * **环境变量配置**:支持通过 `.env` 文件配置代理自身的认证密钥 (`PROXY_API_KEY`)、目标 API 的基 URL (`GEMINI_BASE_URL`) 和认证信息 (`GEMINI_API_KEY`)。
13
+ * **健康检查**:提供一个简单的 `/health` 端点,用于验证代理服务是否正常运行。
14
+ * **User-Agent 修改**:强制将转发请求的 `User-Agent` 头设置为 `curl/8.7.1`,以解决某些客户端(如 Postman)可能遇到的兼容性问题。
15
+
16
+ ## 3. 技术栈
17
+
18
+ * **Python 3.9+**
19
+ * **FastAPI**:高性能 Python Web 框架。
20
+ * **Uvicorn**:ASGI 服务器。
21
+ * **httpx**:异步 HTTP 客户端。
22
+ * **python-dotenv**:环境变量管理。
23
+
24
+ ## 4. 环境搭建与部署
25
+
26
+ ### 4.1. 创建虚拟环境并安装依赖
27
+
28
+ 建议使用 `conda` 或 `venv` 创建独立的 Python 虚拟环境:
29
+
30
+ ```bash
31
+ conda create -n airs python=3.9
32
+ conda activate airs
33
+ ```
34
+
35
+ 在项目根目录创建 `requirements.txt` 文件,并添加以下内容:
36
+
37
+ ```
38
+ fastapi
39
+ uvicorn[standard]
40
+ httpx
41
+ python-dotenv
42
+ ```
43
+
44
+ 然后安装依赖:
45
+
46
+ ```bash
47
+ pip install -r requirements.txt
48
+ ```
49
+
50
+ ### 4.2. 配置环境变量
51
+
52
+ 在项目根目录创建 `.env` 文件,并配置代理自身的 API 密钥、Gemini API 密钥和 OpenAI 兼容 API 的 Base URL:
53
+
54
+ ```dotenv
55
+ PROXY_API_KEY="YOUR_PROXY_API_KEY"
56
+ GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
57
+ GEMINI_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai"
58
+ ```
59
+
60
+ 请将 `YOUR_PROXY_API_KEY` 替换为您为代理设置的密钥,将 `YOUR_GEMINI_API_KEY` 替换为您的实际 Gemini API 密钥。
61
+
62
+ ### 4.3. `app.py` 代码实现
63
+
64
+ 创建 `app.py` 文件,并添加以下代码:
65
+
66
+ ```python
67
+ # uvicorn app:app --host 0.0.0.0 --port 7860 --reload
68
+
69
+ from fastapi import FastAPI, Request, HTTPException, Depends, status
70
+ from fastapi.responses import Response
71
+ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
72
+ import httpx
73
+ import os
74
+ from dotenv import load_dotenv
75
+
76
+ # 加载环境变量
77
+ load_dotenv()
78
+
79
+ # 从环境变量获取代理自身的API密钥
80
+ PROXY_API_KEY = os.getenv("PROXY_API_KEY")
81
+
82
+ # 定义HTTPBearer安全方案
83
+ security = HTTPBearer()
84
+
85
+ # 依赖函数:验证代理的API密钥
86
+ def verify_proxy_api_key(credentials: HTTPAuthorizationCredentials = Depends(security)):
87
+ if not PROXY_API_KEY or credentials.credentials != PROXY_API_KEY:
88
+ raise HTTPException(
89
+ status_code=status.HTTP_401_UNAUTHORIZED,
90
+ detail="Invalid or missing proxy API key",
91
+ headers={"WWW-Authenticate": "Bearer"},
92
+ )
93
+ return credentials.credentials
94
+
95
+ app = FastAPI(title="Gemini Proxy API")
96
+
97
+ @app.get("/")
98
+ def greet_json():
99
+ return {"Hello": "World!"}
100
+
101
+ # 3. 健康检查接口(可选,用于验证服务是否正常)
102
+ @app.get("/health")
103
+ async def health_check():
104
+ return {"status": "ok", "message": "Proxy service is running."}
105
+
106
+ # 1. 配置Gemini真实信息
107
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
108
+ GEMINI_BASE_URL = os.getenv("GEMINI_BASE_URL")
109
+ print(f"Using Gemini Base URL: {GEMINI_BASE_URL}")
110
+ print(f"Using Gemini API Key: {GEMINI_API_KEY}")
111
+
112
+ # 2. 通用转发接口(匹配Gemini的/predict等端点,路径动态匹配)
113
+ @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
114
+ async def proxy_gemini(request: Request, path: str, proxy_api_key: str = Depends(verify_proxy_api_key)): # 添加代理认证依赖
115
+ # 拼接Gemini真实请求URL
116
+ gemini_url = f"{GEMINI_BASE_URL}/{path}"
117
+
118
+ # 提取客户端请求的headers和body,透传给Gemini
119
+ client_headers = dict(request.headers)
120
+ # 移除FastAPI自带的Host头,避免Gemini校验报错
121
+ client_headers.pop("host", None)
122
+
123
+ # 将User-Agent改为curl/8.7.1,以模拟curl请求
124
+ client_headers["User-Agent"] = "curl/8.7.1"
125
+
126
+ # 添加Authorization头,用于Gemini的OpenAI兼容API
127
+ if GEMINI_API_KEY:
128
+ client_headers["Authorization"] = f"Bearer {GEMINI_API_KEY}"
129
+
130
+ try:
131
+ # 读取客户端请求体
132
+ client_body = await request.body()
133
+
134
+ # 使用httpx异步客户端发起请求
135
+ async with httpx.AsyncClient() as client:
136
+ response = await client.request(
137
+ method=request.method,
138
+ url=gemini_url,
139
+ headers=client_headers,
140
+ content=client_body,
141
+ timeout=30
142
+ )
143
+
144
+ # 将Gemini的响应透传给客户端
145
+ return Response(
146
+ content=response.content,
147
+ status_code=response.status_code,
148
+ headers=dict(response.headers)
149
+ )
150
+
151
+ except httpx.RequestError as e:
152
+ raise HTTPException(status_code=500, detail=f"转发请求失败:{str(e)}")
153
+ except httpx.HTTPStatusError as e:
154
+ raise HTTPException(status_code=e.response.status_code, detail=f"目标API返回错误:{e.response.text}")
155
+ except Exception as e:
156
+ raise HTTPException(status_code=500, detail=f"转发失败:{str(e)}")
157
+ ```
158
+
159
+ ### 4.4. 运行应用程序
160
+
161
+ 在项目根目录,激活您的虚拟环境并运行 FastAPI 应用:
162
+
163
+ ```bash
164
+ conda activate airs
165
+ uvicorn app:app --host 0.0.0.0 --port 7860 --reload
166
+ ```
167
+
168
+ 应用程序将在 `http://0.0.0.0:7860` 上运行。
169
+
170
+ ## 5. 如何使用代理
171
+
172
+ ### 5.1. 健康检查
173
+
174
+ 您可以通过访问 `/health` 端点来检查代理服务是否正常运行:
175
+
176
+ ```bash
177
+ curl -X GET http://0.0.0.0:7860/health
178
+ ```
179
+
180
+ 预期响应:
181
+
182
+ ```json
183
+ {"status":"ok","message":"Proxy service is running."}
184
+ ```
185
+
186
+ ### 5.2. 调用 Gemini OpenAI 兼容 API
187
+
188
+ 要通过代理调用 Gemini 模型(例如 `gemini-2.5-flash-preview-05-20`),您需要向代理的 `/v1/chat/completions` 端点发送一个 POST 请求,并在请求体中指定模型名称和消息。**同时,您需要在请求头中包含代理自身的 API 密钥。**
189
+
190
+ 以下是一个 `curl` 命令示例(请将 `YOUR_PROXY_API_KEY` 替换为您的实际代理密钥):
191
+
192
+ ```bash
193
+ curl -X POST http://0.0.0.0:7860/v1/chat/completions \
194
+ -H "Content-Type: application/json" \
195
+ -H "Authorization: Bearer YOUR_PROXY_API_KEY" \
196
+ -d '{
197
+ "model": "gemini-2.5-flash-preview-05-20",
198
+ "messages": [
199
+ {
200
+ "role": "user",
201
+ "content": "你好,请介绍一下你自己。"
202
+ }
203
+ ],
204
+ "temperature": 0.7
205
+ }'
206
+ ```
207
+
208
+ 如果您将代理部署到 Hugging Face Spaces,例如部署在 `https://airsltd-superproxy.hf.space`,则 `curl` 命令应如下所示:
209
+
210
+ ```bash
211
+ curl -X POST https://airsltd-superproxy.hf.space/v1/chat/completions \
212
+ --header 'Content-Type: application/json' \
213
+ --header 'Authorization: Bearer YOUR_PROXY_API_KEY' \
214
+ --data '{
215
+ "model": "gemini-2.5-flash-preview-05-20",
216
+ "messages": [
217
+ {
218
+ "role": "user",
219
+ "content": "你好,请介绍一下你自己。"
220
+ }
221
+ ],
222
+ "temperature": 0.7
223
+ }'
224
+ ```
225
+
226
+ ## 6. 常见问题与解决方案
227
+
228
+ * **代理认证失败 (401 Unauthorized)**:
229
+ * **问题**:当您尝试调用代理时,收到 `401 Unauthorized` 错误,并提示“Invalid or missing proxy API key”。
230
+ * **原因**:这表示您没有在请求头中提供正确的 `Authorization: Bearer YOUR_PROXY_API_KEY`,或者 `PROXY_API_KEY` 环境变量未在代理部署环境中正确设置。
231
+ * **解决方案**:确保您的客户端请求包含正确的 `Authorization: Bearer YOUR_PROXY_API_KEY` 头,并且 `YOUR_PROXY_API_KEY` 与 `.env` 文件中配置的值一致。如果部署在 Hugging Face Spaces,请确保 Space 的环境变量中已设置 `PROXY_API_KEY`。
232
+
233
+ * **“User location is not supported for the API use.”**:此错误来自 Gemini API,表明您的请求源 IP 地址所在的区域不受 Gemini API 支持。这通常发生在本地测试时。部署代理到支持的区域(例如 Hugging Face Spaces)可以解决此问题。
234
+
235
+ * **Postman “Error: incorrect header check”**:此错误通常是由于 Postman 自动添加的某些请求头与部署环境或代理不兼容。本项目已通过强制设置 `User-Agent: curl/8.7.1` 来尝试解决此问题。如果问题仍然存在,请检查 Postman 发送的其他请求头,并尝试禁用非必要的头部。
memory-bank/activeContext.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 活跃背景 (activeContext.md)
2
+
3
+ ## 当前工作焦点
4
+ * **API 转发代理的实现和调试**:主要工作是构建一个 FastAPI 应用程序,用于转发对 Google Gemini API(OpenAI 兼容接口)的请求。
5
+ * **解决客户端兼容性问题**:处理 Postman 等客户端在与代理交互时可能遇到的头部相关问题。
6
+
7
+ ## 最近的更改
8
+ * **`app.py` 修改**:
9
+ * 引入 `httpx` 和 `Response`。
10
+ * 将 `GEMINI_BASE_URL` 从硬编码改为从环境变量加载。
11
+ * 将 `/health` 端点移到通用代理路由之前,以确保其正确匹配。
12
+ * 修改了 API 密钥的传递方式,从 URL 查询参数改为 `Authorization: Bearer` 头。
13
+ * 强制将转发请求的 `User-Agent` 头设置为 `curl/8.7.1`。
14
+ * **`requirements.txt` 更新**:添加了 `httpx` 和 `python-dotenv` 依赖。
15
+ * **`.clinerules` 更新**:添加了自动激活 `conda` 环境 `airs` 的自定义指令。
16
+
17
+ ## 下一步
18
+ * **验证 Postman 兼容性**:用户需要再次尝试使用 Postman 调用部署的代理,以确认 `User-Agent` 头部修改是否解决了“incorrect header check”错误。
19
+ * **本地测试环境问题**:如果本地测试仍然遇到“User location is not supported for the API use.”错误,需要明确告知用户这是 Gemini API 的地域限制,而非代理代码问题。
20
+
21
+ ## 活跃决策和考虑
22
+ * **API 密钥传递方式**:从 URL 查询参数改为 `Authorization` 头是符合 OpenAI 兼容 API 规范的正确做法。
23
+ * **`User-Agent` 强制修改**:这是一个临时的解决方案,用于解决特定客户端(Postman)与部署环境之间的兼容性问题。如果未来出现其他客户端问题,可能需要更灵活的头部处理策略。
24
+ * **路由顺序**:确保特定路由在通用路由之前定义是 FastAPI 应用中的重要考虑因素。
25
+
26
+ ## 学习和项目洞察
27
+ * **FastAPI 路由匹配机制**:理解路由定义顺序对匹配行为的影响至关重要。
28
+ * **HTTP 头部的重要性**:客户端和服务器之间的 HTTP 头部兼容性可能导致意想不到的问题,尤其是在代理场景中。
29
+ * **API 地域限制**:外部 API 的地域限制是部署代理时需要考虑的重要因素。
memory-bank/productContext.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 产品背景 (productContext.md)
2
+
3
+ ## 项目存在的原因
4
+ 本项目旨在解决直接访问某些 API(如 Google Gemini API)可能遇到的问题,包括:
5
+ * **地域限制**:某些 API 可能对特定地理位置的请求有限制。通过部署在特定区域的代理,可以绕过这些限制。
6
+ * **认证管理**:集中管理 API 密钥,避免在多个客户端应用中重复配置和暴露敏感信息。
7
+ * **请求修改**:在请求转发过程中,可以对请求头、请求体等进行修改,以适应目标 API 的要求或解决兼容性问题(例如修改 `User-Agent`)。
8
+ * **简化客户端集成**:为客户端提供一个统一的、本地化的 API 端点,简化其与复杂外部 API 的集成。
9
+
10
+ ## 解决的问题
11
+ * **Gemini API 地域访问限制**:通过将代理部署在 Gemini API 支持的区域,解决本地开发环境可能无法直接访问的问题。
12
+ * **API 密钥安全**:将 API 密钥存储在代理服务器的环境变量中,减少客户端暴露密钥的风险。
13
+ * **Postman 头部兼容性**:通过修改 `User-Agent` 等请求头,解决 Postman 等工具在与某些 API 或部署环境交互时可能出现的兼容性问题。
14
+
15
+ ## 工作方式
16
+ 客户端向 FastAPI 代理发送请求,代理接收请求后,根据预设的配置(环境变量中的 `GEMINI_BASE_URL` 和 `GEMINI_API_KEY`),对请求进行必要的修改(例如添加 `Authorization` 头,修改 `User-Agent`),然后将请求转发到实际的目标 API。目标 API 的响应再由代理原封不动地返回给客户端。
17
+
18
+ ## 用户体验目标
19
+ * **透明性**:客户端无需感知代理的存在,感觉就像直接与目标 API 交互。
20
+ * **可靠性**:代理能够稳定、高效地转发请求,减少因网络或兼容性问题导致的失败。
21
+ * **易用性**:配置简单,易于部署和维护。
memory-bank/progress.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 进度 (progress.md)
2
+
3
+ ## 已完成的工作
4
+ * **FastAPI 代理应用初始化**:创建了基本的 FastAPI 应用程序结构。
5
+ * **依赖管理**:配置了 `requirements.txt` 并安装了必要的依赖(`fastapi`, `uvicorn`, `httpx`, `python-dotenv`)。
6
+ * **环境变量配置**:实现了从 `.env` 文件加载 `GEMINI_API_KEY` 和 `GEMINI_BASE_URL`。
7
+ * **通用转发逻辑**:实现了 `/{path:path}` 通用路由,能够捕获并转发所有 HTTP 方法的请求。
8
+ * **健康检查端点**:添加并修复了 `/health` 端点,确保其独立于上游 API 正常工作。
9
+ * **API 密钥传递**:将 Gemini API 密钥的传递方式从 URL 查询参数修改为 `Authorization: Bearer` 头,以符合 OpenAI 兼容 API 的要求。
10
+ * **User-Agent 修改**:强制将转发请求的 `User-Agent` 头设置为 `curl/8.7.1`,以解决潜在的客户端兼容性问题。
11
+ * **`.clinerules` 更新**:添加了自动激活 `conda` 环境 `airs` 的自定义指令。
12
+ * **部署环境验证**:通过 `curl` 命令验证了部署在 Hugging Face Spaces 上的代理功能正常。
13
+
14
+ ## 待完成的工作
15
+ * **Postman 客户端兼容性验证**:用户需要再次尝试使用 Postman 调用部署的代理,以确认 `User-Agent` 头部修改是否解决了“incorrect header check”错误。
16
+ * **本地测试地域限制说明**:如果用户在本地测试时仍然遇到“User location is not supported for the API use.”错误,需要明确告知这是 Gemini API 的地域限制,而非代理代码问题。
17
+
18
+ ## 当前状态
19
+ 代理应用程序的核心功能已完成并部署验证。主要剩余任务是解决特定客户端(Postman)的兼容性问题,并向用户明确本地测试可能遇到的地域限制。
20
+
21
+ ## 已知问题
22
+ * **本地测试地域限制**:在某些地域,直接从本地机器访问 Gemini API 可能会遇到“User location is not supported for the API use.”错误。
23
+ * **Postman 头部兼容性**:Postman 客户端在调用部署的代理时,曾出现“Error: incorrect header check”错误,已尝试通过修改 `User-Agent` 头部来解决。
24
+
25
+ ## 项目决策演变
26
+ * 最初使用 `requests` 库,后改为 `httpx` 以支持异步。
27
+ * API 密钥最初通过 URL 查询参数传递,后改为 `Authorization` 头。
28
+ * 健康检查端点最初被通用路由覆盖,后调整了路由顺序。
29
+ * 为了解决 Postman 问题,增加了强制修改 `User-Agent` 头的逻辑。
memory-bank/projectBrief.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 项目简报 (projectBrief.md)
2
+
3
+ ## 项目名称
4
+ FastAPI API 转发代理 (SuperProxy)
5
+
6
+ ## 项目目标
7
+ 搭建一个通用的 FastAPI 应用程序,作为 API 转发代理。主要目标是转发对 Google Gemini API 的请求,特别是其 OpenAI 兼容 API。
8
+
9
+ ## 核心功能
10
+ 1. 接收来自客户端的 HTTP 请求(GET, POST, PUT, DELETE)。
11
+ 2. 将这些请求转发到预配置的目标 API(例如 Gemini API)。
12
+ 3. 处理请求头、查询参数和请求体。
13
+ 4. 将目标 API 的响应(状态码、头部、响应体)返回给客户端。
14
+ 5. 支持通过环境变量配置目标 API 的基 URL 和认证信息。
15
+ 6. 提供一个简单的健康检查端点。
16
+
17
+ ## 关键技术
18
+ * Python
19
+ * FastAPI
20
+ * Uvicorn
21
+ * httpx (异步 HTTP 客户端)
22
+ * python-dotenv (环境变量管理)
23
+
24
+ ## 部署环境
25
+ Hugging Face Spaces (或任何支持 FastAPI 应用的 Python 环境)
26
+
27
+ ## 当前状态
28
+ * FastAPI 代理应用已基本实现。
29
+ * 已配置通过环境变量 `GEMINI_BASE_URL` 和 `GEMINI_API_KEY` 转发到 Gemini 的 OpenAI 兼容 API。
30
+ * 已修复健康检查端点。
31
+ * 已将转发请求的 `User-Agent` 头修改为 `curl/8.7.1`。
32
+ * 在部署环境 (Hugging Face Spaces) 中,代理功能已通过 `curl` 命令验证成功。
33
+ * 在本地测试时,Gemini API 返回“User location is not supported for the API use.”错误,这可能是由于本地 IP 地址的区域限制。
34
+ * Postman 客户端在调用部署的代理时遇到“Error: incorrect header check”错误,这可能与 Postman 自动生成的头部有关。
memory-bank/systemPatterns.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 系统模式 (systemPatterns.md)
2
+
3
+ ## 系统架构
4
+ 本项目采用简单的客户端-代理-目标 API 的三层架构。
5
+
6
+ ```mermaid
7
+ graph LR
8
+ Client[客户端 (e.g., Postman, curl)] --> Proxy[FastAPI 代理 (SuperProxy)]
9
+ Proxy --> TargetAPI[目标 API (e.g., Google Gemini API)]
10
+ ```
11
+
12
+ ## 关键技术决策
13
+ * **FastAPI**:选择 FastAPI 作为 Web 框架,因为它提供了高性能、易于使用的异步 API 开发能力,非常适合构建轻量级代理服务。
14
+ * **httpx**:选择 `httpx` 作为 HTTP 客户端库,因为它支持异步请求,与 FastAPI 的异步特性完美结合,避免了阻塞。
15
+ * **环境变量配置**:使用 `python-dotenv` 管理敏感信息(如 API 密钥)和可配置参数(如目标 API 基 URL),增强了安全性和灵活性。
16
+ * **通用路由**:采用 `/{path:path}` 通用路由来捕获所有传入请求,实现灵活的转发,无需为每个目标 API 端点单独定义路由。
17
+
18
+ ## 设计模式
19
+ * **代理模式 (Proxy Pattern)**:本项目是代理模式的经典应用,FastAPI 应用程序充当客户端和目标 API 之间的代理,控制对目标 API 的访问并进行请求/响应转换。
20
+ * **配置即代码 (Configuration as Code)**:通过 `.env` 文件管理配置,使得部署和环境切换更加便捷和可控。
21
+
22
+ ## 组件关系
23
+ * **FastAPI 应用 (`app.py`)**:核心组件,负责路由、请求解析、请求转发和响应处理。
24
+ * **httpx 客户端**:在 FastAPI 应用内部使用,负责向目标 API 发送实际的 HTTP 请求。
25
+ * **python-dotenv**:在应用启动时加载 `.env` 文件中的环境变量,供 FastAPI 应用使用。
26
+ * **客户端**:可以是任何 HTTP 客户端(浏览器、Postman、`curl`、自定义应用),向 FastAPI 代理发送请求。
27
+ * **目标 API**:本项目中特指 Google Gemini API(OpenAI 兼容接口),是代理请求的最终目的地。
28
+
29
+ ## 关键实现路径
30
+ 1. **请求接收**:FastAPI 的 `@app.api_route("/{path:path}")` 装饰器捕获所有传入请求。
31
+ 2. **请求解析**:`Request` 对象用于获取请求方法、头部、查询参数和请求体。
32
+ 3. **头部处理**:移除 `Host` 头,添加 `Authorization: Bearer` 头,并强制设置 `User-Agent`。
33
+ 4. **URL 构建**:根据 `GEMINI_BASE_URL` 和传入的 `path` 构建目标 API 的完整 URL。
34
+ 5. **请求转发**:使用 `httpx.AsyncClient().request()` 异步发送请求到目标 API。
35
+ 6. **响应处理**:将目标 API 的 `content`、`status_code` 和 `headers` 封装成 `FastAPI.Response` 返回给客户端。
36
+ 7. **错误处理**:捕获 `httpx.RequestError` 和 `httpx.HTTPStatusError`,并转换为 `HTTPException` 返回给客户端。
memory-bank/techContext.md ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 技术背景 (techContext.md)
2
+
3
+ ## 使用的技术
4
+ * **Python 3.9+**:作为主要的开发语言。
5
+ * **FastAPI 0.120.0+**:高性能的 Python Web 框架,用于构建 API 代理。
6
+ * **Uvicorn**:ASGI 服务器,用于运行 FastAPI 应用程序。
7
+ * **httpx 0.28.1+**:异步 HTTP 客户端,用于向目标 API 发送请求。
8
+ * **python-dotenv**:用于从 `.env` 文件加载环境变量。
9
+
10
+ ## 开发环境设置
11
+ 1. **Python 环境**:建议使用 `conda` 或 `venv` 创建独立的 Python 虚拟环境。
12
+ ```bash
13
+ conda create -n airs python=3.9
14
+ conda activate airs
15
+ ```
16
+ 2. **依赖安装**:通过 `requirements.txt` 安装所有项目依赖。
17
+ ```bash
18
+ pip install -r requirements.txt
19
+ ```
20
+ 3. **环境变量**:在项目根目录创建 `.env` 文件,并配置以下变量:
21
+ ```
22
+ GEMINI_API_KEY="YOUR_GEMINI_API_KEY"
23
+ GEMINI_BASE_URL="https://generativelanguage.googleapis.com/v1beta/openai"
24
+ ```
25
+ 请将 `YOUR_GEMINI_API_KEY` 替换为您的实际 Gemini API 密钥。
26
+
27
+ ## 技术约束
28
+ * **FastAPI 路由匹配顺序**:通用路由 `/{path:path}` 必须放在特定路由(如 `/health`)之后,否则会优先匹配通用路由。
29
+ * **异步 HTTP 请求**:由于 FastAPI 是异步框架,使用 `httpx` 这样的异步 HTTP 客户端是最佳实践,以避免阻塞事件循环。
30
+ * **API 密钥安全**:API 密钥不应直接硬编码在代码中,而应通过环境变量安全管理。
31
+ * **Hugging Face Spaces 部署**:部署到 Hugging Face Spaces 时,需要确保 `.env` 文件中的环境变量已正确配置,并且 `app.py` 中的 `uvicorn` 启动命令与 Space 的配置兼容。
32
+
33
+ ## 依赖管理
34
+ 项目依赖通过 `requirements.txt` 文件进行管理:
35
+ ```
36
+ fastapi
37
+ uvicorn[standard]
38
+ httpx
39
+ python-dotenv
40
+ ```
41
+
42
+ ## 工具使用模式
43
+ * **`uvicorn`**:用于本地开发和部署时启动 FastAPI 应用。
44
+ `uvicorn app:app --host 0.0.0.0 --port 7860 --reload`
45
+ * **`pip` / `pip3`**:用于安装 Python 依赖。
46
+ * **`curl` / Postman**:用于测试 API 代理功能。
47
+ * **`.clinerules`**:用于配置 Cline 的自定义指令,例如自动激活 `conda` 环境。
requirements.txt CHANGED
@@ -2,3 +2,4 @@ fastapi
2
  uvicorn[standard]
3
  httpx
4
  python-dotenv
 
 
2
  uvicorn[standard]
3
  httpx
4
  python-dotenv
5
+ python-jose