Skip to content

Commit facb079

Browse files
tolerate missing starlette import
1 parent 360401b commit facb079

File tree

2 files changed

+28
-77
lines changed

2 files changed

+28
-77
lines changed

tests/conftest.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
from werkzeug.wrappers import Request, Response
1717
import jsonschema
1818

19-
from starlette.testclient import TestClient
19+
try:
20+
from starlette.testclient import TestClient
21+
except ImportError:
22+
TestClient = None
2023

2124
try:
2225
import gevent

tests/integrations/mcp/test_mcp.py

Lines changed: 24 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ async def __call__(self, *args, **kwargs):
3636

3737
from starlette.routing import Mount
3838
from starlette.applications import Starlette
39-
from starlette.testclient import TestClient
4039

4140
try:
4241
from mcp.server.lowlevel.server import request_ctx
@@ -48,77 +47,6 @@ async def __call__(self, *args, **kwargs):
4847
from sentry_sdk.integrations.mcp import MCPIntegration
4948

5049

51-
def json_rpc(app, method: str, params, request_id: str | None = None):
52-
if request_id is None:
53-
request_id = "1" # arbitrary
54-
55-
with TestClient(app) as client:
56-
init_response = client.post(
57-
"/mcp/",
58-
headers={
59-
"Accept": "application/json, text/event-stream",
60-
"Content-Type": "application/json",
61-
},
62-
json={
63-
"jsonrpc": "2.0",
64-
"method": "initialize",
65-
"params": {
66-
"clientInfo": {"name": "test-client", "version": "1.0"},
67-
"protocolVersion": "2025-11-25",
68-
"capabilities": {},
69-
},
70-
"id": request_id,
71-
},
72-
)
73-
74-
session_id = init_response.headers["mcp-session-id"]
75-
76-
# Notification response is mandatory.
77-
# https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle
78-
client.post(
79-
"/mcp/",
80-
headers={
81-
"Accept": "application/json, text/event-stream",
82-
"Content-Type": "application/json",
83-
"mcp-session-id": session_id,
84-
},
85-
json={
86-
"jsonrpc": "2.0",
87-
"method": "notifications/initialized",
88-
"params": {},
89-
},
90-
)
91-
92-
response = client.post(
93-
"/mcp/",
94-
headers={
95-
"Accept": "application/json, text/event-stream",
96-
"Content-Type": "application/json",
97-
"mcp-session-id": session_id,
98-
},
99-
json={
100-
"jsonrpc": "2.0",
101-
"method": method,
102-
"params": params,
103-
"id": request_id,
104-
},
105-
)
106-
107-
return session_id, response
108-
109-
110-
def select_transactions_with_mcp_spans(events, method_name):
111-
return [
112-
transaction
113-
for transaction in events
114-
if transaction["type"] == "transaction"
115-
and any(
116-
span["data"].get("mcp.method.name") == method_name
117-
for span in transaction.get("spans", [])
118-
)
119-
]
120-
121-
12250
@pytest.fixture(autouse=True)
12351
def reset_request_ctx():
12452
"""Reset request context before and after each test"""
@@ -287,7 +215,12 @@ def test_tool(tool_name, arguments):
287215
[(True, True), (True, False), (False, True), (False, False)],
288216
)
289217
async def test_tool_handler_async(
290-
sentry_init, capture_events, send_default_pii, include_prompts
218+
sentry_init,
219+
capture_events,
220+
send_default_pii,
221+
include_prompts,
222+
json_rpc,
223+
select_transactions_with_mcp_spans,
291224
):
292225
"""Test that async tool handlers create proper spans"""
293226
sentry_init(
@@ -476,7 +409,12 @@ def test_prompt(name, arguments):
476409
[(True, True), (True, False), (False, True), (False, False)],
477410
)
478411
async def test_prompt_handler_async(
479-
sentry_init, capture_events, send_default_pii, include_prompts
412+
sentry_init,
413+
capture_events,
414+
send_default_pii,
415+
include_prompts,
416+
json_rpc,
417+
select_transactions_with_mcp_spans,
480418
):
481419
"""Test that async prompt handlers create proper spans"""
482420
sentry_init(
@@ -619,7 +557,12 @@ def test_resource(uri):
619557

620558

621559
@pytest.mark.asyncio
622-
async def test_resource_handler_async(sentry_init, capture_events):
560+
async def test_resource_handler_async(
561+
sentry_init,
562+
capture_events,
563+
json_rpc,
564+
select_transactions_with_mcp_spans,
565+
):
623566
"""Test that async resource handlers create proper spans"""
624567
sentry_init(
625568
integrations=[MCPIntegration()],
@@ -1098,7 +1041,12 @@ def test_tool(tool_name, arguments):
10981041
assert span["data"][SPANDATA.MCP_SESSION_ID] == "session-sse-123"
10991042

11001043

1101-
def test_streamable_http_transport_detection(sentry_init, capture_events):
1044+
def test_streamable_http_transport_detection(
1045+
sentry_init,
1046+
capture_events,
1047+
json_rpc,
1048+
select_transactions_with_mcp_spans,
1049+
):
11021050
"""Test that StreamableHTTP transport is correctly detected via header"""
11031051
sentry_init(
11041052
integrations=[MCPIntegration()],

0 commit comments

Comments
 (0)