CassiopeiaCode commited on
Commit
2c96fd3
·
1 Parent(s): f05f74b

修复流式响应:等待首个内容后再返回200

Browse files
Files changed (1) hide show
  1. app.py +45 -36
app.py CHANGED
@@ -365,48 +365,57 @@ def chat_completions(req: ChatCompletionRequest, account: Dict[str, Any] = Depen
365
  created = int(time.time())
366
  stream_id = f"chatcmpl-{uuid.uuid4()}"
367
  model_used = model or "unknown"
368
-
369
- def event_gen() -> Generator[str, None, None]:
370
- tracker = None
371
- first_chunk = True
372
- try:
373
- _, it, tracker = _send_upstream(stream=True)
374
- assert it is not None
375
- for piece in it:
376
- if not piece:
377
- continue
378
- if first_chunk:
379
- yield _sse_format({
380
- "id": stream_id,
381
- "object": "chat.completion.chunk",
382
- "created": created,
383
- "model": model_used,
384
- "choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": None}],
385
- })
386
- first_chunk = False
387
  yield _sse_format({
388
  "id": stream_id,
389
  "object": "chat.completion.chunk",
390
  "created": created,
391
  "model": model_used,
392
- "choices": [{"index": 0, "delta": {"content": piece}, "finish_reason": None}],
393
  })
394
- yield _sse_format({
395
- "id": stream_id,
396
- "object": "chat.completion.chunk",
397
- "created": created,
398
- "model": model_used,
399
- "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}],
400
- })
401
- yield "data: [DONE]\n\n"
402
- if tracker:
403
- _update_stats(account["id"], tracker.has_content)
404
- except Exception:
405
- if tracker:
406
- _update_stats(account["id"], tracker.has_content)
407
- raise
408
-
409
- return StreamingResponse(event_gen(), media_type="text/event-stream")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
  # ------------------------------------------------------------------------------
412
  # Device Authorization (URL Login, 5-minute timeout)
 
365
  created = int(time.time())
366
  stream_id = f"chatcmpl-{uuid.uuid4()}"
367
  model_used = model or "unknown"
368
+
369
+ try:
370
+ _, it, tracker = _send_upstream(stream=True)
371
+ assert it is not None
372
+ first_piece = next(it, None)
373
+ if not first_piece:
374
+ _update_stats(account["id"], False)
375
+ raise HTTPException(status_code=502, detail="No content from upstream")
376
+
377
+ def event_gen() -> Generator[str, None, None]:
378
+ try:
 
 
 
 
 
 
 
 
379
  yield _sse_format({
380
  "id": stream_id,
381
  "object": "chat.completion.chunk",
382
  "created": created,
383
  "model": model_used,
384
+ "choices": [{"index": 0, "delta": {"role": "assistant"}, "finish_reason": None}],
385
  })
386
+ yield _sse_format({
387
+ "id": stream_id,
388
+ "object": "chat.completion.chunk",
389
+ "created": created,
390
+ "model": model_used,
391
+ "choices": [{"index": 0, "delta": {"content": first_piece}, "finish_reason": None}],
392
+ })
393
+ for piece in it:
394
+ if piece:
395
+ yield _sse_format({
396
+ "id": stream_id,
397
+ "object": "chat.completion.chunk",
398
+ "created": created,
399
+ "model": model_used,
400
+ "choices": [{"index": 0, "delta": {"content": piece}, "finish_reason": None}],
401
+ })
402
+ yield _sse_format({
403
+ "id": stream_id,
404
+ "object": "chat.completion.chunk",
405
+ "created": created,
406
+ "model": model_used,
407
+ "choices": [{"index": 0, "delta": {}, "finish_reason": "stop"}],
408
+ })
409
+ yield "data: [DONE]\n\n"
410
+ _update_stats(account["id"], True)
411
+ except Exception:
412
+ _update_stats(account["id"], tracker.has_content if tracker else False)
413
+ raise
414
+
415
+ return StreamingResponse(event_gen(), media_type="text/event-stream")
416
+ except Exception as e:
417
+ _update_stats(account["id"], False)
418
+ raise
419
 
420
  # ------------------------------------------------------------------------------
421
  # Device Authorization (URL Login, 5-minute timeout)