geqintan commited on
Commit
a095012
·
1 Parent(s): b1bcc51
Files changed (3) hide show
  1. .clinerules +4 -1
  2. app.py +29 -17
  3. requirements.txt +2 -0
.clinerules CHANGED
@@ -1,6 +1,9 @@
1
  # 自定义指令
2
  CUSTOM_INSTRUCTIONS = """
3
-
 
 
 
4
  """
5
 
6
 
 
1
  # 自定义指令
2
  CUSTOM_INSTRUCTIONS = """
3
+ # 自动激活conda环境
4
+ # 在每次会话开始时,自动激活名为 'airs' 的conda环境。
5
+ # 这确保了所有后续的Python相关命令都在正确的环境中执行。
6
+ conda activate airs
7
  """
8
 
9
 
app.py CHANGED
@@ -1,7 +1,8 @@
1
  # uvicorn app:app --host 0.0.0.0 --port 7860 --reload
2
 
3
  from fastapi import FastAPI, Request, HTTPException
4
- import requests
 
5
  import os
6
  from dotenv import load_dotenv
7
 
@@ -13,33 +14,45 @@ app = FastAPI(title="Gemini Proxy API")
13
  def greet_json():
14
  return {"Hello": "World!"}
15
 
 
 
 
 
 
16
  # 1. 配置Gemini真实信息
17
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") # 从环境变量获取密钥
18
- GEMINI_BASE_URL = "https://generativelanguage.googleapis.com/v1beta/models" # Gemini真实Base URL
 
 
19
 
20
  # 2. 通用转发接口(匹配Gemini的/predict等端点,路径动态匹配)
21
  @app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
22
  async def proxy_gemini(request: Request, path: str):
23
- # 拼接Gemini真实请求URL(如客户端访问 /models/gemini-pro:generateContent → 转发到Gemini的对应路径)
24
- gemini_url = f"{GEMINI_BASE_URL}/{path}?key={GEMINI_API_KEY}"
25
 
26
  # 提取客户端请求的headers和body,透传给Gemini
27
  client_headers = dict(request.headers)
28
  # 移除FastAPI自带的Host头,避免Gemini校验报错
29
  client_headers.pop("host", None)
30
 
 
 
 
 
31
  try:
32
  # 读取客户端请求体
33
  client_body = await request.body()
34
 
35
- # 向Gemini发起请求(转发)
36
- response = requests.request(
37
- method=request.method,
38
- url=gemini_url,
39
- headers=client_headers,
40
- data=client_body,
41
- timeout=30 # 超时时间,可调整
42
- )
 
43
 
44
  # 将Gemini的响应透传给客户端
45
  return Response(
@@ -48,10 +61,9 @@ async def proxy_gemini(request: Request, path: str):
48
  headers=dict(response.headers)
49
  )
50
 
 
 
 
 
51
  except Exception as e:
52
  raise HTTPException(status_code=500, detail=f"转发失败:{str(e)}")
53
-
54
- # 3. 健康检查接口(可选,用于验证服务是否正常)
55
- @app.get("/health")
56
- async def health_check():
57
- return {"status": "ok", "proxy_target": "Google Gemini"}
 
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
 
 
14
  def greet_json():
15
  return {"Hello": "World!"}
16
 
17
+ # 3. 健康检查接口(可选,用于验证服务是否正常)
18
+ @app.get("/health")
19
+ async def health_check():
20
+ return {"status": "ok", "message": "Proxy service is running."}
21
+
22
  # 1. 配置Gemini真实信息
23
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") # 从环境变量获取密钥
24
+ GEMINI_BASE_URL = os.getenv("GEMINI_BASE_URL") # 从环境变量获取Gemini真实Base URL
25
+ print(f"Using Gemini Base URL: {GEMINI_BASE_URL}")
26
+ 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
 
34
  # 提取客户端请求的headers和body,透传给Gemini
35
  client_headers = dict(request.headers)
36
  # 移除FastAPI自带的Host头,避免Gemini校验报错
37
  client_headers.pop("host", None)
38
 
39
+ # 添加Authorization头,用于Gemini的OpenAI兼容API
40
+ if GEMINI_API_KEY:
41
+ client_headers["Authorization"] = f"Bearer {GEMINI_API_KEY}"
42
+
43
  try:
44
  # 读取客户端请求体
45
  client_body = await request.body()
46
 
47
+ # 使用httpx异步客户端发起请求
48
+ async with httpx.AsyncClient() as client:
49
+ response = await client.request(
50
+ method=request.method,
51
+ url=gemini_url,
52
+ headers=client_headers,
53
+ content=client_body, # httpx使用content参数传递请求体
54
+ timeout=30 # 超时时间,可调整
55
+ )
56
 
57
  # 将Gemini的响应透传给客户端
58
  return Response(
 
61
  headers=dict(response.headers)
62
  )
63
 
64
+ except httpx.RequestError as e:
65
+ raise HTTPException(status_code=500, detail=f"转发请求失败:{str(e)}")
66
+ except httpx.HTTPStatusError as e:
67
+ raise HTTPException(status_code=e.response.status_code, detail=f"目标API返回错误:{e.response.text}")
68
  except Exception as e:
69
  raise HTTPException(status_code=500, detail=f"转发失败:{str(e)}")
 
 
 
 
 
requirements.txt CHANGED
@@ -1,2 +1,4 @@
1
  fastapi
2
  uvicorn[standard]
 
 
 
1
  fastapi
2
  uvicorn[standard]
3
+ httpx
4
+ python-dotenv