Skip to content

feat: Add PWA file handler for CSV/XLS/Parquet uploads#36191

Merged
betodealmeida merged 8 commits into
masterfrom
file-handler
Feb 2, 2026
Merged

feat: Add PWA file handler for CSV/XLS/Parquet uploads#36191
betodealmeida merged 8 commits into
masterfrom
file-handler

Conversation

@betodealmeida
Copy link
Copy Markdown
Member

@betodealmeida betodealmeida commented Nov 19, 2025

User description

SUMMARY

Make Superset a progressive web app (PWA) by adding a manifest file.

Also add functionality to allow CSV/XLS/Parquet file uploads from the desktop.

BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF

Screenshot 2025-12-16 at 12 12 50 PM Screenshot 2025-12-16 at 12 13 00 PM Screenshot 2025-12-16 at 12 13 37 PM Screenshot 2025-12-16 at 12 13 46 PM Screenshot 2025-12-16 at 12 14 08 PM Screenshot 2025-12-16 at 12 14 13 PM Screenshot 2025-12-16 at 12 14 17 PM

TESTING INSTRUCTIONS

ADDITIONAL INFORMATION

  • Has associated issue:
  • Required feature flags:
  • Changes UI
  • Includes DB Migration (follow approval process in SIP-59)
    • Migration is atomic, supports rollback & is backwards-compatible
    • Confirm DB migration upgrade and downgrade tested
    • Runtime estimates and downtime expectations provided
  • Introduces new feature or API
  • Removes existing feature or API

CodeAnt-AI Description

Add PWA install and desktop file-handler for CSV/Excel/Parquet

What Changed

  • Superset can be installed as a Progressive Web App (PWA): a manifest and service worker are registered so users can install the app and see install screenshots and icons.
  • Desktop file handling: opening CSV, .xls/.xlsx, or Parquet files from the OS launches Superset and opens the upload modal populated with the selected file so users can import directly.
  • Unsupported or failed file launches show a clear error toast and redirect users back to the welcome page; closing the upload modal also returns users to the welcome page.
  • Browser support and scope: service worker is emitted at the root, and responses include a header allowing the service worker to control the root scope to enable file-handler registration.
  • Automated tests added to verify file-handler behaviors (CSV/Excel/Parquet handling, error cases, redirects, and loading state).

Impact

✅ Installable desktop app via browser PWA prompt
✅ Open CSV/Excel/Parquet files from desktop into Superset upload flow
✅ Clearer errors and consistent redirect when file handling fails or is unsupported

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

@github-actions github-actions Bot added the api Related to the REST API label Nov 19, 2025
@betodealmeida betodealmeida changed the title feat: file handler for CSV/XSL feat: Add PWA file handler for CSV/XLS/Parquet uploads Nov 20, 2025
@betodealmeida betodealmeida force-pushed the file-handler branch 2 times, most recently from d8540f3 to 44e08de Compare December 16, 2025 15:09
@betodealmeida betodealmeida marked this pull request as ready for review December 16, 2025 17:16
@dosubot dosubot Bot added change:frontend Requires changing the frontend data:csv Related to import/export of CSVs labels Dec 16, 2025
@codeant-ai-for-open-source
Copy link
Copy Markdown
Contributor

CodeAnt AI is reviewing your PR.

@codeant-ai-for-open-source codeant-ai-for-open-source Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Dec 16, 2025
Comment thread superset-frontend/src/service-worker.ts Outdated
Comment thread superset-frontend/webpack.config.js Outdated
Comment thread superset/initialization/__init__.py Outdated
Comment thread superset/static/service-worker.js Outdated
Comment thread superset/templates/superset/spa.html Outdated
@codeant-ai-for-open-source
Copy link
Copy Markdown
Contributor

CodeAnt AI finished reviewing your PR.

@codeant-ai-for-open-source
Copy link
Copy Markdown
Contributor

💡 Enhance Your PR Reviews

We noticed that 3 feature(s) are not configured for this repository. Enabling these features can help improve your code quality and workflow:

🚦 Quality Gates

Status: Quality Gates are not enabled at the organization level
Learn more about Quality Gates

🎫 Jira Ticket Compliance

Status: Jira credentials file not found. Please configure Jira integration in your settings
Learn more about Jira Integration

⚙️ Custom Rules

Status: No custom rules configured. Add rules via organization settings or .codeant/review.json in your repository
Learn more about Custom Rules


