Skip to content

Commit 07e721f

Browse files
committed
formatting
1 parent 5097bb7 commit 07e721f

File tree

1 file changed

+65
-27
lines changed

1 file changed

+65
-27
lines changed

tests/shared/test_sse.py

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# test_sse.py
21
import re
32
import multiprocessing
43
import socket
@@ -21,20 +20,30 @@
2120
from mcp.client.sse import sse_client
2221
from mcp.server import Server
2322
from mcp.server.sse import SseServerTransport
24-
from mcp.types import EmptyResult, ErrorData, InitializeResult, TextContent, TextResourceContents, Tool
23+
from mcp.types import (
24+
EmptyResult,
25+
ErrorData,
26+
InitializeResult,
27+
TextContent,
28+
TextResourceContents,
29+
Tool,
30+
)
2531

2632
SERVER_NAME = "test_server_for_SSE"
2733

34+
2835
@pytest.fixture
2936
def server_port() -> int:
3037
with socket.socket() as s:
31-
s.bind(('127.0.0.1', 0))
38+
s.bind(("127.0.0.1", 0))
3239
return s.getsockname()[1]
3340

41+
3442
@pytest.fixture
3543
def server_url(server_port: int) -> str:
3644
return f"http://127.0.0.1:{server_port}"
3745

46+
3847
# Test server implementation
3948
class TestServer(Server):
4049
def __init__(self):
@@ -45,15 +54,19 @@ async def handle_read_resource(uri: AnyUrl) -> str | bytes:
4554
if uri.scheme == "foobar":
4655
return f"Read {uri.host}"
4756
# TODO: make this an error
48-
raise McpError(error=ErrorData(code=404, message="OOPS! no resource with that URI was found"))
57+
raise McpError(
58+
error=ErrorData(
59+
code=404, message="OOPS! no resource with that URI was found"
60+
)
61+
)
4962

5063
@self.list_tools()
5164
async def handle_list_tools():
5265
return [
5366
Tool(
5467
name="test_tool",
5568
description="A test tool",
56-
inputSchema={"type": "object", "properties": {}}
69+
inputSchema={"type": "object", "properties": {}},
5770
)
5871
]
5972

@@ -62,9 +75,8 @@ async def handle_call_tool(name: str, args: dict):
6275
return [TextContent(type="text", text=f"Called {name}")]
6376

6477

65-
6678
# Test fixtures
67-
def make_server_app()-> Starlette:
79+
def make_server_app() -> Starlette:
6880
"""Create test Starlette app with SSE transport"""
6981
sse = SseServerTransport("/messages/")
7082
server = TestServer()
@@ -74,80 +86,97 @@ async def handle_sse(request):
7486
request.scope, request.receive, request._send
7587
) as streams:
7688
await server.run(
77-
streams[0],
78-
streams[1],
79-
server.create_initialization_options()
89+
streams[0], streams[1], server.create_initialization_options()
8090
)
8191

82-
app = Starlette(routes=[
83-
Route("/sse", endpoint=handle_sse),
84-
Mount("/messages/", app=sse.handle_post_message),
85-
])
92+
app = Starlette(
93+
routes=[
94+
Route("/sse", endpoint=handle_sse),
95+
Mount("/messages/", app=sse.handle_post_message),
96+
]
97+
)
8698

8799
return app
88100

101+
89102
@pytest.fixture(autouse=True)
90103
def space_around_test():
91104
time.sleep(0.1)
92105
yield
93106
time.sleep(0.1)
94107

108+
95109
def run_server(server_port: int):
96110
app = make_server_app()
97-
server = uvicorn.Server(config=uvicorn.Config(app=app, host="127.0.0.1", port=server_port, log_level="error"))
98-
print(f'starting server on {server_port}')
111+
server = uvicorn.Server(
112+
config=uvicorn.Config(
113+
app=app, host="127.0.0.1", port=server_port, log_level="error"
114+
)
115+
)
116+
print(f"starting server on {server_port}")
99117
server.run()
100118

