bobocup commited on
Commit
575ed5e
·
verified ·
1 Parent(s): 329cee1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -28
app.py CHANGED
@@ -8,6 +8,7 @@ from typing import List, Optional
8
  import requests
9
  from itertools import cycle
10
  import asyncio
 
11
 
12
  # 创建FastAPI应用
13
  app = FastAPI()
@@ -26,6 +27,7 @@ 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
 
30
  # 全局变量
31
  keys = []
@@ -85,37 +87,60 @@ async def list_models():
85
 
86
  # 流式响应生成器
87
  async def stream_generator(response):
88
- async for chunk in response.aiter_bytes():
89
- yield chunk
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
 
91
  # 聊天完成路由
92
  @app.post("/api/v1/chat/completions")
93
  async def chat_completions(request: Request):
94
- # 获取请求体
95
- body = await request.body()
96
- body_json = json.loads(body)
97
-
98
- # 获取headers
99
- headers = {
100
- "Authorization": f"Bearer {get_next_key()}",
101
- "Content-Type": "application/json",
102
- "Accept": "text/event-stream" if body_json.get("stream") else "application/json"
103
- }
104
-
105
- # 构建目标URL
106
- url = f"{Config.OPENAI_API_BASE}/chat/completions"
107
-
108
- print(f"Chat request to: {url}")
109
- print(f"Headers: {headers}")
110
- print(f"Body: {json.dumps(body_json)}")
111
-
112
- async with httpx.AsyncClient() as client:
113
- try:
114
  response = await client.post(
115
  url,
116
  headers=headers,
117
- json=body_json,
118
- timeout=60.0
119
  )
120
 
121
  # 检查响应状态
@@ -131,7 +156,12 @@ async def chat_completions(request: Request):
131
  if body_json.get("stream"):
132
  return StreamingResponse(
133
  stream_generator(response),
134
- media_type="text/event-stream"
 
 
 
 
 
135
  )
136
 
137
  # 处理普通响应
@@ -140,9 +170,9 @@ async def chat_completions(request: Request):
140
  media_type=response.headers.get("content-type", "application/json")
141
  )
142
 
143
- except Exception as e:
144
- print(f"Chat Error: {str(e)}")
145
- raise HTTPException(status_code=500, detail=str(e))
146
 
147
  # 代理其他请求到X.AI
148
  @app.api_route("/api/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
 
8
  import requests
9
  from itertools import cycle
10
  import asyncio
11
+ import time
12
 
13
  # 创建FastAPI应用
14
  app = FastAPI()
 
27
  OPENAI_API_BASE = "https://api.x.ai/v1"
28
  KEYS_URL = os.getenv("KEYS_URL", "")
29
  WHITELIST_IPS = os.getenv("WHITELIST_IPS", "").split(",")
30
+ CHUNK_SIZE = 1 # 控制流式传输的块大小
31
 
32
  # 全局变量
33
  keys = []
 
87
 
88
  # 流式响应生成器
89
  async def stream_generator(response):
90
+ buffer = ""
91
+ try:
92
+ async for chunk in response.aiter_bytes():
93
+ chunk_str = chunk.decode('utf-8')
94
+ buffer += chunk_str
95
+
96
+ # 处理buffer中的完整事件
97
+ while '\n\n' in buffer:
98
+ event, buffer = buffer.split('\n\n', 1)
99
+ if event.startswith('data: '):
100
+ data = event[6:] # 移除 "data: " 前缀
101
+ if data.strip() == '[DONE]':
102
+ yield f"data: [DONE]\n\n"
103
+ else:
104
+ try:
105
+ # 解析JSON并重新格式化
106
+ json_data = json.loads(data)
107
+ yield f"data: {json.dumps(json_data)}\n\n"
108
+ # 添加小延迟使流更平滑
109
+ await asyncio.sleep(0.01)
110
+ except json.JSONDecodeError:
111
+ print(f"JSON decode error for data: {data}")
112
+ continue
113
+ except Exception as e:
114
+ print(f"Stream Error: {str(e)}")
115
+ yield f"data: {json.dumps({'error': str(e)})}\n\n"
116
 
117
  # 聊天完成路由
118
  @app.post("/api/v1/chat/completions")
119
  async def chat_completions(request: Request):
120
+ try:
121
+ # 获取请求体
122
+ body = await request.body()
123
+ body_json = json.loads(body)
124
+
125
+ # 获取headers
126
+ headers = {
127
+ "Authorization": f"Bearer {get_next_key()}",
128
+ "Content-Type": "application/json",
129
+ "Accept": "text/event-stream" if body_json.get("stream") else "application/json"
130
+ }
131
+
132
+ # 构建目标URL
133
+ url = f"{Config.OPENAI_API_BASE}/chat/completions"
134
+
135
+ print(f"Chat request to: {url}")
136
+ print(f"Headers: {headers}")
137
+ print(f"Body: {json.dumps(body_json)}")
138
+
139
+ async with httpx.AsyncClient(timeout=60.0) as client:
140
  response = await client.post(
141
  url,
142
  headers=headers,
143
+ json=body_json
 
144
  )
145
 
146
  # 检查响应状态
 
156
  if body_json.get("stream"):
157
  return StreamingResponse(
158
  stream_generator(response),
159
+ media_type="text/event-stream",
160
+ headers={
161
+ "Cache-Control": "no-cache",
162
+ "Connection": "keep-alive",
163
+ "Content-Type": "text/event-stream"
164
+ }
165
  )
166
 
167
  # 处理普通响应
 
170
  media_type=response.headers.get("content-type", "application/json")
171
  )
172
 
173
+ except Exception as e:
174
+ print(f"Chat Error: {str(e)}")
175
+ raise HTTPException(status_code=500, detail=str(e))
176
 
177
  # 代理其他请求到X.AI
178
  @app.api_route("/api/v1/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])