fix: msgspec encoding for starlette user#9406
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
Fixes IPC msgspec serialization failures when Starlette authentication middleware attaches a BaseUser (e.g., SimpleUser) to the request scope, which previously broke sandbox home mode.
Changes:
- Normalize
request.scope["user"]andrequest.scope["meta"]into IPC-encodable dicts when buildingHTTPRequest. - Introduce an
Encodabletype alias to tighten and document which values are expected to round-trip across msgspec IPC boundaries. - Add regression tests covering Starlette user normalization and msgspec msgpack encoding.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/_runtime/test_requests.py | Adds regression tests for Starlette user normalization and IPC msgpack encoding safety. |
| marimo/_types/encodable.py | Introduces an Encodable type alias for msgspec IPC-safe payload types. |
| marimo/_runtime/commands.py | Normalizes user/meta in HTTPRequest.from_request and tightens typing for IPC-serialized structures. |
| marimo/_messaging/context.py | Adjusts typing around HTTPRequest.url access after tightening URL field types. |
| marimo/_code_mode/_context.py | Updates typing/casts for request.meta access after tightening meta field types. |
| # Convert headers to list of tuples as expected by Starlette | ||
| raw_headers = [(k.lower(), v) for k, v in (headers or {}).items()] | ||
| scope = { | ||
| scope: dict[str, Any] = { | ||
| "type": "http", | ||
| "method": "GET", | ||
| "headers": dict(raw_headers), |
There was a problem hiding this comment.
The comment says headers are converted to a list of tuples "as expected by Starlette", but the scope ultimately stores a dict and the overridden headers property builds Headers(headers=...) from that dict. Please either update the comment to match the mock’s behavior, or store raw headers in the scope (e.g., bytes tuples) to more closely mirror Starlette’s ASGI scope shape.
There was a problem hiding this comment.
No issues found across 5 files
Architecture diagram
sequenceDiagram
participant Client as "Web Client"
participant Server as "Marimo Server (Starlette)"
participant Auth as "Auth Middleware"
participant CMD as "HTTPRequest (commands.py)"
participant IPC as "msgspec Encoder"
participant Kernel as "Marimo Kernel"
Note over Client,Kernel: Request Execution Flow (e.g., Sandbox Home)
Client->>Server: HTTP Request (GET /api/kernel/execute)
Server->>Auth: Process Request Scope
Auth-->>Server: Injects Starlette SimpleUser into scope
Server->>CMD: HTTPRequest.from_request(request)
rect rgb(240,240,240)
Note over CMD: NEW: Normalization Boundary
CMD->>CMD: NEW: _user_to_dict(user)
Note right of CMD: Converts Starlette object<br/>to Encodable dict
CMD->>CMD: NEW: _meta_to_dict(meta)
end
CMD-->>Server: Return serializable HTTPRequest
Server->>IPC: CHANGED: msgspec.encode(request)
alt Encoding Success
IPC-->>Server: Binary Payload
Server->>Kernel: Send Request Data via IPC
Kernel->>Kernel: Execute User Code (mo.app_meta())
else Encoding Failure (Fixed)
Note over IPC: Previously failed on<br/>Starlette User objects
IPC-->>Server: Raise TypeError
end
Note over Kernel: Code Execution Context
Kernel->>Kernel: CHANGED: cast types for server_url/auth_token
Kernel-->>Client: Result / Screenshot Data
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="marimo/_runtime/commands.py">
<violation number="1" location="marimo/_runtime/commands.py:132">
P2: Widening `user` from `dict[str, Encodable]` to `Encodable` weakens the type contract while `_user_to_dict` (the sole producer) always returns a dict. If a starlette user object is reaching this field un-converted, the fix should ensure `_user_to_dict` is called on that code path rather than loosening the type — an un-converted starlette object still won't be msgspec-encodable even under the `Encodable` (`Any`) annotation.
(Based on your team's feedback about requiring strict typing over Any.) [FEEDBACK_USED]</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
|
🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.4-dev15 |
📝 Summary
This PR fixes a bug introduced in 0.23.3 where msgspec encoding fails on a starlette object, breaking
sandbox homemode. This PR also adds typing to help mitigate these issues in the future.