feat: sandboxed exports for consistent wasm envs#9519
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
1 issue found across 8 files
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/_cli/sandbox.py">
<violation number="1" location="marimo/_cli/sandbox.py:288">
P2: `python_version_override` can desynchronize runtime Python and persisted `requires-python` metadata. The sandbox may run with the override while the file is rewritten with the host interpreter version.</violation>
</file>
Architecture diagram
sequenceDiagram
participant CLI as CLI HTML WASM
participant Sandbox as Sandbox Manager
participant UV as uv sandbox
participant Pyodide as Pyodide Constraints
participant Server as Export Server
participant Pinning as Dependency Pinner
participant CDN as Marimo WASM CDN
Note over CLI,CDN: NEW: Sandboxed Export Flow with Pyodide Constraints
CLI->>CLI: Check MARIMO_HTML_WASM_SANDBOX_BOOTSTRAPPED env var
alt Not bootstrapped AND --execute flag set
CLI->>CLI: Set sandbox=True, python_version_override, extra_env
CLI->>Sandbox: run_in_sandbox(args, pyodide_constraints=True, python_version_override="3.12")
Sandbox->>UV: construct_uv_command(...)
Sandbox->>Pyodide: write_constraint_file()
Pyodide->>CDN: GET pyodide-lock.json (custom User-Agent)
alt CDN fetch succeeds
CDN-->>Pyodide: Lockfile data
Pyodide->>UV: Write constraints.txt
UV->>Sandbox: Set UV_CONSTRAINT env var
else CDN fetch fails
Pyodide-->>Sandbox: Return False (no constraints)
end
Note over Sandbox,UV: Re-runs with MARIMO_HTML_WASM_SANDBOX_BOOTSTRAPPED=1
else Already bootstrapped OR no --execute
Note over CLI,Server: Fall through to standard sandboxing or no sandbox
end
Note over Server,Pinning: Export phase (inside sandbox or not)
Server->>Pinning: pin_pep723_dependencies_for_wasm(code, path)
Pinning->>Pinning: Get installed packages from importlib.metadata
Pinning->>Pyodide: fetch_pyodide_package_versions()
alt Pyodide lockfile reachable
Pinning->>Pinning: Intersect installed with Pyodide packages
Note over Pinning: Only pin packages present in both
alt Non-Pyodide top-level deps found
Pinning->>CLI: Warning about missing browser packages
end
else Pyodide lockfile unreachable
Pinning->>Pinning: Pin all installed packages (degraded)
end
alt Bootstrapped env detected
Pinning->>Pinning: lock_kind = "resolved"
else
Pinning->>Pinning: lock_kind = "observed"
end
Pinning->>Pinning: with_pinned_dependencies(code, pins, lock_kind)
Note over Pinning: Rewrite PEP 723 block with exact versions
Pinning-->>Server: Return modified code
Server->>Server: Export as WASM HTML with pinned dependencies
Note over CDN: Optional offline override via MARIMO_PYODIDE_LOCK_FILE env var
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Pull request overview
This PR aims to make marimo export html-wasm --execute run in a more Pyodide-consistent environment by bootstrapping execution into a uv sandbox constrained by the Pyodide lockfile, and by rewriting embedded PEP 723 dependency metadata to include pinned versions.
Changes:
- Add Pyodide lockfile fetching + constraints-file generation, and optionally apply it via
UV_CONSTRAINTwhen running in a sandbox. - Add PEP 723 dependency pinning logic for WASM exports (including a
lock_kindannotation and warnings for non-Pyodide deps). - Extend CLI sandbox utilities to support an explicit Python version override, with new tests for command construction and lockfile/metadata rewriting.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/_utils/test_inline_script_metadata.py | Adds tests for PEP 723 dependency pinning/rewriting behavior. |
| tests/_cli/test_sandbox.py | Adds tests ensuring python_version_override wins over script metadata. |
| tests/_cli/test_pyodide_constraints.py | Adds unit tests for lockfile fetching, normalization, and constraints writing. |
| marimo/_utils/inline_script_metadata.py | Implements dependency pinning utilities and WASM-specific PEP 723 pin/warn flow. |
| marimo/_server/export/init.py | Uses the new pinning function when embedding code in WASM HTML exports. |
| marimo/_cli/sandbox.py | Adds sandbox support for python version override + optional Pyodide constraints. |
| marimo/_cli/export/pyodide_constraints.py | Introduces lockfile fetching and constraints file generation. |
| marimo/_cli/export/commands.py | Bootstraps html-wasm --execute into a constrained sandbox with a re-entry guard. |
| def pin_pep723_dependencies_for_wasm(code: str, path: MarimoPath) -> str: | ||
| """Pin a notebook's PEP 723 deps for embedding in a WASM HTML export. | ||
|
|
||
| Snapshots the running interpreter's package versions, intersects with | ||
| the Pyodide lockfile (when reachable) so we never embed a pin Pyodide |
| LOGGER = _loggers.marimo_logger() | ||
|
|
||
| # Pyodide version matching frontend/package.json — update together. | ||
| PYODIDE_VERSION = "0.27.7" |
There was a problem hiding this comment.
thoughts on keeping this file in _pyodide/?
There was a problem hiding this comment.
or at least the constants
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
📝 Summary
This PR attempts to match the pyodide environment for wasm exports by starting a sandbox environment with pyodide constraints.
As a rule, there is graceful fallback, and in the minimal case (no uv), marimo will continue to export.