Bound file previews and offer download for unpreviewable files#10277
Open
kirangadhave wants to merge 4 commits into
Open
Bound file previews and offer download for unpreviewable files#10277kirangadhave wants to merge 4 commits into
kirangadhave wants to merge 4 commits into
Conversation
Request file previews with a 10 MiB ceiling and render metadata-only states for oversized or unsupported files instead of mounting an editor or dumping base64 text.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves file preview behavior in marimo’s file explorer by bounding preview reads (to avoid sending large/binary payloads through JSON), adding file-size metadata, and offering a download-first UX when previewing isn’t feasible.
Changes:
- Backend: Add
FileInfo.size, introduceFileSystem.get_info()for metadata-only operations, and support bounded reads viamaxBytes+isTooLargein file-details responses. - Frontend: Request bounded previews (10 MiB), classify responses by render mode (text/csv/media/unsupported), and render metadata + download action for oversized/unsupported files.
- Tests/OpenAPI: Extend API schema and add coverage across server, Pyodide bridge, and frontend rendering behavior.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/_server/files/test_os_file_system.py | Adds tests for get_info() size reporting and bounded get_details() behavior. |
| tests/_server/api/endpoints/test_file_explorer.py | Verifies maxBytes behavior (bounded vs unbounded) and negative-limit rejection. |
| tests/_pyodide/test_pyodide_session.py | Adds tests ensuring Pyodide bridge honors bounded vs unbounded file_details. |
| packages/openapi/src/api.ts | Updates generated TS types for maxBytes, isTooLarge, and FileInfo.size. |
| packages/openapi/api.yaml | Updates OpenAPI schema for maxBytes, isTooLarge, and size. |
| marimo/_server/models/files.py | Adds size, max_bytes, and is_too_large to models. |
| marimo/_server/files/os_file_system.py | Implements metadata-only get_info() and bounded read logic in get_details(). |
| marimo/_server/files/file_system.py | Adds get_info() abstraction and max_bytes parameter to get_details(). |
| marimo/_server/api/endpoints/file_explorer.py | Adds maxBytes validation and switches validation calls to get_info(). |
| marimo/_pyodide/pyodide_session.py | Plumbs max_bytes through the Pyodide bridge. |
| frontend/src/core/network/types.ts | Updates sendFileDetails signature to accept FileDetailsRequest. |
| frontend/src/components/editor/file-tree/file-viewer.tsx | Requests bounded previews and renders metadata/download for oversized/unsupported files. |
| frontend/src/components/editor/file-tree/file-render-mode.ts | Adds central render-mode classification helper. |
| frontend/src/components/editor/file-tree/file-preview-metadata.tsx | New metadata-only preview UI with optional download action. |
| frontend/src/components/editor/file-tree/tests/file-viewer.test.tsx | Adds UI tests for bounded previews and unsupported/oversized behavior. |
| frontend/src/components/editor/file-tree/tests/file-render-mode.test.ts | Adds unit tests for render-mode mapping. |
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 16 files
Architecture diagram
sequenceDiagram
participant Client as FileViewer (Frontend)
participant API as Frontend API Client
participant Server as file_details Endpoint
participant FS as OSFileSystem
participant Disk as File on Disk
participant Download as /download Endpoint
Note over Client,Download: NEW: Bounded file preview + download fallback
Client->>API: sendFileDetails({path, maxBytes: 10 MB})
API->>Server: POST /api/files/file_details<br/>with maxBytes
Server->>FS: get_details(path, max_bytes=10 MB)
Note over FS,Disk: NEW: Separate metadata path for other operations
FS->>Disk: stat(path) → size, mime_type
Disk-->>FS: file info
alt size > maxBytes (or file content exceeds limit after reading)
FS->>FS: is_too_large = True, contents = None
else size <= maxBytes
Note over FS: Reads at most maxBytes+1 bytes
FS->>Disk: open and read bounded content
Disk-->>FS: raw bytes (≤ maxBytes+1)
FS->>FS: decode as text or base64-encode binary
end
FS-->>Server: FileDetailsResponse<br/>(is_too_large, contents, mime_type, ...)
Server-->>API: HTTP 200
API-->>Client: FileDetailsResponse
Client->>Client: getFileRenderMode(mime_type, isBase64)
alt is_too_large OR renderMode === "unsupported"
Client->>Client: Show FilePreviewMetadata<br/>(path, type, size, message)
Note over Client,Download: Download button triggers streaming GET
Client->>Download: GET /download?path=...
Download-->>Client: file stream
else text / csv / media
Client->>Client: Render FileContentRenderer<br/>(editor or media viewer)
end
Note over Server,FS: CHANGED: delete/copy/move/update endpoints now use<br/>get_info() instead of get_details() to avoid content reads
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
Contributor
Coverage Report for ./frontend
File Coverage
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Treat empty contents as valid so edits to an initially empty text file survive file switches, and use a nullish fallback when restoring a saved draft so a cleared file is not overwritten by stale server contents. Correct the max_bytes docstring to match its passthrough behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
📝 Summary
Open every selected file in FileViewer while preventing oversized files from being fully read, base64-encoded, and shipped through JSON.
The
/api/files/file_detailsendpoint bounds a read only when the caller passesmaxBytes, so the file preview stays capped at 10 MiB while every other consumer (AI attachments, ACP reads, vimrc) reads in full as before. Metadata lookup is split from content retrieval, and reads stop at the limit without opening oversized files. The frontend classifies each response into text, CSV, media, or unsupported, and renders file metadata with a download action instead of mounting an empty editor or dumping base64 for oversized or unsupported files. Native downloads use the streaming GET endpoint; the explicit WASM download stays full-content.Closes MO-6275