2121 EmptyResult ,
2222 ErrorData ,
2323 InitializeResult ,
24+ ReadResourceResult ,
2425 TextContent ,
2526 TextResourceContents ,
2627 Tool ,
@@ -50,7 +51,11 @@ def __init__(self):
5051 async def handle_read_resource (uri : AnyUrl ) -> str | bytes :
5152 if uri .scheme == "foobar" :
5253 return f"Read { uri .host } "
53- # TODO: make this an error
54+ elif uri .scheme == "slow" :
55+ # Simulate a slow resource
56+ await anyio .sleep (2.0 )
57+ return f"Slow response from { uri .host } "
58+
5459 raise McpError (
5560 error = ErrorData (
5661 code = 404 , message = "OOPS! no resource with that URI was found"
@@ -200,12 +205,13 @@ async def test_sse_client_basic_connection(server: None, server_url: str) -> Non
200205async def initialized_sse_client_session (
201206 server , server_url : str
202207) -> AsyncGenerator [ClientSession , None ]:
203- async with sse_client (server_url + "/sse" ) as streams :
208+ async with sse_client (server_url + "/sse" , sse_read_timeout = 0.5 ) as streams :
204209 async with ClientSession (* streams ) as session :
205210 await session .initialize ()
206211 yield session
207212
208213
214+
209215@pytest .mark .anyio
210216async def test_sse_client_happy_request_and_response (
211217 initialized_sse_client_session : ClientSession ,
@@ -226,4 +232,23 @@ async def test_sse_client_exception_handling(
226232 await session .read_resource (uri = AnyUrl ("xxx://will-not-work" ))
227233
228234
229- # TODO: test that timeouts are respected and that the error comes back
235+ @pytest .mark .anyio
236+ @pytest .mark .skip (
237+ "this test highlights a possible bug in SSE read timeout exception handling"
238+ )
239+ async def test_sse_client_timeout (
240+ initialized_sse_client_session : ClientSession ,
241+ ) -> None :
242+ session = initialized_sse_client_session
243+
244+ # sanity check that normal, fast responses are working
245+ response = await session .read_resource (uri = AnyUrl ("foobar://1" ))
246+ assert isinstance (response , ReadResourceResult )
247+
248+ with anyio .move_on_after (3 ):
249+ with pytest .raises (McpError , match = "Read timed out" ):
250+ response = await session .read_resource (uri = AnyUrl ("slow://2" ))
251+ # we should receive an error here
252+ return
253+
254+ pytest .fail ("the client should have timed out and returned an error already" )
0 commit comments