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