pythoncookiesfastapiserver-sent-events

Cannot set cookies when using StreamingResponse in FastAPI route for SSE (Server-Sent Events)


I am working on a FastAPI application where I need to set an HTTP cookie while streaming data to the client using Server-Sent Events (SSE). However, I am encountering an issue where the cookie is not being set in the client browser when I use response.set_cookie inside the FastAPI route that returns the StreamingResponse.

from fastapi import FastAPI, Response, Request
from starlette.responses import StreamingResponse

app = FastAPI()

@app.get("/stream")
async def stream(response: Response, request: Request):
    # Example function to handle session management
    user_chat_session = handle_session(request, response, redis_client)

    # Attempt to set a cookie
    response.set_cookie(
        key="chat_session",
        value="test",
        httponly=True,
        expires=3600,  # 1-hour expiration
    )
    
    # Return a streaming response for SSE
    return StreamingResponse(
        chat_client.stream(question="hello", user_chat_session=user_chat_session),
        media_type="text/event-stream"
    )

The Problem:

The cookie chat_session is not being set on the client side. I understand that response.set_cookie modifies the HTTP headers, and I suspect this issue might be related to how StreamingResponse works.

Since SSE uses a streaming connection, the response headers are sent immediately, and once the headers are sent, it’s no longer possible to modify them (which is likely why set_cookie isn’t taking effect).

Important Detail:

If I remove the StreamingResponse and instead return a normal response (like return {"message": "test"}), the cookie is set correctly. This makes me believe the issue is specific to StreamingResponse and how it handles response headers in an SSE setup.

My Questions:

  1. Is it possible to set cookies while also sending a StreamingResponse in FastAPI?

  2. If not, what would be the best workaround?

Any insights, suggestions, or best practices on handling cookies in combination with SSE would be greatly appreciated!

What I’ve Tried:


Solution

  • You have set the cookie on the wrong response. Please update your code as follows, and it will work correctly.

    @app.get("/stream")
    async def stream(response: Response, request: Request):
        # Example function to handle session management
        user_chat_session = handle_session(request, response, redis_client)
    
        # Return a streaming response for SSE
        streaming_response = StreamingResponse(
            chat_client.stream(question="hello", user_chat_session=user_chat_session),
            media_type="text/event-stream"
        )
    
    
        # Set a cookie
        streaming_response.set_cookie(
            key="chat_session",
            value="test",
            httponly=True,
            expires=3600,  # 1-hour expiration
        )
        
    
        return streaming_response