[PR #21394] [CLOSED] feat: support arbitrary file output from Jupyter code execution #64921

Closed
opened 2026-05-06 10:39:37 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/open-webui/open-webui/pull/21394
Author: @lewisco
Created: 2/13/2026
Status: Closed

Base: mainHead: feat/jupyter-generic-file-output


📝 Commits (1)

  • 3151992 feat: support arbitrary file output from Jupyter code execution

📊 Changes

5 files changed (+343 additions, -71 deletions)

View changed files

📝 backend/open_webui/tools/builtin.py (+84 -32)
📝 backend/open_webui/utils/code_interpreter.py (+124 -4)
📝 backend/open_webui/utils/files.py (+76 -2)
📝 backend/open_webui/utils/middleware.py (+58 -32)
📝 src/lib/components/chat/Messages/ResponseMessage.svelte (+1 -1)

📄 Description

Summary

  • The Jupyter code interpreter engine was limited to capturing image/png outputs only. Skills that generate documents (PPTX, PDF, XLSX, CSV, etc.) had no way to deliver files to users
  • This generalizes the entire output pipeline — from Jupyter kernel capture through backend processing to frontend display — to handle any file type
  • Non-image files are delivered as downloadable chat message attachments using the existing chat:message:files event pattern (same as generate_image)

Changes across 5 files:

  • code_interpreter.py — Capture any image/*, application/*, audio/* MIME type from Jupyter. Add preamble/postamble that creates a writable data dir, scans for new files after execution, and emits them as display_data with correct MIME types and original filenames
  • files.py — Add generic upload_file_from_base64() and get_file_url_from_base64() that handle any data URI MIME type. Register common office MIME types. Support embedded filename parameter in data URIs
  • builtin.py — Replace image-only scanning in execute_code with generic data URI detection. Images render inline; non-image files emitted as chat:message:files attachments with DB persistence
  • middleware.py — Apply same generic handling to the native (non-tool) code interpreter path
  • ResponseMessage.svelte — Change file display gate from filter(f => f.type === 'image') to show all file types (the inner {#each} already dispatches to <Image> vs <FileItem>)

How it works

  1. User code saves a file (e.g., .pptx) to __owui_data_dir (set by the preamble)
  2. Postamble detects the new file, reads it, and emits as display_data with the correct MIME type
  3. code_interpreter.py captures the base64 data with MIME type and original filename
  4. builtin.py uploads via get_file_url_from_base64() and emits as a chat file attachment
  5. Frontend renders it as a downloadable <FileItem>

Test plan

  • Set CODE_INTERPRETER_ENGINE=jupyter with an external Jupyter server
  • Run a skill/code that generates a .pptx file using python-pptx — verify it appears as a downloadable attachment in the chat
  • Run existing image generation code (e.g., matplotlib plot) — verify images still render inline as before
  • Test with PDF output (data:application/pdf;base64,...) and CSV output
  • Verify the original filename is preserved (not generated-file.pptx)
  • Verify the download link works (no 404 or double URL path)

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/open-webui/open-webui/pull/21394 **Author:** [@lewisco](https://github.com/lewisco) **Created:** 2/13/2026 **Status:** ❌ Closed **Base:** `main` ← **Head:** `feat/jupyter-generic-file-output` --- ### 📝 Commits (1) - [`3151992`](https://github.com/open-webui/open-webui/commit/3151992435793bb12297d41111ae16df3bb6b889) feat: support arbitrary file output from Jupyter code execution ### 📊 Changes **5 files changed** (+343 additions, -71 deletions) <details> <summary>View changed files</summary> 📝 `backend/open_webui/tools/builtin.py` (+84 -32) 📝 `backend/open_webui/utils/code_interpreter.py` (+124 -4) 📝 `backend/open_webui/utils/files.py` (+76 -2) 📝 `backend/open_webui/utils/middleware.py` (+58 -32) 📝 `src/lib/components/chat/Messages/ResponseMessage.svelte` (+1 -1) </details> ### 📄 Description ## Summary - The Jupyter code interpreter engine was limited to capturing `image/png` outputs only. Skills that generate documents (PPTX, PDF, XLSX, CSV, etc.) had no way to deliver files to users - This generalizes the entire output pipeline — from Jupyter kernel capture through backend processing to frontend display — to handle any file type - Non-image files are delivered as downloadable chat message attachments using the existing `chat:message:files` event pattern (same as `generate_image`) ### Changes across 5 files: - **`code_interpreter.py`** — Capture any `image/*`, `application/*`, `audio/*` MIME type from Jupyter. Add preamble/postamble that creates a writable data dir, scans for new files after execution, and emits them as `display_data` with correct MIME types and original filenames - **`files.py`** — Add generic `upload_file_from_base64()` and `get_file_url_from_base64()` that handle any data URI MIME type. Register common office MIME types. Support embedded `filename` parameter in data URIs - **`builtin.py`** — Replace image-only scanning in `execute_code` with generic data URI detection. Images render inline; non-image files emitted as `chat:message:files` attachments with DB persistence - **`middleware.py`** — Apply same generic handling to the native (non-tool) code interpreter path - **`ResponseMessage.svelte`** — Change file display gate from `filter(f => f.type === 'image')` to show all file types (the inner `{#each}` already dispatches to `<Image>` vs `<FileItem>`) ### How it works 1. User code saves a file (e.g., `.pptx`) to `__owui_data_dir` (set by the preamble) 2. Postamble detects the new file, reads it, and emits as `display_data` with the correct MIME type 3. `code_interpreter.py` captures the base64 data with MIME type and original filename 4. `builtin.py` uploads via `get_file_url_from_base64()` and emits as a chat file attachment 5. Frontend renders it as a downloadable `<FileItem>` ## Test plan - [ ] Set `CODE_INTERPRETER_ENGINE=jupyter` with an external Jupyter server - [ ] Run a skill/code that generates a `.pptx` file using `python-pptx` — verify it appears as a downloadable attachment in the chat - [ ] Run existing image generation code (e.g., matplotlib plot) — verify images still render inline as before - [ ] Test with PDF output (`data:application/pdf;base64,...`) and CSV output - [ ] Verify the original filename is preserved (not `generated-file.pptx`) - [ ] Verify the download link works (no 404 or double URL path) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-05-06 10:39:37 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/open-webui#64921