fix(table): export menu works for plain-Python data without pandas/polars/pyarrow#9246
Merged
kirangadhave merged 4 commits intomainfrom Apr 17, 2026
Merged
fix(table): export menu works for plain-Python data without pandas/polars/pyarrow#9246kirangadhave merged 4 commits intomainfrom
pandas/polars/pyarrow#9246kirangadhave merged 4 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
for more information, see https://pre-commit.ci
Contributor
There was a problem hiding this comment.
Pull request overview
Fixes mo.ui.table export behavior when the table is backed by plain-Python data (dict / list[dict]) and no dataframe libraries are installed, by ensuring the Export UI is available and providing a structured “missing dependency” flow for Parquet.
Changes:
- Remove dependency-gated download support for
DefaultTableManagerand implement CSV export via Python stdlib (csv). - Extend the download RPC contract to return structured
error/missing_packagesfor unsupported formats (notably Parquet without deps), and surface this in the Export UI via a new mode-aware prompt. - Add/adjust backend and frontend tests covering the new behaviors.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
marimo/_plugins/ui/_impl/tables/default_table.py |
Removes dep-based download gating; implements stdlib CSV export and CSV cell serialization helper. |
marimo/_plugins/ui/_impl/table.py |
Extends download response shape; adds Parquet missing-deps short-circuit for tables. |
frontend/src/components/data-table/schemas.ts |
Updates RPC schema typings/output to include error and missing_packages. |
frontend/src/components/data-table/export-actions.tsx |
Handles missing-package download responses by showing a toast with an install prompt + retry. |
frontend/src/components/datasources/missing-package-prompt.tsx |
New reusable mode-aware missing-package UI (hides install option in read mode). |
frontend/src/core/mode.ts |
Adds useInstallAllowed() helper based on current app mode. |
tests/_plugins/ui/_impl/test_table.py |
Adds backend test asserting Parquet-without-deps returns structured missing-packages response. |
tests/_plugins/ui/_impl/tables/test_default_table.py |
Adds/updates tests for supports_download() and CSV output for plain-Python default tables. |
frontend/src/components/datasources/__tests__/missing-package-prompt.test.tsx |
New tests validating prompt copy/button behavior in edit vs read mode. |
21ea42e to
4579540
Compare
mscolnick
reviewed
Apr 17, 2026
| if args.format == "parquet": | ||
| has_polars = DependencyManager.polars.has() | ||
| has_pandas = DependencyManager.pandas.has() | ||
| has_pyarrow = DependencyManager.pyarrow.has() |
Contributor
There was a problem hiding this comment.
this may do more work than required (has() would import things). but its not a common path so don't need to optimize
mscolnick
approved these changes
Apr 17, 2026
|
🚀 Development release published. You may be able to view the changes at https://marimo.app?v=0.23.2-dev50 |
5 tasks
akshayka
added a commit
that referenced
this pull request
Apr 21, 2026
#9246 moved DefaultTableManager.to_csv_str to the stdlib csv module, which emits column name "value" for single-column data. Previously the fallback went through pandas (via _as_table_manager), so a list of ints became a DataFrame with integer column 0. The test's expected_df still used {0: [1, 2, 3]}; update it to {"value": [1, 2, 3]} to match. The post-search assertion was already {"value": [2]}, so no change there.
akshayka
added a commit
that referenced
this pull request
Apr 21, 2026
Unblocks the test_be CI after #9305. Each of these five failures has an independent root cause — grouping them since the fixes are small and share the same goal. - **`test_download_as[df0]`** — the Parquet short-circuit in `_download_as` required `polars OR (pandas AND pyarrow)`, rejecting pyarrow-alone environments even though pyarrow can write Parquet natively. Relax to `polars OR pyarrow`. The `_parquet_without_libs_reports_missing_packages` and `_parquet_with_pandas_only_prompts_pyarrow` regression tests still pass. - **`test_get_data_url_no_deps`** — #9246 rewrote `DefaultTableManager.to_csv_str` to use the stdlib `csv` module, so `_to_chart_data_url` now returns CSV instead of falling through to JSON. Update the test expectation. - **`test_get_data_url_values`** — same #9246 change: stdlib CSV emits column name `"value"` for single-column data, where the old pandas fallback produced integer column `0`. Update the first `expected_df` to `{"value": [1, 2, 3]}`. (Landed as a separate commit after I found it on a broader sweep with the `test-optional` group.) - **`test_serve_static_allowed_files`** — `serve_static` returned `FileResponse` without checking existence, so Starlette raised `RuntimeError` at request time when the file was missing. CI copies `index.html` and `favicon.ico` into `_static/` but not `manifest.json`, which is how this surfaced. Add an `is_file()` guard that 404s. The test passed locally only because `_static/` doesn't exist on dev machines and `PathValidator` rejected upstream. - **`test_get_completion_options_bails_out_when_timeout_elapsed`** — #9247 switched the production code to `time.monotonic` but the test still mocked `time.time`, so the budget never expired and all completions got types set. Mock `time.monotonic`. ## Test plan - [x] Ran all four originally-failing tests; they pass. - [x] Ran the affected modules (`test_table.py`, `test_assets.py`, `test_complete.py`) with the `test` group — no new failures; pre-existing `test_index*` failures need a built `_static/` which CI provides. - [x] Ran the same modules with `test-optional` (pandas + polars + pyarrow + altair) — uncovered and fixed `test_get_data_url_values`. - [x] Confirmed the Parquet "missing packages" prompts still fire correctly under pandas-only and no-lib environments. - [ ] Let CI verify Linux/Windows.
jacobcbeaudin
pushed a commit
to jacobcbeaudin/marimo
that referenced
this pull request
Apr 21, 2026
…o-team#9306) Unblocks the test_be CI after marimo-team#9305. Each of these five failures has an independent root cause — grouping them since the fixes are small and share the same goal. - **`test_download_as[df0]`** — the Parquet short-circuit in `_download_as` required `polars OR (pandas AND pyarrow)`, rejecting pyarrow-alone environments even though pyarrow can write Parquet natively. Relax to `polars OR pyarrow`. The `_parquet_without_libs_reports_missing_packages` and `_parquet_with_pandas_only_prompts_pyarrow` regression tests still pass. - **`test_get_data_url_no_deps`** — marimo-team#9246 rewrote `DefaultTableManager.to_csv_str` to use the stdlib `csv` module, so `_to_chart_data_url` now returns CSV instead of falling through to JSON. Update the test expectation. - **`test_get_data_url_values`** — same marimo-team#9246 change: stdlib CSV emits column name `"value"` for single-column data, where the old pandas fallback produced integer column `0`. Update the first `expected_df` to `{"value": [1, 2, 3]}`. (Landed as a separate commit after I found it on a broader sweep with the `test-optional` group.) - **`test_serve_static_allowed_files`** — `serve_static` returned `FileResponse` without checking existence, so Starlette raised `RuntimeError` at request time when the file was missing. CI copies `index.html` and `favicon.ico` into `_static/` but not `manifest.json`, which is how this surfaced. Add an `is_file()` guard that 404s. The test passed locally only because `_static/` doesn't exist on dev machines and `PathValidator` rejected upstream. - **`test_get_completion_options_bails_out_when_timeout_elapsed`** — marimo-team#9247 switched the production code to `time.monotonic` but the test still mocked `time.time`, so the budget never expired and all completions got types set. Mock `time.monotonic`. ## Test plan - [x] Ran all four originally-failing tests; they pass. - [x] Ran the affected modules (`test_table.py`, `test_assets.py`, `test_complete.py`) with the `test` group — no new failures; pre-existing `test_index*` failures need a built `_static/` which CI provides. - [x] Ran the same modules with `test-optional` (pandas + polars + pyarrow + altair) — uncovered and fixed `test_get_data_url_values`. - [x] Confirmed the Parquet "missing packages" prompts still fire correctly under pandas-only and no-lib environments. - [ ] Let CI verify Linux/Windows.
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.
When using python
dictorlist(dict)withmo.ui.tablewithout any dataframe library installed, theExportbutton was hidden.DefaultTableManager.supports_download()checked for dataframe libraries and returnedFalse. We now always show the download button. We can supportcsv,json,mdwith stdlib in python. If user selectsparquet, we show a toast for missing packages and an install button.The
MissingPackagePromptis mode-aware. In run mode where users cannot install packages it shows aParquet export isn't available in this notebookwithout an install button.Notes
The DefaultTableManager always uses
csvlib even if pandas/polars is installed. Exporting actual dataframe objects is not affected.We suggest
polarsinstead ofpyarrowbecause we already have apolarscode path which is well testedScreen.Recording.2026-04-17.at.10.27.37.AM.mov