bobocup commited on
Commit
58c9684
·
verified ·
1 Parent(s): 0828051

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -33
app.py CHANGED
@@ -134,21 +134,33 @@ async def access_control(request: Request, call_next):
134
 
135
  # 流式响应生成器
136
  async def stream_generator(response):
137
- async for line in response.aiter_lines():
138
- if line.strip(): # 确保行不是空的
139
- try:
140
- # 如果是JSON格式的数据,直接转发
141
- if line.startswith('{'):
142
- yield f"data: {line}\n\n"
143
- # 如果已经是SSE格式,直接发送
144
- elif line.startswith('data: '):
145
- yield f"{line}\n\n"
146
- # 其他情况,添加data前缀
147
- else:
148
- yield f"data: {line}\n\n"
149
- except Exception as e:
150
- print(f"Error processing line: {str(e)}")
151
- continue
 
 
 
 
 
 
 
 
 
 
 
 
152
 
153
  # 修改 handle_api_request 函数中的超时设置
154
  async def handle_api_request(url: str, headers: dict, method: str = "GET", body: dict = None, for_chat: bool = False):
@@ -312,37 +324,55 @@ async def add_key(request: Request):
312
  @app.post("/api/v1/chat/completions")
313
  async def chat_completions(request: Request):
314
  try:
 
315
  body = await request.body()
316
  body_json = json.loads(body)
317
 
 
318
  headers = {
 
319
  "Content-Type": "application/json",
320
- "Accept": "text/event-stream",
321
  }
322
 
323
- print("Starting chat completion request...")
 
324
 
325
- async with httpx.AsyncClient() as client:
326
- key = get_chat_key()
327
- headers["Authorization"] = f"Bearer {key}"
328
-
329
- async with client.stream(
330
- "POST",
331
- f"{Config.OPENAI_API_BASE}/chat/completions",
332
  headers=headers,
333
- json=body_json,
334
- timeout=None
335
- ) as response:
336
- if response.status_code != 200:
337
- raise HTTPException(status_code=response.status_code, detail="API request failed")
338
-
 
 
 
 
 
 
 
339
  return StreamingResponse(
340
  stream_generator(response),
341
- media_type="text/event-stream"
 
 
 
 
 
342
  )
343
-
 
 
 
 
 
 
344
  except Exception as e:
345
- print(f"Chat completion error: {str(e)}")
346
  raise HTTPException(status_code=500, detail=str(e))
347
 
348
  # 代理其他请求
 
134
 
135
  # 流式响应生成器
136
  async def stream_generator(response):
137
+ buffer = ""
138
+ try:
139
+ async for chunk in response.aiter_bytes():
140
+ chunk_str = chunk.decode('utf-8')
141
+ buffer += chunk_str
142
+
143
+ # 处理buffer中的完整事件
144
+ while '\n\n' in buffer:
145
+ event, buffer = buffer.split('\n\n', 1)
146
+ if event.startswith('data: '):
147
+ data = event[6:] # 移除 "data: " 前缀
148
+ if data.strip() == '[DONE]':
149
+ yield f"data: [DONE]\n\n"
150
+ else:
151
+ try:
152
+ # 解析JSON并重新格式化
153
+ json_data = json.loads(data)
154
+ yield f"data: {json.dumps(json_data)}\n\n"
155
+ # 添加小延迟使流更平滑
156
+ await asyncio.sleep(0.01)
157
+ except json.JSONDecodeError:
158
+ print(f"JSON decode error for data: {data}")
159
+ continue
160
+ except Exception as e:
161
+ print(f"Stream Error: {str(e)}")
162
+ yield f"data: {json.dumps({'error': str(e)})}\n\n"
163
+
164
 
165
  # 修改 handle_api_request 函数中的超时设置
166
  async def handle_api_request(url: str, headers: dict, method: str = "GET", body: dict = None, for_chat: bool = False):
 
324
  @app.post("/api/v1/chat/completions")
325
  async def chat_completions(request: Request):
326
  try:
327
+ # 获取请求体
328
  body = await request.body()
329
  body_json = json.loads(body)
330
 
331
+ # 获取headers
332
  headers = {
333
+ "Authorization": f"Bearer {get_next_key()}",
334
  "Content-Type": "application/json",
335
+ "Accept": "text/event-stream" if body_json.get("stream") else "application/json"
336
  }
337
 
338
+ # 构建目标URL
339
+ url = f"{Config.OPENAI_API_BASE}/chat/completions"
340
 
341
+ async with httpx.AsyncClient(timeout=60.0) as client:
342
+ response = await client.post(
343
+ url,
 
 
 
 
344
  headers=headers,
345
+ json=body_json
346
+ )
347
+
348
+ # 检查响应状态
349
+ if response.status_code != 200:
350
+ return Response(
351
+ content=response.text,
352
+ status_code=response.status_code,
353
+ media_type=response.headers.get("content-type", "application/json")
354
+ )
355
+
356
+ # 处理流式响应
357
+ if body_json.get("stream"):
358
  return StreamingResponse(
359
  stream_generator(response),
360
+ media_type="text/event-stream",
361
+ headers={
362
+ "Cache-Control": "no-cache",
363
+ "Connection": "keep-alive",
364
+ "Content-Type": "text/event-stream"
365
+ }
366
  )
367
+
368
+ # 处理普通响应
369
+ return Response(
370
+ content=response.text,
371
+ media_type=response.headers.get("content-type", "application/json")
372
+ )
373
+
374
  except Exception as e:
375
+ print(f"Chat Error: {str(e)}")
376
  raise HTTPException(status_code=500, detail=str(e))
377
 
378
  # 代理其他请求