Skip to content

fix(python): add timeout parameter to generated RPC methods#580

Closed
Rasaboun wants to merge 1 commit intogithub:mainfrom
Rasaboun:fix/python-rpc-timeout-param
Closed

fix(python): add timeout parameter to generated RPC methods#580
Rasaboun wants to merge 1 commit intogithub:mainfrom
Rasaboun:fix/python-rpc-timeout-param

Conversation

@Rasaboun
Copy link

Summary

  • Modifies scripts/codegen/python.ts so every generated RPC method gets an optional timeout keyword argument forwarded to JsonRpcClient.request()
  • Adds a _timeout_kwargs helper in the generated preamble to conditionally build the **kwargs
  • Regenerates python/copilot/generated/rpc.py (not hand-edited)
  • Adds unit tests verifying timeout forwarding and default behavior

Usage

# Before (workaround via private API):
result = await session._client.request("session.fleet.start", params, timeout=600.0)

# After (typed API):
result = await session.rpc.fleet.start(params, timeout=600.0)

Motivation

FleetApi.start() inherits a hardcoded 30s timeout from JsonRpcClient.request(), but session.fleet.start is a blocking RPC that only returns once the fleet completes — routinely >30s. Users are forced to bypass the typed API.

Fixes #539

Note on fleet.start semantics

session.fleet.start blocks until the entire fleet completes and always returns started=True, making the return value meaningless. Consider making fleet.start return immediately once the fleet is deployed, and let callers wait via SESSION_IDLE events. This would also eliminate the need for large timeouts.

Test plan

  • npm run generate:python succeeds
  • rpc.py diff: timeout param on every method, _timeout_kwargs helper at top
  • Unit tests pass (pytest test_rpc_timeout.py)
  • ruff check . clean

Copilot AI review requested due to automatic review settings February 25, 2026 10:58
@Rasaboun Rasaboun requested a review from a team as a code owner February 25, 2026 10:58
@Rasaboun Rasaboun force-pushed the fix/python-rpc-timeout-param branch 2 times, most recently from 371af5c to 5af8c3d Compare February 25, 2026 11:00
Every generated async RPC method now accepts an optional `timeout`
keyword argument that is forwarded to `JsonRpcClient.request()`.
This lets callers override the default 30s timeout for long-running
RPCs like `session.fleet.start` without bypassing the typed API.

Fixes github#539
@Rasaboun Rasaboun force-pushed the fix/python-rpc-timeout-param branch from 5af8c3d to 7a0753b Compare February 25, 2026 11:02
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Python SDK’s generated typed RPC surface so callers can override the default JSON-RPC request timeout (notably for long-running blocking RPCs like session.fleet.start) while keeping the default behavior unchanged when no timeout is provided.

Changes:

  • Extend Python RPC codegen to add a keyword-only timeout: Optional[float] = None parameter to every generated RPC method and forward it to JsonRpcClient.request().
  • Add a generated _timeout_kwargs() helper to conditionally include timeout only when provided.
  • Add Python unit tests covering default vs. custom timeout forwarding.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
scripts/codegen/python.ts Updates the Python RPC generator to add timeout to generated method signatures and forward it via _timeout_kwargs().
python/copilot/generated/rpc.py Regenerated output reflecting the new timeout parameter and forwarding behavior across RPC wrappers.
python/test_rpc_timeout.py Adds unit tests to validate that timeout is not forwarded by default and is forwarded when explicitly provided.

Comment on lines +179 to 187
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);
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The generated _timeout_kwargs helper is emitted before the quicktype-generated import block (typesCode), which results in rpc.py defining a function in between import sections (and before some imports). Consider emitting the helper after typesCode (or at least after all imports) so the generated module keeps imports at the top and won’t trip tools that enforce import ordering if copilot/generated is ever linted/type-checked.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +48
@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
Copy link

Copilot AI Feb 25, 2026

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 no params (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 ensure timeout forwarding works in those branches too.

Copilot uses AI. Check for mistakes.
@Rasaboun Rasaboun closed this Feb 25, 2026
@Rasaboun Rasaboun deleted the fix/python-rpc-timeout-param branch February 25, 2026 11:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

"FleetApi.start()" uses default 30s timeout but "fleet.start" RPC blocks until fleet completes

2 participants