101119
# Give server time to start
102120
while not server.started:
103-
print('waiting for server to start')
121+
print("waiting for server to start")
104122
time.sleep(0.5)
105123

124+
106125
@pytest.fixture()
107126
def server(server_port: int):
108-
proc = multiprocessing.Process(target=run_server, kwargs={"server_port": server_port}, daemon=True)
109-
print('starting process')
127+
proc = multiprocessing.Process(
128+
target=run_server, kwargs={"server_port": server_port}, daemon=True
129+
)
130+
print("starting process")
110131
proc.start()
111132

112133
# Wait for server to be running
113134
max_attempts = 20
114135
attempt = 0
115-
print('waiting for server to start')
136+
print("waiting for server to start")
116137
while attempt < max_attempts:
117138
try:
118139
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
119-
s.connect(('127.0.0.1', server_port))
140+
s.connect(("127.0.0.1", server_port))
120141
break
121142
except ConnectionRefusedError:
122143
time.sleep(0.1)
123144
attempt += 1
124145
else:
125-
raise RuntimeError("Server failed to start after {} attempts".format(max_attempts))
146+
raise RuntimeError(
147+
"Server failed to start after {} attempts".format(max_attempts)
148+
)
126149

127150
yield
128151

129-
print('killing server')
152+
print("killing server")
130153
# Signal the server to stop
131154
proc.kill()
132155
proc.join(timeout=2)
133156
if proc.is_alive():
134157
print("server process failed to terminate")
135158

159+
136160
@pytest.fixture()
137161
async def http_client(server, server_url) -> AsyncGenerator[httpx.AsyncClient, None]:
138162
"""Create test client"""
139163
async with httpx.AsyncClient(base_url=server_url) as client:
140164
yield client
141165

166+
142167
# Tests
143168
@pytest.mark.anyio
144169
async def test_raw_sse_connection(http_client: httpx.AsyncClient):
145170
"""Test the SSE connection establishment simply with an HTTP client."""
146171
async with anyio.create_task_group() as tg:
172+
147173
async def connection_test():
148174
async with http_client.stream("GET", "/sse") as response:
149175
assert response.status_code == 200
150-
assert response.headers["content-type"] == "text/event-stream; charset=utf-8"
176+
assert (
177+
response.headers["content-type"]
178+
== "text/event-stream; charset=utf-8"
179+
)
151180

152181
line_number = 0
153182
async for line in response.aiter_lines():
@@ -177,23 +206,32 @@ async def test_sse_client_basic_connection(server, server_url):
177206
ping_result = await session.send_ping()
178207
assert isinstance(ping_result, EmptyResult)
179208

209+
180210
@pytest.fixture
181-
async def initialized_sse_client_session(server, server_url: str) -> AsyncGenerator[ClientSession, None]:
211+
async def initialized_sse_client_session(
212+
server, server_url: str
213+
) -> AsyncGenerator[ClientSession, None]:
182214
async with sse_client(server_url + "/sse") as streams:
183215
async with ClientSession(*streams) as session:
184216
await session.initialize()
185217
yield session
186218

219+
187220
@pytest.mark.anyio
188-
async def test_sse_client_happy_request_and_response(initialized_sse_client_session: ClientSession):
221+
async def test_sse_client_happy_request_and_response(
222+
initialized_sse_client_session: ClientSession,
223+
):
189224
session = initialized_sse_client_session
190225
response = await session.read_resource(uri=AnyUrl("foobar://should-work"))
191226
assert len(response.contents) == 1
192227
assert isinstance(response.contents[0], TextResourceContents)
193228
assert response.contents[0].text == "Read should-work"
194229

230+
195231
@pytest.mark.anyio
196-
async def test_sse_client_exception_handling(initialized_sse_client_session: ClientSession):
232+
async def test_sse_client_exception_handling(
233+
initialized_sse_client_session: ClientSession,
234+
):
197235
session = initialized_sse_client_session
198236
with pytest.raises(McpError, match="OOPS! no resource with that URI was found"):
199237
await session.read_resource(uri=AnyUrl("xxx://will-not-work"))

0 commit comments

Comments
 (0)