Skip to content

ccproxy.api.middleware.streaming_hooks

ccproxy.api.middleware.streaming_hooks

Streaming response wrapper for hook emission.

This module provides a wrapper for streaming responses that emits REQUEST_COMPLETED hook event when the stream actually completes.

StreamingResponseWithHooks

StreamingResponseWithHooks(
    content,
    hook_manager,
    request_id,
    request_data,
    start_time,
    status_code=200,
    request_metadata=None,
    origin="client",
    is_sse=False,
    **kwargs,
)

Bases: StreamingResponse

Streaming response wrapper that emits hooks on completion.

This wrapper ensures REQUEST_COMPLETED is emitted when streaming actually finishes, not when the response is initially created.

Parameters:

Name Type Description Default
content AsyncGenerator[bytes, None] | AsyncIterator[bytes]

The async generator producing streaming content

required
hook_manager HookManager | None

Hook manager for emitting events

required
request_id str

Request ID for correlation

required
request_data dict[str, Any]

Original request data for context

required
start_time float

Request start timestamp

required
status_code int

HTTP status code for the response

200
request_metadata dict[str, Any] | None

Metadata from RequestContext (includes tokens, cost, etc.)

None
**kwargs Any

Additional arguments passed to StreamingResponse

{}
Source code in ccproxy/api/middleware/streaming_hooks.py
def __init__(
    self,
    content: AsyncGenerator[bytes, None] | AsyncIterator[bytes],
    hook_manager: HookManager | None,
    request_id: str,
    request_data: dict[str, Any],
    start_time: float,
    status_code: int = 200,
    request_metadata: dict[str, Any] | None = None,
    origin: str = "client",
    is_sse: bool = False,
    **kwargs: Any,
) -> None:
    """Initialize streaming response with hook emission.

    Args:
        content: The async generator producing streaming content
        hook_manager: Hook manager for emitting events
        request_id: Request ID for correlation
        request_data: Original request data for context
        start_time: Request start timestamp
        status_code: HTTP status code for the response
        request_metadata: Metadata from RequestContext (includes tokens, cost, etc.)
        **kwargs: Additional arguments passed to StreamingResponse
    """
    self.hook_manager = hook_manager
    self.request_id = request_id
    self.request_data = request_data
    self.request_metadata = request_metadata or {}
    self.start_time = start_time
    self.origin = origin
    self.is_sse = is_sse

    # Wrap the content generator to add hook emission
    wrapped_content = self._wrap_with_hooks(content, status_code)

    super().__init__(wrapped_content, status_code=status_code, **kwargs)