Send a JSON-RPC request and wait for the response. Args: method: Method name params: Optional parameters timeout: Optional request timeout in seconds. If None (default), waits indefinitely for the server to respond. on
(
self,
method: str,
params: dict | None = None,
timeout: float | None = None,
*,
on_response_inline: Callable[[Any], None] | None = None,
)
| 135 | self._stderr_thread.join(timeout=1.0) |
| 136 | |
| 137 | async def request( |
| 138 | self, |
| 139 | method: str, |
| 140 | params: dict | None = None, |
| 141 | timeout: float | None = None, |
| 142 | *, |
| 143 | on_response_inline: Callable[[Any], None] | None = None, |
| 144 | ) -> Any: |
| 145 | """ |
| 146 | Send a JSON-RPC request and wait for the response. |
| 147 | |
| 148 | Args: |
| 149 | method: Method name |
| 150 | params: Optional parameters |
| 151 | timeout: Optional request timeout in seconds. If None (default), |
| 152 | waits indefinitely for the server to respond. |
| 153 | on_response_inline: Optional synchronous callback invoked from the |
| 154 | reader thread the instant a successful response is parsed, |
| 155 | before the awaiter's future is scheduled on the event loop. |
| 156 | Use this to perform state mutations (for example, registering |
| 157 | a server-assigned session id) that must be visible before any |
| 158 | subsequent notification on the same connection is dispatched. |
| 159 | The callback receives the parsed JSON result. If the callback |
| 160 | raises, the exception is propagated to the awaiter. |
| 161 | |
| 162 | Returns: |
| 163 | The result from the response |
| 164 | |
| 165 | Raises: |
| 166 | JsonRpcError: If the server returns an error |
| 167 | asyncio.TimeoutError: If the request times out (only when timeout is set) |
| 168 | """ |
| 169 | request_start = time.perf_counter() |
| 170 | request_id = str(uuid.uuid4()) |
| 171 | |
| 172 | # Use the stored loop to ensure consistency with the reader thread |
| 173 | if not self._loop: |
| 174 | raise RuntimeError("Client not started. Call start() first.") |
| 175 | |
| 176 | future = self._loop.create_future() |
| 177 | with self._pending_lock: |
| 178 | self.pending_requests[request_id] = future |
| 179 | if on_response_inline is not None: |
| 180 | self._pending_inline_callbacks[request_id] = on_response_inline |
| 181 | |
| 182 | message = { |
| 183 | "jsonrpc": "2.0", |
| 184 | "id": request_id, |
| 185 | "method": method, |
| 186 | "params": params or {}, |
| 187 | } |
| 188 | |
| 189 | try: |
| 190 | await self._send_message(message) |
| 191 | if timeout is not None: |
| 192 | result = await asyncio.wait_for(future, timeout=timeout) |
| 193 | else: |
| 194 | result = await future |