-
Notifications
You must be signed in to change notification settings - Fork 902
fix(python): add timeout parameter to generated RPC methods #580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| """Tests for timeout parameter on generated RPC methods.""" | ||
| from unittest.mock import AsyncMock | ||
|
|
||
| import pytest | ||
|
|
||
| from copilot.generated.rpc import ( | ||
| FleetApi, | ||
| Mode, | ||
| ModeApi, | ||
| SessionFleetStartParams, | ||
| SessionModeSetParams, | ||
| ) | ||
|
|
||
|
|
||
| class TestRpcTimeout: | ||
| @pytest.mark.asyncio | ||
| async def test_default_timeout_not_forwarded(self): | ||
| client = AsyncMock() | ||
| client.request = AsyncMock(return_value={"started": True}) | ||
| api = FleetApi(client, "sess-1") | ||
|
|
||
| await api.start(SessionFleetStartParams(prompt="go")) | ||
|
|
||
| client.request.assert_called_once() | ||
| _, kwargs = client.request.call_args | ||
| assert "timeout" not in kwargs | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_custom_timeout_forwarded(self): | ||
| client = AsyncMock() | ||
| client.request = AsyncMock(return_value={"started": True}) | ||
| api = FleetApi(client, "sess-1") | ||
|
|
||
| await api.start(SessionFleetStartParams(prompt="go"), timeout=600.0) | ||
|
|
||
| _, kwargs = client.request.call_args | ||
| assert kwargs["timeout"] == 600.0 | ||
|
|
||
| @pytest.mark.asyncio | ||
| async def test_timeout_on_other_methods(self): | ||
| client = AsyncMock() | ||
| client.request = AsyncMock(return_value={"mode": "plan"}) | ||
| api = ModeApi(client, "sess-1") | ||
|
|
||
| await api.set(SessionModeSetParams(mode=Mode.PLAN), timeout=120.0) | ||
|
|
||
| _, kwargs = client.request.call_args | ||
| assert kwargs["timeout"] == 120.0 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -169,11 +169,20 @@ AUTO-GENERATED FILE - DO NOT EDIT | |
| Generated from: api.schema.json | ||
| """ | ||
|
|
||
| from typing import TYPE_CHECKING | ||
| from typing import TYPE_CHECKING, Optional | ||
|
|
||
| if TYPE_CHECKING: | ||
| from ..jsonrpc import JsonRpcClient | ||
|
|
||
| `); | ||
|
|
||
| lines.push(` | ||
| def _timeout_kwargs(timeout: Optional[float]) -> dict: | ||
| """Build keyword arguments for optional timeout forwarding.""" | ||
| if timeout is not None: | ||
| return {"timeout": timeout} | ||
| return {} | ||
|
|
||
| `); | ||
| lines.push(typesCode); | ||
|
Comment on lines
+179
to
187
|
||
| lines.push(``); | ||
|
|
@@ -255,10 +264,10 @@ function emitMethod(lines: string[], name: string, method: RpcMethod, isSession: | |
| const hasParams = isSession ? nonSessionParams.length > 0 : Object.keys(paramProps).length > 0; | ||
| const paramsType = toPascalCase(method.rpcMethod) + "Params"; | ||
|
|
||
| // Build signature with typed params | ||
| // Build signature with typed params + optional timeout | ||
| const sig = hasParams | ||
| ? ` async def ${methodName}(self, params: ${paramsType}) -> ${resultType}:` | ||
| : ` async def ${methodName}(self) -> ${resultType}:`; | ||
| ? ` async def ${methodName}(self, params: ${paramsType}, *, timeout: Optional[float] = None) -> ${resultType}:` | ||
| : ` async def ${methodName}(self, *, timeout: Optional[float] = None) -> ${resultType}:`; | ||
|
|
||
| lines.push(sig); | ||
|
|
||
|
|
@@ -267,16 +276,16 @@ function emitMethod(lines: string[], name: string, method: RpcMethod, isSession: | |
| if (hasParams) { | ||
| lines.push(` params_dict = {k: v for k, v in params.to_dict().items() if v is not None}`); | ||
| lines.push(` params_dict["sessionId"] = self._session_id`); | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", params_dict))`); | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", params_dict, **_timeout_kwargs(timeout)))`); | ||
| } else { | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", {"sessionId": self._session_id}))`); | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", {"sessionId": self._session_id}, **_timeout_kwargs(timeout)))`); | ||
| } | ||
| } else { | ||
| if (hasParams) { | ||
| lines.push(` params_dict = {k: v for k, v in params.to_dict().items() if v is not None}`); | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", params_dict))`); | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", params_dict, **_timeout_kwargs(timeout)))`); | ||
| } else { | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", {}))`); | ||
| lines.push(` return ${resultType}.from_dict(await self._client.request("${method.rpcMethod}", {}, **_timeout_kwargs(timeout)))`); | ||
| } | ||
| } | ||
| lines.push(``); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Current tests only cover session-scoped methods that have
params. Since the codegen change also touches (1) server-scoped APIs and (2) methods with noparams(e.g.,ModelsApi.list()), it would be good to add at least one test covering a no-params method and/or a server-scoped method to ensuretimeoutforwarding works in those branches too.