Send a streaming request and process the response.
(url, headers, data, stream_name)
| 443 | print(f"Error: {self.error_message}") |
| 444 | |
| 445 | async def stream_response(url, headers, data, stream_name): |
| 446 | """Send a streaming request and process the response.""" |
| 447 | print(f"\nStarting {stream_name} stream...") |
| 448 | stats = StreamStats() |
| 449 | error = None |
| 450 | |
| 451 | try: |
| 452 | async with httpx.AsyncClient() as client: |
| 453 | # Add stream flag to ensure it's streamed |
| 454 | request_data = data.copy() |
| 455 | request_data["stream"] = True |
| 456 | |
| 457 | start_time = time.time() |
| 458 | async with client.stream("POST", url, json=request_data, headers=headers, timeout=30) as response: |
| 459 | if response.status_code != 200: |
| 460 | error_text = await response.aread() |
| 461 | stats.has_error = True |
| 462 | stats.error_message = f"HTTP {response.status_code}: {error_text.decode('utf-8')}" |
| 463 | error = stats.error_message |
| 464 | print(f"Error: {stats.error_message}") |
| 465 | return stats, error |
| 466 | |
| 467 | print(f"{stream_name} connected, receiving events...") |
| 468 | |
| 469 | # Process each chunk |
| 470 | buffer = "" |
| 471 | async for chunk in response.aiter_text(): |
| 472 | if not chunk.strip(): |
| 473 | continue |
| 474 | |
| 475 | # Handle multiple events in one chunk |
| 476 | buffer += chunk |
| 477 | events = buffer.split("\n\n") |
| 478 | |
| 479 | # Process all complete events |
| 480 | for event_text in events[:-1]: # All but the last (possibly incomplete) event |
| 481 | if not event_text.strip(): |
| 482 | continue |
| 483 | |
| 484 | # Parse server-sent event format |
| 485 | if "data: " in event_text: |
| 486 | # Extract the data part |
| 487 | data_parts = [] |
| 488 | for line in event_text.split("\n"): |
| 489 | if line.startswith("data: "): |
| 490 | data_part = line[len("data: "):] |
| 491 | # Skip the "[DONE]" marker |
| 492 | if data_part == "[DONE]": |
| 493 | break |
| 494 | data_parts.append(data_part) |
| 495 | |
| 496 | if data_parts: |
| 497 | try: |
| 498 | event_data = json.loads("".join(data_parts)) |
| 499 | stats.add_event(event_data) |
| 500 | except json.JSONDecodeError as e: |
| 501 | print(f"Error parsing event: {e}\nRaw data: {''.join(data_parts)}") |
| 502 |
no test coverage detected