Skip to content

Commit eb74b7c

Browse files
committed
refactor: rename send_request to send_raw_request in JSONRPCDispatcher
Follows the Outbound Protocol rename in the previous commit. Mechanical rename across JSONRPCDispatcher, _JSONRPCDispatchContext, and tests.
1 parent 0a8f0f4 commit eb74b7c

2 files changed

Lines changed: 27 additions & 27 deletions

File tree

src/mcp/shared/jsonrpc_dispatcher.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,15 @@ def can_send_request(self) -> bool:
112112
async def notify(self, method: str, params: Mapping[str, Any] | None) -> None:
113113
await self._dispatcher.notify(method, params, _related_request_id=self._request_id)
114114

115-
async def send_request(
115+
async def send_raw_request(
116116
self,
117117
method: str,
118118
params: Mapping[str, Any] | None,
119119
opts: CallOptions | None = None,
120120
) -> dict[str, Any]:
121121
if not self.can_send_request:
122122
raise NoBackChannelError(method)
123-
return await self._dispatcher.send_request(method, params, opts, _related_request_id=self._request_id)
123+
return await self._dispatcher.send_raw_request(method, params, opts, _related_request_id=self._request_id)
124124

125125
async def progress(self, progress: float, total: float | None = None, message: str | None = None) -> None:
126126
if self._progress_token is None:
@@ -208,7 +208,7 @@ def __init__(
208208
self._tg: anyio.abc.TaskGroup | None = None
209209
self._running = False
210210

211-
async def send_request(
211+
async def send_raw_request(
212212
self,
213213
method: str,
214214
params: Mapping[str, Any] | None,
@@ -232,7 +232,7 @@ async def send_request(
232232
finished.
233233
"""
234234
if not self._running:
235-
raise RuntimeError("JSONRPCDispatcher.send_request called before run() / after close")
235+
raise RuntimeError("JSONRPCDispatcher.send_raw_request called before run() / after close")
236236
opts = opts or {}
237237
request_id = self._allocate_id()
238238
out_params = dict(params) if params is not None else None
@@ -308,7 +308,7 @@ async def run(
308308
309309
Each inbound request is handled in its own task in an internal task
310310
group; ``task_status.started()`` fires once that group is open, so
311-
``await tg.start(dispatcher.run, ...)`` resumes when ``send_request``
311+
``await tg.start(dispatcher.run, ...)`` resumes when ``send_raw_request``
312312
is usable.
313313
"""
314314
try:
@@ -323,9 +323,9 @@ async def run(
323323
# snapshot per message). Plain memory streams don't.
324324
sender_ctx: contextvars.Context | None = getattr(self._read_stream, "last_context", None)
325325
self._dispatch(item, on_request, on_notify, sender_ctx)
326-
# Read stream EOF: wake any blocked `send_request` waiters now,
326+
# Read stream EOF: wake any blocked `send_raw_request` waiters now,
327327
# *before* the task group joins, so handlers parked in
328-
# `dctx.send_request()` can unwind and the join doesn't deadlock.
328+
# `dctx.send_raw_request()` can unwind and the join doesn't deadlock.
329329
self._running = False
330330
self._fan_out_closed()
331331
finally:
@@ -457,7 +457,7 @@ def _spawn(
457457
self._tg.start_soon(fn, *args)
458458

459459
def _fan_out_closed(self) -> None:
460-
"""Wake every pending ``send_request`` waiter with ``CONNECTION_CLOSED``.
460+
"""Wake every pending ``send_raw_request`` waiter with ``CONNECTION_CLOSED``.
461461
462462
Synchronous (uses ``send_nowait``) because it's called from ``finally``
463463
which may be inside a cancelled scope. Idempotent.
@@ -491,7 +491,7 @@ async def _handle_request(
491491
# Close the back-channel the moment the handler exits
492492
# (success or raise), before the response write — a handler
493493
# spawning detached work that later calls
494-
# `dctx.send_request()` should see `NoBackChannelError`.
494+
# `dctx.send_raw_request()` should see `NoBackChannelError`.
495495
dctx.close()
496496
await self._write_result(req.id, result)
497497
# Peer-cancel: `_dispatch_notification` cancelled this scope. anyio

tests/shared/test_jsonrpc_dispatcher.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242

4343
@pytest.mark.anyio
44-
async def test_concurrent_send_requests_correlate_by_id_when_responses_arrive_out_of_order():
44+
async def test_concurrent_send_raw_requests_correlate_by_id_when_responses_arrive_out_of_order():
4545
release_first = anyio.Event()
4646

4747
async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] | None) -> dict[str, Any]:
@@ -53,7 +53,7 @@ async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] |
5353
results: dict[str, dict[str, Any]] = {}
5454

5555
async def call(method: str) -> None:
56-
results[method] = await client.send_request(method, None)
56+
results[method] = await client.send_raw_request(method, None)
5757

5858
with anyio.fail_after(5):
5959
async with anyio.create_task_group() as tg: # pragma: no branch
@@ -76,7 +76,7 @@ async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] |
7676

7777
async with running_pair(jsonrpc_pair, server_on_request=server_on_request) as (client, *_):
7878
with anyio.fail_after(5), pytest.raises(MCPError) as exc:
79-
await client.send_request("tools/list", None)
79+
await client.send_raw_request("tools/list", None)
8080
assert exc.value.error.code == INTERNAL_ERROR
8181
assert exc.value.error.message == "kaboom"
8282
assert exc.value.__cause__ is None # cause does not survive the wire
@@ -103,7 +103,7 @@ async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] |
103103

104104
async def call_then_record() -> None:
105105
with pytest.raises(MCPError): # we'll cancel via tg below
106-
await client.send_request("slow", None)
106+
await client.send_raw_request("slow", None)
107107

108108
tg.start_soon(call_then_record)
109109
await handler_started.wait()
@@ -140,7 +140,7 @@ def factory(*, can_send_request: bool = True):
140140
async with anyio.create_task_group() as tg: # pragma: no branch
141141

142142
async def call() -> None:
143-
result_box.append(await client.send_request("slow", None))
143+
result_box.append(await client.send_raw_request("slow", None))
144144

145145
tg.start_soon(call)
146146
await handler_started.wait()
@@ -150,8 +150,8 @@ async def call() -> None:
150150

151151

152152
@pytest.mark.anyio
153-
async def test_send_request_raises_connection_closed_when_read_stream_eofs_mid_await():
154-
"""A blocked send_request is woken with CONNECTION_CLOSED when run() exits."""
153+
async def test_send_raw_request_raises_connection_closed_when_read_stream_eofs_mid_await():
154+
"""A blocked send_raw_request is woken with CONNECTION_CLOSED when run() exits."""
155155
c2s_send, c2s_recv = anyio.create_memory_object_stream[SessionMessage | Exception](32)
156156
s2c_send, s2c_recv = anyio.create_memory_object_stream[SessionMessage | Exception](32)
157157
client: JSONRPCDispatcher[TransportContext] = JSONRPCDispatcher(s2c_recv, c2s_send)
@@ -162,7 +162,7 @@ async def test_send_request_raises_connection_closed_when_read_stream_eofs_mid_a
162162

163163
async def caller() -> None:
164164
with pytest.raises(MCPError) as exc:
165-
await client.send_request("ping", None)
165+
await client.send_raw_request("ping", None)
166166
assert exc.value.error.code == CONNECTION_CLOSED
167167

168168
tg.start_soon(caller)
@@ -187,13 +187,13 @@ async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] |
187187
async with running_pair(jsonrpc_pair, server_on_request=server_on_request) as (client, *_):
188188
with anyio.fail_after(5):
189189
with pytest.raises(MCPError): # REQUEST_TIMEOUT
190-
await client.send_request("slow", None, {"timeout": 0})
190+
await client.send_raw_request("slow", None, {"timeout": 0})
191191
# The server handler is still running; let it finish and write a
192192
# response for an id the client has already discarded.
193193
await handler_started.wait()
194194
proceed.set()
195195
# One more round-trip proves the dispatcher is still healthy.
196-
assert await client.send_request("ping", None) == {"late": True}
196+
assert await client.send_raw_request("ping", None) == {"late": True}
197197

198198

199199
@pytest.mark.anyio
@@ -234,14 +234,14 @@ async def on_notify(ctx: DCtx, method: str, params: Mapping[str, Any] | None) ->
234234

235235

236236
@pytest.mark.anyio
237-
async def test_ctx_send_request_tags_outbound_with_server_message_metadata():
237+
async def test_ctx_send_raw_request_tags_outbound_with_server_message_metadata():
238238
"""Server-to-client requests carry related_request_id for SHTTP routing."""
239239
c2s_send, c2s_recv = anyio.create_memory_object_stream[SessionMessage | Exception](32)
240240
s2c_send, s2c_recv = anyio.create_memory_object_stream[SessionMessage | Exception](32)
241241
server: JSONRPCDispatcher[TransportContext] = JSONRPCDispatcher(c2s_recv, s2c_send)
242242

243243
async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] | None) -> dict[str, Any]:
244-
return await ctx.send_request("sampling/createMessage", {"prompt": "hi"})
244+
return await ctx.send_raw_request("sampling/createMessage", {"prompt": "hi"})
245245