Want to enable these features? Contact your organization admin or check our documentation for setup instructions.

@github-actions github-actions Bot removed plugins dependencies:npm github_actions Pull requests that update GitHub Actions code packages labels Dec 19, 2025
@rusackas
Copy link
Copy Markdown
Member

LGTM! Not sure if SVG is supported, but that'd be neat to not require more flavors of logo file.

Not sure if the the screenshot image can just link to the one(s) from the readme/docs, but the goal is to automate those so they're always current, in the near future.

Barring the above, rebase and go for it!

betodealmeida and others added 7 commits January 30, 2026 23:18
- Change route from /file-handler to /superset/file-handler to match Flask blueprint
- Add Service-Worker-Allowed header for root scope registration
- Add proper square icons (192x192, 512x512) for PWA install
- Add wide and narrow screenshots for PWA install prompt
- Update tests to use new route path

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add webworker lib reference for ServiceWorkerGlobalScope types
- Fix UploadFile type casting for fileListOverride
- Fix window type assertion with unknown intermediate cast
- Add required properties to error file handle mock

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The webworker lib reference was adding ServiceWorker types globally,
which conflicted with useBeforeUnload test. Use local type declarations
instead.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bito-code-review
Copy link
Copy Markdown
Contributor

bito-code-review Bot commented Jan 31, 2026

Code Review Agent Run #693f87

Actionable Suggestions - 0
Additional Suggestions - 3
  • superset-frontend/src/features/databases/UploadDataModel/index.tsx - 1
    • useEffect inefficiency · Line 530-544
      The useEffect depends on previewUploadedFile but only uses it conditionally, potentially causing unnecessary re-runs. Also, the loadFileMetadata promise lacks error handling.
      Code suggestion
       @@ -530,15 +530,18 @@
      -  useEffect(() => {
      -    if (fileListOverride?.length) {
      -      setFileList(
      -        fileListOverride.map(file => ({
      -          uid: file.name,
      -          name: file.name,
      -          originFileObj: file as UploadFile['originFileObj'],
      -          status: 'done' as const,
      -        })),
      -      );
      -      if (previewUploadedFile) {
      -        loadFileMetadata(fileListOverride[0]).then(r => r);
      -      }
      -    }
      -  }, [fileListOverride, previewUploadedFile]);
      +  useEffect(() => {
      +    if (fileListOverride?.length) {
      +      setFileList(
      +        fileListOverride.map(file => ({
      -          uid: file.name,
      -          name: file.name,
      -          originFileObj: file as UploadFile['originFileObj'],
      -          status: 'done' as const,
      -        })),
      -      );
      -      if (previewUploadedFile) {
      -        loadFileMetadata(fileListOverride[0]).catch(error => {
      -          addDangerToast(error.error || 'Error');
      -        });
      -      }
      -    } else {
      -      setFileList([]);
      -    }
      -  }, [fileListOverride, previewUploadedFile]);
  • superset/static/service-worker.js - 1
    • Misleading Comment · Line 20-20
      The comment claims 'PWA file handling support', but the service worker only handles install and activate events without any file-related logic like fetch interception.
  • superset/templates/superset/spa.html - 1
    • PWA Feature Compatibility · Line 33-35
      The PWA manifest includes file_handlers, an experimental feature with limited browser support (primarily Chromium-based browsers with flags enabled). This may not work for Firefox or Safari users, potentially leading to confusion if file handling is expected. Consider removing it for broader compatibility, or document the limitation.
Review Details
  • Files reviewed - 10 · Commit Range: c9c22e5..d1c1a7d
    • superset-frontend/src/features/databases/UploadDataModel/index.tsx
    • superset-frontend/src/pages/FileHandler/index.test.tsx
    • superset-frontend/src/pages/FileHandler/index.tsx
    • superset-frontend/src/service-worker.ts
    • superset-frontend/src/views/routes.tsx
    • superset-frontend/webpack.config.js
    • superset/initialization/__init__.py
    • superset/static/service-worker.js
    • superset/templates/superset/spa.html
    • superset/views/core.py
  • Files skipped - 1
    • superset-frontend/src/pwa-manifest.json - Reason: Filter setting
  • Tools
    • Whispers (Secret Scanner) - ✔︎ Successful
    • Detect-secrets (Secret Scanner) - ✔︎ Successful
    • Eslint (Linter) - ✔︎ Successful
    • MyPy (Static Code Analysis) - ✔︎ Successful
    • Astral Ruff (Static Code Analysis) - ✔︎ Successful

