bobocup commited on
Commit
35cd777
·
verified ·
1 Parent(s): b336412

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -59
app.py CHANGED
@@ -6,14 +6,11 @@ import json
6
  from typing import List, Optional
7
  import requests
8
  from itertools import cycle
9
- import logging
10
 
11
- # 设置日志
12
- logging.basicConfig(level=logging.INFO)
13
- logger = logging.getLogger(__name__)
14
-
15
- app = FastAPI(openapi_url="/api/v1/openapi.json", docs_url="/api/v1/docs")
16
 
 
17
  app.add_middleware(
18
  CORSMiddleware,
19
  allow_origins=["*"],
@@ -22,8 +19,9 @@ app.add_middleware(
22
  allow_headers=["*"],
23
  )
24
 
 
25
  class Config:
26
- OPENAI_API_BASE = "https://api.x.ai" # 移除 /v1
27
  KEYS_URL = os.getenv("KEYS_URL", "")
28
  WHITELIST_IPS = os.getenv("WHITELIST_IPS", "").split(",")
29
 
@@ -31,6 +29,7 @@ class Config:
31
  keys = []
32
  key_cycle = None
33
 
 
34
  def init_keys():
35
  global keys, key_cycle
36
  try:
@@ -42,12 +41,13 @@ def init_keys():
42
  keys = [k.strip() for k in f.readlines() if k.strip()]
43
 
44
  key_cycle = cycle(keys)
45
- logger.info(f"Loaded {len(keys)} API keys")
46
  except Exception as e:
47
- logger.error(f"Error loading keys: {e}")
48
  keys = []
49
  key_cycle = cycle(keys)
50
 
 
51
  @app.middleware("http")
52
  async def ip_whitelist(request: Request, call_next):
53
  if Config.WHITELIST_IPS and Config.WHITELIST_IPS[0]:
@@ -56,64 +56,44 @@ async def ip_whitelist(request: Request, call_next):
56
  raise HTTPException(status_code=403, detail="IP not allowed")
57
  return await call_next(request)
58
 
 
59
  def get_next_key():
60
  if not keys:
61
  raise HTTPException(status_code=500, detail="No API keys available")
62
  return next(key_cycle)
63
 
 
64
  @app.api_route("/api/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
65
  async def proxy(path: str, request: Request):
66
- try:
67
- # 获取请求信息
68
- body = await request.body()
69
- params = dict(request.query_params)
70
- headers = dict(request.headers)
71
- headers.pop("host", None)
72
-
73
- # 设置API key
74
- api_key = get_next_key()
75
- headers["Authorization"] = f"Bearer {api_key}"
76
-
77
- # 构建目标URL
78
- url = f"{Config.OPENAI_API_BASE}/v1/{path}"
79
-
80
- logger.info(f"Proxying request to: {url}")
81
- logger.info(f"Method: {request.method}")
82
- logger.info(f"Headers: {headers}")
83
-
84
- async with httpx.AsyncClient() as client:
85
- try:
86
- response = await client.request(
87
- method=request.method,
88
- url=url,
89
- params=params,
90
- headers=headers,
91
- content=body,
92
- timeout=30.0 # 增加超时时间
93
- )
94
-
95
- # 记录响应状态
96
- logger.info(f"Response status: {response.status_code}")
97
-
98
- # 如果响应不是200,记录错误信息
99
- if response.status_code != 200:
100
- logger.error(f"Error response: {response.text}")
101
-
102
- return response.json()
103
- except httpx.HTTPError as e:
104
- logger.error(f"HTTP error occurred: {e}")
105
- raise HTTPException(status_code=500, detail=str(e))
106
- except Exception as e:
107
- logger.error(f"Unexpected error: {e}")
108
- raise HTTPException(status_code=500, detail=str(e))
109
- except Exception as e:
110
- logger.error(f"Error in proxy function: {e}")
111
- raise HTTPException(status_code=500, detail=str(e))
112
-
113
- @app.get("/api/v1/health")
114
- async def health_check():
115
- return {"status": "healthy", "key_count": len(keys)}
116
 
 
117
  @app.on_event("startup")
118
  async def startup_event():
119
  init_keys()
 
6
  from typing import List, Optional
7
  import requests
8
  from itertools import cycle
 
9
 
10
+ # 创建FastAPI应用
11
+ app = FastAPI()
 
 
 
12
 
13
+ # CORS设置
14
  app.add_middleware(
15
  CORSMiddleware,
16
  allow_origins=["*"],
 
19
  allow_headers=["*"],
20
  )
21
 
22
+ # 配置
23
  class Config:
24
+ OPENAI_API_BASE = "https://api.x.ai/v1" # 注意这里是v1
25
  KEYS_URL = os.getenv("KEYS_URL", "")
26
  WHITELIST_IPS = os.getenv("WHITELIST_IPS", "").split(",")
27
 
 
29
  keys = []
30
  key_cycle = None
31
 
32
+ # 初始化keys
33
  def init_keys():
34
  global keys, key_cycle
35
  try:
 
41
  keys = [k.strip() for k in f.readlines() if k.strip()]
42
 
43
  key_cycle = cycle(keys)
44
+ print(f"Loaded {len(keys)} API keys")
45
  except Exception as e:
46
+ print(f"Error loading keys: {e}")
47
  keys = []
48
  key_cycle = cycle(keys)
49
 
50
+ # IP白名单中间件
51
  @app.middleware("http")
52
  async def ip_whitelist(request: Request, call_next):
53
  if Config.WHITELIST_IPS and Config.WHITELIST_IPS[0]:
 
56
  raise HTTPException(status_code=403, detail="IP not allowed")
57
  return await call_next(request)
58
 
59
+ # 获取下一个key
60
  def get_next_key():
61
  if not keys:
62
  raise HTTPException(status_code=500, detail="No API keys available")
63
  return next(key_cycle)
64
 
65
+ # 代理请求到X.AI
66
  @app.api_route("/api/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
67
  async def proxy(path: str, request: Request):
68
+ # 获取请求体
69
+ body = await request.body()
70
+ # 获取查询参数
71
+ params = dict(request.query_params)
72
+ # 获取headers
73
+ headers = dict(request.headers)
74
+ headers.pop("host", None)
75
+
76
+ # 设置API key
77
+ headers["Authorization"] = f"Bearer {get_next_key()}"
78
+
79
+ # 构建目标URL
80
+ url = f"{Config.OPENAI_API_BASE}/{path}"
81
+
82
+ async with httpx.AsyncClient() as client:
83
+ try:
84
+ response = await client.request(
85
+ method=request.method,
86
+ url=url,
87
+ params=params,
88
+ headers=headers,
89
+ content=body
90
+ )
91
+ return response.json()
92
+ except Exception as e:
93
+ print(f"Error: {str(e)}") # 添加错误日志
94
+ raise HTTPException(status_code=500, detail=str(e))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
 
96
+ # 启动时初始化
97
  @app.on_event("startup")
98
  async def startup_event():
99
  init_keys()