10
10
11
11
# Create Starlette routes for SSE and message handling
12
12
routes = [
13
- Route("/sse", endpoint=handle_sse),
13
+ Route("/sse", endpoint=handle_sse, methods=["GET"] ),
14
14
Mount("/messages/", app=sse.handle_post_message),
15
15
]
16
16
@@ -22,12 +22,18 @@ async def handle_sse(request):
22
22
await app.run(
23
23
streams[0], streams[1], app.create_initialization_options()
24
24
)
25
+ # Return empty response to avoid NoneType error
26
+ return Response()
25
27
26
28
# Create and run Starlette app
27
29
starlette_app = Starlette(routes=routes)
28
30
uvicorn.run(starlette_app, host="0.0.0.0", port=port)
29
31
```
30
32
33
+ Note: The handle_sse function must return a Response to avoid a "TypeError: 'NoneType'
34
+ object is not callable" error when client disconnects. The example above returns
35
+ an empty Response() after the SSE connection ends to fix this.
36
+
31
37
See SseServerTransport class documentation for more details.
32
38
"""
33
39
@@ -120,11 +126,22 @@ async def sse_writer():
120
126
)
121
127
122
128
async with anyio .create_task_group () as tg :
123
- response = EventSourceResponse (
124
- content = sse_stream_reader , data_sender_callable = sse_writer
125
- )
129
+
130
+ async def response_wrapper (scope : Scope , receive : Receive , send : Send ):
131
+ """
132
+ The EventSourceResponse returning signals a client close / disconnect.
133
+ In this case we close our side of the streams to signal the client that
134
+ the connection has been closed.
135
+ """
136
+ await EventSourceResponse (
137
+ content = sse_stream_reader , data_sender_callable = sse_writer
138
+ )(scope , receive , send )
139
+ await read_stream_writer .aclose ()
140
+ await write_stream_reader .aclose ()
141
+ logging .debug (f"Client session disconnected { session_id } " )
142
+
126
143
logger .debug ("Starting SSE response task" )
127
- tg .start_soon (response , scope , receive , send )
144
+ tg .start_soon (response_wrapper , scope , receive , send )
128
145
129
146
logger .debug ("Yielding read and write streams" )
130
147
yield (read_stream , write_stream )
0 commit comments