Bito Usage Guide

Commands

Type the following command in the pull request comment and save the comment.

  • /review - Manually triggers a full AI review.

  • /pause - Pauses automatic reviews on this pull request.

  • /resume - Resumes automatic reviews.

  • /resolve - Marks all Bito-posted review comments as resolved.

  • /abort - Cancels all in-progress reviews.

Refer to the documentation for additional commands.

Configuration

This repository uses Superset You can customize the agent settings here or contact your Bito workspace admin at evan@preset.io.

Documentation & Help

AI Code Review powered by Bito Logo

Comment on lines +76 to +88

let type: 'csv' | 'excel' | 'columnar' | null = null;
let extensions: string[] = [];

if (fileName.endsWith('.csv')) {
type = 'csv';
extensions = ['csv'];
} else if (fileName.endsWith('.xls') || fileName.endsWith('.xlsx')) {
type = 'excel';
extensions = ['xls', 'xlsx'];
} else if (fileName.endsWith('.parquet')) {
type = 'columnar';
extensions = ['parquet'];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggestion: The file type detection logic only recognizes .csv, .xls, .xlsx, and .parquet extensions, ignoring other formats that the existing upload modal already supports (notably .tsv for delimited text and .zip for columnar uploads). This causes a valid TSV or zipped columnar file that can be uploaded via the standard UI to be rejected as "Unsupported file type" when opened via the PWA file handler, leading to inconsistent behavior between entry points. [logic error]

Severity Level: Major ⚠️
- ❌ PWA file-launch rejects .tsv desktop uploads.
- ❌ PWA file-launch rejects zipped columnar (.zip) uploads.
- ⚠️ Inconsistent behavior vs UploadDataModal (upload UI).
- ⚠️ User-facing redirect to welcome page on open.
Suggested change
let type: 'csv' | 'excel' | 'columnar' | null = null;
let extensions: string[] = [];
if (fileName.endsWith('.csv')) {
type = 'csv';
extensions = ['csv'];
} else if (fileName.endsWith('.xls') || fileName.endsWith('.xlsx')) {
type = 'excel';
extensions = ['xls', 'xlsx'];
} else if (fileName.endsWith('.parquet')) {
type = 'columnar';
extensions = ['parquet'];
const extension = fileName.split('.').pop() || '';
let type: 'csv' | 'excel' | 'columnar' | null = null;
let extensions: string[] = [];
if (extension === 'csv' || extension === 'tsv') {
type = 'csv';
// Match the CSV behavior in UploadDataModal (supports csv and tsv)
extensions = ['csv', 'tsv'];
} else if (extension === 'xls' || extension === 'xlsx') {
type = 'excel';
extensions = ['xls', 'xlsx'];
} else if (extension === 'parquet' || extension === 'zip') {
// Columnar uploads also support zipped files
type = 'columnar';
extensions = ['parquet', 'zip'];
Steps of Reproduction ✅
1. Navigate to the PWA file-handler route (the component is mounted at
/superset/file-handler and defined in superset-frontend/src/pages/FileHandler/index.tsx).
The launchQueue consumer is registered in useEffect at lines 52-112, specifically
launchQueue.setConsumer(...) at lines 66-108.

2. From the desktop, open a supported-but-unchecked file type (example: a tab-separated
file test.tsv or a zipped columnar file test.zip). The OS will invoke the PWA and the
LaunchQueue consumer receives the file handle; the consumer callback receives launchParams
and executes the code starting at line 73 (const fileHandle = launchParams.files[0];).

3. FileHandler reads the File object via fileHandle.getFile() (line 74) and computes
fileName at line 75. The current logic checks
fileName.endsWith('.csv'/.xls/.xlsx/.parquet) (lines 80-88) and will not match '.tsv' or
'.zip'.

4. Because '.tsv' and '.zip' are not recognized, the else branch at lines 89-97 runs: a
danger toast is added with the message 'Unsupported file type...' and the user is
redirected to '/superset/welcome/' (lines 90-96). The upload modal is never opened.

5. Contrast with the existing UploadDataModal behavior: allowedExtensionsToAccept includes
'.tsv' for csv and '.zip' for columnar at src/features/databases/UploadDataModel/index.tsx
lines 166-170, and validateUploadFileExtension (lines 178-192) accepts those extensions.
This shows the FileHandler rejection is inconsistent with the modal's supported
extensions.

6. Reproduced in tests: the component tests in
superset-frontend/src/pages/FileHandler/index.test.tsx simulate launchQueue file handles
and expect the modal to open for various extensions (see tests for csv/xls/xlsx/parquet).
Adding a test case for 'test.tsv' or 'test.zip' will fail with the current FileHandler
logic (it will trigger the unsupported-file branch).
Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** superset-frontend/src/pages/FileHandler/index.tsx
**Line:** 76:88
**Comment:**
	*Logic Error: The file type detection logic only recognizes `.csv`, `.xls`, `.xlsx`, and `.parquet` extensions, ignoring other formats that the existing upload modal already supports (notably `.tsv` for delimited text and `.zip` for columnar uploads). This causes a valid TSV or zipped columnar file that can be uploaded via the standard UI to be rejected as "Unsupported file type" when opened via the PWA file handler, leading to inconsistent behavior between entry points.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.

@netlify
Copy link
Copy Markdown

netlify Bot commented Feb 2, 2026

Deploy Preview for superset-docs-preview ready!

Name Link
🔨 Latest commit 376aecc
🔍 Latest deploy log https://app.netlify.com/projects/superset-docs-preview/deploys/6980c9403faf960008af99e1
😎 Deploy Preview https://deploy-preview-36191--superset-docs-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@betodealmeida betodealmeida merged commit f2b6c39 into master Feb 2, 2026
72 checks passed
@betodealmeida betodealmeida deleted the file-handler branch February 2, 2026 16:24
@bito-code-review
Copy link
Copy Markdown
Contributor

Bito Automatic Review Skipped – PR Already Merged

Bito scheduled an automatic review for this pull request, but the review was skipped because this PR was merged before the review could be run.
No action is needed if you didn't intend to review it. To get a review, you can type /review in a comment and save it

alexandrusoare pushed a commit that referenced this pull request Feb 3, 2026
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
aminghadersohi pushed a commit to aminghadersohi/superset that referenced this pull request Mar 5, 2026
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
alex-poor pushed a commit to alex-poor/superset that referenced this pull request Mar 15, 2026
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
rusackas pushed a commit that referenced this pull request Apr 17, 2026
Cover remaining 6.1 features across existing and new pages:

MCP server:
- Add MCP_PARSE_REQUEST_ENABLED to configuration reference
- Add Audit Events section (MCP tool calls appear in Action Log)
- Add Tool Pagination section documenting cursor-based pagination (#37674)

Using AI with Superset:
- Expand Available Tools Reference into categorized sections covering
  all new tools added in the MCP tool library expansion
- Document preview-first workflow for generate_chart / update_chart

Creating Your First Dashboard:
- AG Grid server-side column filters (#35683): filter types, AND/OR logic,
  pagination interaction
- Time Shift for AG Grid Interactive Table (#37072)
- Dynamic currency formatting via currency_code_column dataset field (#36416)
- ECharts option editor in Explore for JSON overrides (#37868)
- Table chart: export behavior with search filter active (#36281)
- Dataset folders: organizing datasets into groups (#36239)
- PWA file handler: opening CSV/XLS/Parquet from OS file manager (#36191)
- Share database connection option when adding a new database (#37940)

Exploring Data:
- Dialect-aware Format SQL (applies selected database dialect) (#39393)
- SQL Lab tips section and time range natural language expressions
  (consolidates content from batch 4 for master branch)

Importing/Exporting:
- Dashboard import overwrite behavior: charts are replaced not duplicated (#36551)
- UUID in REST API POST responses for dataset/chart/dashboard (#37806)

New pages:
- docs/docs/using-superset/embedding.mdx: embedded SDK quick start,
  resolvePermalinkUrl callback (#36924),
  DISABLE_EMBEDDED_SUPERSET_LOGOUT feature flag (#37537),
  URL parameters, guest token security notes
- docs/admin_docs/configuration/aws-iam.mdx: cross-account IAM
  authentication for Aurora and Redshift via STS AssumeRole (#37585),
  configuration reference, trust policy setup guide

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
qfcwell pushed a commit to qfcwell/superset that referenced this pull request May 12, 2026
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api Related to the REST API change:frontend Requires changing the frontend data:csv Related to import/export of CSVs preset-io size/XL size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants