gcli2api / src /router /stream_passthrough.py
a3216's picture
sync: github -> hf space
c50496f
from typing import Any, AsyncIterator
from fastapi import Response
from fastapi.responses import StreamingResponse
async def prepend_async_item(first_item: Any, iterator: AsyncIterator[Any]):
"""Yield a prefetched item before continuing the original iterator."""
yield first_item
async for item in iterator:
yield item
async def read_first_async_item(iterator: AsyncIterator[Any]) -> Any:
"""Python 3.9-compatible async equivalent of built-in anext()."""
return await iterator.__anext__()
async def build_streaming_response_or_error(
iterator: AsyncIterator[Any],
media_type: str = "text/event-stream",
):
"""
Prefetch the first async item so router code can return an upstream error
response directly before FastAPI commits a 200 streaming response.
"""
try:
first_item = await read_first_async_item(iterator)
except StopAsyncIteration:
return Response(status_code=204)
if isinstance(first_item, Response):
return first_item
return StreamingResponse(
prepend_async_item(first_item, iterator),
media_type=media_type,
)