tanbushi commited on
Commit
e9670f4
·
1 Parent(s): 141d8af
Files changed (2) hide show
  1. app.py +13 -40
  2. proxy.py +21 -0
app.py CHANGED
@@ -7,6 +7,7 @@ import httpx # 使用httpx替代requests,因为requests是同步的,而FastA
7
  import os, json
8
  from dotenv import load_dotenv
9
  from enum import Enum
 
10
 
11
  # 加载环境变量
12
  load_dotenv()
@@ -59,54 +60,26 @@ keys_count = len(gemini_api_keys_arr)
59
  @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
60
  # @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["POST"])
61
  async def proxy_gemini(request: Request, protocol: ProtocolType, host:str, path: str, proxy_api_key: str = Depends(verify_proxy_api_key)): # 添加代理认证依赖
62
- global key_index # 声明使用全局变量
63
  real_url = f"{protocol.value}://{host}/{path}"
64
-
65
- # 提取客户端请求的headers和body,透传给Gemini
66
  client_headers = dict(request.headers)
67
-
 
68
  # 移除FastAPI自带的Host头,避免Gemini校验报错
69
  client_headers.pop("host", None)
70
-
71
  # 将User-Agent改为curl/8.7.1,以模拟curl请求
72
  client_headers["User-Agent"] = "curl/8.7.1"
73
-
74
- # 添加Authorization头,用于Gemini的OpenAI兼容API
75
- if gemini_api_keys_arr: # 确保有可用的API密钥
76
- print(f"key_index: {key_index}")
77
  gemini_api_key = gemini_api_keys_arr[key_index]
78
  key_index = (key_index + 1) % keys_count
79
- print(f"next_key_index: {key_index}")
80
- client_headers["Authorization"] = f"Bearer {gemini_api_key}"
81
- elif gemini_api_key: # 如果没有API密钥列表,使用单个API密钥
82
  client_headers["Authorization"] = f"Bearer {gemini_api_key}"
 
 
83
  else:
84
  raise HTTPException(status_code=500, detail="No Gemini API keys configured.")
85
-
86
- try:
87
- # 读取客户端请求体
88
- client_body = await request.body()
89
-
90
- # 使用httpx异步客户端发起请求
91
- async with httpx.AsyncClient() as client:
92
- response = await client.request(
93
- method=request.method,
94
- url=real_url,
95
- headers=client_headers,
96
- content=client_body, # httpx使用content参数传递请求体
97
- timeout=30 # 超时时间,可调整
98
- )
99
-
100
- # 将Gemini的响应透传给客户端
101
- return Response(
102
- content=response.content,
103
- status_code=response.status_code,
104
- headers=dict(response.headers)
105
- )
106
-
107
- except httpx.RequestError as e:
108
- raise HTTPException(status_code=500, detail=f"转发请求失败:{str(e)}")
109
- except httpx.HTTPStatusError as e:
110
- raise HTTPException(status_code=e.response.status_code, detail=f"目标API返回错误:{e.response.text}")
111
- except Exception as e:
112
- raise HTTPException(status_code=500, detail=f"转发失败:{str(e)}")
 
7
  import os, json
8
  from dotenv import load_dotenv
9
  from enum import Enum
10
+ from proxy import do_proxy
11
 
12
  # 加载环境变量
13
  load_dotenv()
 
60
  @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
61
  # @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["POST"])
62
  async def proxy_gemini(request: Request, protocol: ProtocolType, host:str, path: str, proxy_api_key: str = Depends(verify_proxy_api_key)): # 添加代理认证依赖
 
63
  real_url = f"{protocol.value}://{host}/{path}"
64
+ # 提取客户端请求的headers和body
 
65
  client_headers = dict(request.headers)
66
+ client_body = await request.body()
67
+
68
  # 移除FastAPI自带的Host头,避免Gemini校验报错
69
  client_headers.pop("host", None)
 
70
  # 将User-Agent改为curl/8.7.1,以模拟curl请求
71
  client_headers["User-Agent"] = "curl/8.7.1"
72
+
73
+ # 处理Gemini API密钥轮换和Authorization头
74
+ global key_index # 声明使用全局变量
75
+ if gemini_api_keys_arr:
76
  gemini_api_key = gemini_api_keys_arr[key_index]
77
  key_index = (key_index + 1) % keys_count
 
 
 
78
  client_headers["Authorization"] = f"Bearer {gemini_api_key}"
79
+ elif os.getenv("GEMINI_API_KEY"): # 如果没有API密钥列表,使用单个API密钥
80
+ client_headers["Authorization"] = f"Bearer {os.getenv('GEMINI_API_KEY')}"
81
  else:
82
  raise HTTPException(status_code=500, detail="No Gemini API keys configured.")
83
+
84
+ # 调用 do_proxy 并返回其结果
85
+ return await do_proxy(real_url, request.method, client_headers, client_body)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
proxy.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi.responses import Response # 导入Response
2
+ import httpx # 使用httpx替代requests,因为requests是同步的,而FastAPI是异步的
3
+
4
+ async def do_proxy(url:str, method:str, headers:dict, content:str):
5
+ print("Proxy service started.", url)
6
+ # 使用httpx异步客户端发起请求
7
+ async with httpx.AsyncClient() as client:
8
+ response = await client.request(
9
+ method=method,
10
+ url=url,
11
+ headers=headers,
12
+ content=content, # httpx使用content参数传递请求体
13
+ timeout=30 # 超时时间,可调整
14
+ )
15
+
16
+ # 将Gemini的响应透传给客户端
17
+ return Response(
18
+ content=response.content,
19
+ status_code=response.status_code,
20
+ headers=dict(response.headers)
21
+ )