246246
async def on_notify(ctx: DCtx, method: str, params: Mapping[str, Any] | None) -> None:
247247
raise NotImplementedError
@@ -285,7 +285,7 @@ async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] |
285285

286286
async with running_pair(jsonrpc_pair, server_on_request=server_on_request) as (client, *_):
287287
with anyio.fail_after(5):
288-
await client.send_request("t", None, {"on_progress": on_progress})
288+
await client.send_raw_request("t", None, {"on_progress": on_progress})
289289
assert received == [(0.25, None, None)]
290290

291291

@@ -297,18 +297,18 @@ async def server_on_request(ctx: DCtx, method: str, params: Mapping[str, Any] |
297297

298298
async with running_pair(jsonrpc_pair, server_on_request=server_on_request) as (client, *_):
299299
with anyio.fail_after(5), pytest.raises(MCPError) as exc:
300-
await client.send_request("t", None)
300+
await client.send_raw_request("t", None)
301301
assert exc.value.error.code == INVALID_PARAMS
302302

303303

304304
@pytest.mark.anyio
305-
async def test_send_request_before_run_raises_runtimeerror():
305+
async def test_send_raw_request_before_run_raises_runtimeerror():
306306
c2s_send, c2s_recv = anyio.create_memory_object_stream[SessionMessage | Exception](1)
307307
s2c_send, s2c_recv = anyio.create_memory_object_stream[SessionMessage | Exception](1)
308308
d: JSONRPCDispatcher[TransportContext] = JSONRPCDispatcher(s2c_recv, c2s_send)
309309
try:
310310
with pytest.raises(RuntimeError, match="before run"):
311-
await d.send_request("ping", None)
311+
await d.send_raw_request("ping", None)
312312
finally:
313313
for s in (c2s_send, c2s_recv, s2c_send, s2c_recv):
314314
s.close()
@@ -351,7 +351,7 @@ async def test_cancelled_notification_for_unknown_request_id_is_noop():
351351
with anyio.fail_after(5):
352352
await client.notify("notifications/cancelled", {"requestId": 999})
353353
# No effect; dispatcher remains healthy.
354-
assert await client.send_request("t", None) == {"echoed": "t", "params": {}}
354+
assert await client.send_raw_request("t", None) == {"echoed": "t", "params": {}}
355355
assert srec.notifications == [] # cancelled is fully consumed, never teed
356356

357357

@@ -451,7 +451,7 @@ async def test_cancel_outbound_after_write_stream_closed_is_swallowed():
451451

452452
async def caller() -> None:
453453
with caller_scope:
454-
await client.send_request("slow", None)
454+
await client.send_raw_request("slow", None)
455455
caller_done.set()
456456

457457
tg.start_soon(caller)

0 commit comments

Comments
 (0)