tanbushi commited on
Commit
d7b2837
·
1 Parent(s): beab01e
Files changed (6) hide show
  1. api_key_sb copy.py +0 -30
  2. api_key_sb.py +25 -19
  3. app.py +0 -12
  4. proxy copy 2.py +0 -44
  5. proxy copy.py +0 -24
  6. proxy.py +5 -9
api_key_sb copy.py DELETED
@@ -1,30 +0,0 @@
1
- from supabase import create_client, Client
2
- import os
3
- from fastapi import FastAPI, Request, HTTPException, Depends, status
4
- from dotenv import load_dotenv
5
-
6
- load_dotenv()
7
-
8
- # Supabase 配置
9
- SUPABASE_URL = os.getenv("SUPABASE_URL")
10
- SUPABASE_KEY = os.getenv("SUPABASE_KEY")
11
-
12
- # 初始化 Supabase 客户端
13
- supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
14
- async def get_api_key_info(model: str = None):
15
- try:
16
- # 根据用户提供的SQL语句修改,从 'airs_model_api_keys_view' 视图中获取 'api_key'
17
- if model:
18
- response = supabase.from_('airs_model_api_keys_view').select('api_key', 'api_key_id').eq('model_name', model).order('api_key_ran_at', desc=False).limit(1).execute()
19
- else:
20
- # 如果没有提供model,则获取所有模型的api_key
21
- raise HTTPException(status_code=400, detail="请提供模型名称!")
22
-
23
- if response.data:
24
- api_key_info = response.data[0]
25
- return api_key_info
26
- else:
27
- return None
28
- except Exception as e:
29
- print(f"从Supabase获取API密钥失败: {e}")
30
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
api_key_sb.py CHANGED
@@ -10,8 +10,12 @@ load_dotenv()
10
  SUPABASE_URL = os.getenv("SUPABASE_URL")
11
  SUPABASE_KEY = os.getenv("SUPABASE_KEY")
12
 
13
- # 初始化 Supabase 客户端
14
- supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
 
 
 
 
15
  async def get_api_key_info(model: str = None):
16
  try:
17
  # 根据用户提供的SQL语句修改,从 'airs_model_api_keys_view' 视图中获取 'api_key'
@@ -23,26 +27,28 @@ async def get_api_key_info(model: str = None):
23
 
24
  if response.data:
25
  api_key_info = response.data[0]
26
- api_key = api_key_info.get('api_key')
27
- api_key_id = api_key_info.get('api_key_id')
28
-
29
-
30
- try:
31
- # 创建北京时间时区对象(UTC+8)
32
- beijing_tz = timezone(timedelta(hours=8))
33
- now_beijing = datetime.now(beijing_tz) # 带时区的datetime对象
34
- current_local_time = now_beijing.isoformat()
35
- # current_local_time = int(now_beijing.timestamp()) # 正确的时间戳
36
- # current_local_time = datetime.now().isoformat()
37
- supabase.table("airs_api_keys").update({"ran_at": current_local_time}).eq("id", api_key_id).execute()
38
- print('更新成功')
39
- except Exception as e:
40
- # raise HTTPException(status_code=500, detail="更新API密钥运行时间失败!")
41
- raise HTTPException(status_code=500, detail=f"更新API密钥运行时间失败!错误信息:{str(e)}")
42
-
43
  return api_key_info
44
  else:
45
  return None
46
  except Exception as e:
47
  print(f"从Supabase获取API密钥失败: {e}")
48
  return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  SUPABASE_URL = os.getenv("SUPABASE_URL")
11
  SUPABASE_KEY = os.getenv("SUPABASE_KEY")
12
 
13
+ def get_supabase_client() -> Client:
14
+ """Initializes and returns a Supabase client instance."""
15
+ return create_client(SUPABASE_URL, SUPABASE_KEY)
16
+
17
+ supabase: Client = get_supabase_client()
18
+
19
  async def get_api_key_info(model: str = None):
20
  try:
21
  # 根据用户提供的SQL语句修改,从 'airs_model_api_keys_view' 视图中获取 'api_key'
 
27
 
28
  if response.data:
29
  api_key_info = response.data[0]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  return api_key_info
31
  else:
32
  return None
33
  except Exception as e:
34
  print(f"从Supabase获取API密钥失败: {e}")
35
  return None
36
+
37
+ async def update_api_key_ran_at(api_key_id: str, ran_at_time: datetime = None):
38
+ """
39
+ Updates the 'ran_at' field for a given API key in Supabase.
40
+ If ran_at_time is None, it defaults to the current Beijing time.
41
+ """
42
+ try:
43
+ if ran_at_time is None:
44
+ # 创建北京时间时区对象(UTC+8)
45
+ beijing_tz = timezone(timedelta(hours=8))
46
+ now_beijing = datetime.now(beijing_tz) # 带时区的datetime对象
47
+ current_local_time = now_beijing.isoformat()
48
+ else:
49
+ current_local_time = ran_at_time.isoformat()
50
+
51
+ supabase.table("airs_api_keys").update({"ran_at": current_local_time}).eq("id", api_key_id).execute()
52
+ print(f'API 密钥 {api_key_id} 的 ran_at 更新成功为 {current_local_time}')
53
+ except Exception as e:
54
+ raise HTTPException(status_code=500, detail=f"更新API密钥运行时间失败!错误信息:{str(e)}")
app.py CHANGED
@@ -45,18 +45,6 @@ def greet_json():
45
  async def health_check():
46
  return {"status": "ok", "message": "Proxy service is running."}
47
 
48
- gemini_api_keys_str = os.getenv("GEMINI_API_KEYS_STR")
49
- try:
50
- gemini_api_keys_arr = json.loads(gemini_api_keys_str)
51
- except json.JSONDecodeError as e:
52
- print(f"JSON 解析错误:{e}")
53
- gemini_api_keys_arr = [] # 解析失败时设置默认值
54
- except Exception as e:
55
- print(f"其他错误:{e}")
56
- gemini_api_keys_arr = []
57
-
58
- key_index = 0
59
- keys_count = len(gemini_api_keys_arr)
60
 
61
  @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
62
  # @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["POST"])
 
45
  async def health_check():
46
  return {"status": "ok", "message": "Proxy service is running."}
47
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
50
  # @app.api_route("/v1/{protocol}/{host}/{path:path}", methods=["POST"])
proxy copy 2.py DELETED
@@ -1,44 +0,0 @@
1
- import httpx
2
- import asyncio
3
- from starlette.responses import Response
4
-
5
- async def do_proxy(url: str, method: str, headers: dict, content: str, max_retries: int = 3):
6
- print("Proxy service started.", url)
7
- client = None
8
- try:
9
- async with httpx.AsyncClient() as client:
10
- for attempt in range(max_retries):
11
- response = await client.request(
12
- method=method,
13
- url=url,
14
- headers=headers,
15
- content=content,
16
- timeout=30
17
- )
18
-
19
- # 关键:显式检查状态码
20
- if response.status_code == 429:
21
- retry_after = response.headers.get("Retry-After", "5") # 默认5秒
22
- wait_time = int(retry_after) + attempt * 2 # 指数退避基础值
23
- print(f"⚠️ 429错误!{wait_time}秒后重试 (尝试:{attempt+1})")
24
- await asyncio.sleep(wait_time)
25
- continue
26
-
27
- response.raise_for_status() # 触发其他4xx/5xx异常
28
- return Response(
29
- content=response.content,
30
- status_code=response.status_code,
31
- headers=dict(response.headers)
32
- )
33
-
34
- except httpx.HTTPStatusError as e:
35
- print(f"🚨 服务器错误 {e.response.status_code}: {e.request.url}")
36
- return Response(content=str(e), status_code=e.response.status_code)
37
-
38
- except Exception as e:
39
- print(f"🔥 致命错误: {type(e).__name__}: {str(e)}")
40
- return Response(content="Internal Server Error", status_code=500)
41
-
42
- finally:
43
- if client:
44
- await client.aclose() # 确保连接关闭
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
proxy copy.py DELETED
@@ -1,24 +0,0 @@
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
- try:
7
- # 使用httpx异步客户端发起请求
8
- async with httpx.AsyncClient() as client:
9
- response = await client.request(
10
- method=method,
11
- url=url,
12
- headers=headers,
13
- content=content, # httpx使用content参数传递请求体
14
- timeout=30 # 超时时间,可调整
15
- )
16
- except Exception as e:
17
- print("Error:", e)
18
-
19
- # 将Gemini的响应透传给客户端
20
- return Response(
21
- content=response.content,
22
- status_code=response.status_code,
23
- headers=dict(response.headers)
24
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
proxy.py CHANGED
@@ -1,8 +1,8 @@
1
  import httpx
2
  import asyncio
3
  from starlette.responses import Response
4
- from api_key_sb import get_api_key_info
5
- from supabase import create_client, Client
6
  from dotenv import load_dotenv
7
  import os
8
  from datetime import timezone, timedelta, datetime
@@ -10,12 +10,8 @@ from fastapi import FastAPI, Request, HTTPException, Depends, status
10
 
11
  load_dotenv()
12
 
13
- # Supabase 配置
14
- SUPABASE_URL = os.getenv("SUPABASE_URL")
15
- SUPABASE_KEY = os.getenv("SUPABASE_KEY")
16
-
17
- # 初始化 Supabase 客户端
18
- supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
19
 
20
  async def do_proxy(url: str, method: str, headers: dict, content: str, max_retries: int = 3):
21
  print("Proxy service started.", url)
@@ -54,7 +50,7 @@ async def do_proxy(url: str, method: str, headers: dict, content: str, max_retri
54
  # future_timestamp = future_time.timestamp()
55
  future_timestamp = future_time.isoformat()
56
  print('future_timestamp',future_timestamp)
57
- supabase.table("airs_api_keys").update({"ran_at": future_timestamp}).eq("id", api_key_id).execute()
58
  print('更新成功')
59
  except Exception as e:
60
  raise HTTPException(status_code=500, detail=f"更新API密钥运行时间失败!错误信息:{str(e)}")
 
1
  import httpx
2
  import asyncio
3
  from starlette.responses import Response
4
+ from api_key_sb import get_api_key_info, get_supabase_client, update_api_key_ran_at
5
+ from supabase import Client
6
  from dotenv import load_dotenv
7
  import os
8
  from datetime import timezone, timedelta, datetime
 
10
 
11
  load_dotenv()
12
 
13
+ # 获取共享的 Supabase 客户端实例
14
+ supabase: Client = get_supabase_client()
 
 
 
 
15
 
16
  async def do_proxy(url: str, method: str, headers: dict, content: str, max_retries: int = 3):
17
  print("Proxy service started.", url)
 
50
  # future_timestamp = future_time.timestamp()
51
  future_timestamp = future_time.isoformat()
52
  print('future_timestamp',future_timestamp)
53
+ await update_api_key_ran_at(api_key_id, future_time)
54
  print('更新成功')
55
  except Exception as e:
56
  raise HTTPException(status_code=500, detail=f"更新API密钥运行时间失败!错误信息:{str(e)}")