feat(python-notebook-migration): make embedded jupyter notebook read-only - #6945
feat(python-notebook-migration): make embedded jupyter notebook read-only#6945zyratlo wants to merge 3 commits into
Conversation
|
/request-review @mengw15 |
Automated Reviewer SuggestionsBased on the
|
There was a problem hiding this comment.
Pull request overview
Configures the notebook-migration-service’s embedded classic Jupyter Notebook container to behave as a clean, read-only reference view for migrated workflows, aligning with the intended “view-only” UX for embedded notebooks.
Changes:
- Adds a
custom.cssthat hides classic Notebook chrome and enforces a single scroll container inside the iframe. - Extends the container
Dockerfileto ship the new CSS alongside the existingcustom.js. - Hardens read-only behavior in
custom.jsby disabling CodeMirror editing, disabling keyboard shortcuts, and preventing Markdown cells from entering edit mode.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| notebook-migration-service/src/main/resources/Dockerfile | Copies custom.css into the Jupyter custom directory in the container image. |
| notebook-migration-service/src/main/resources/custom.js | Disables editing/execution interactions and keeps Markdown cells rendered for read-only viewing. |
| notebook-migration-service/src/main/resources/custom.css | Hides classic Notebook UI chrome and fixes the double-scrollbar issue by making #site the sole scroll container. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Yicong-Huang
left a comment
There was a problem hiding this comment.
please add some tests to verify the feature.
I can add tests, but I want to discuss what's testable here. This change is all static assets that live in the Jupyter container: On testing custom.js the traditional way: it's doable, but the catch is placement, not the file. custom.js is classic-Notebook AMD glue that assumes Problem: this is a Scala/sbt module with no JS runtime. The only JS runner in the repo is the frontend project. So either:
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6945 +/- ##
=========================================
Coverage 78.99% 78.99%
Complexity 3788 3788
=========================================
Files 1160 1160
Lines 46105 46105
Branches 5115 5115
=========================================
Hits 36419 36419
Misses 8067 8067
Partials 1619 1619
*This pull request uses carry forward flags. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
| config | throughput | MB/s | latency | max Δ latest / 7d | |
|---|---|---|---|---|---|
| 🔴 | bs=10 sw=10 sl=64 | 410 | 0.25 | 22,947/31,644/31,644 us | 🔴 -7.4% / 🔴 +94.9% |
| 🔴 | bs=100 sw=10 sl=64 | 799 | 0.488 | 123,072/173,136/173,136 us | 🔴 +17.9% / 🔴 +59.4% |
| ⚪ | bs=1000 sw=10 sl=64 | 926 | 0.565 | 1,074,735/1,150,123/1,150,123 us | ⚪ within ±5% / 🔴 +9.9% |
Baseline details
Latest main 31f1e7b from same runner
| config | metric | PR | latest main | 7d avg | Δ latest | Δ 7d |
|---|---|---|---|---|---|---|
| bs=10 sw=10 sl=64 | throughput | 410 tuples/sec | 442 tuples/sec | 767.9 tuples/sec | -7.2% | -46.6% |
| bs=10 sw=10 sl=64 | MB/s | 0.25 MB/s | 0.27 MB/s | 0.469 MB/s | -7.4% | -46.7% |
| bs=10 sw=10 sl=64 | p50 | 22,947 us | 21,739 us | 12,502 us | +5.6% | +83.6% |
| bs=10 sw=10 sl=64 | p95 | 31,644 us | 31,528 us | 16,234 us | +0.4% | +94.9% |
| bs=10 sw=10 sl=64 | p99 | 31,644 us | 31,528 us | 18,919 us | +0.4% | +67.3% |
| bs=100 sw=10 sl=64 | throughput | 799 tuples/sec | 826 tuples/sec | 974.8 tuples/sec | -3.3% | -18.0% |
| bs=100 sw=10 sl=64 | MB/s | 0.488 MB/s | 0.504 MB/s | 0.595 MB/s | -3.2% | -18.0% |
| bs=100 sw=10 sl=64 | p50 | 123,072 us | 121,033 us | 102,449 us | +1.7% | +20.1% |
| bs=100 sw=10 sl=64 | p95 | 173,136 us | 146,824 us | 108,652 us | +17.9% | +59.4% |
| bs=100 sw=10 sl=64 | p99 | 173,136 us | 146,824 us | 116,310 us | +17.9% | +48.9% |
| bs=1000 sw=10 sl=64 | throughput | 926 tuples/sec | 934 tuples/sec | 1,004 tuples/sec | -0.9% | -7.8% |
| bs=1000 sw=10 sl=64 | MB/s | 0.565 MB/s | 0.57 MB/s | 0.613 MB/s | -0.9% | -7.8% |
| bs=1000 sw=10 sl=64 | p50 | 1,074,735 us | 1,066,164 us | 999,606 us | +0.8% | +7.5% |
| bs=1000 sw=10 sl=64 | p95 | 1,150,123 us | 1,136,643 us | 1,046,770 us | +1.2% | +9.9% |
| bs=1000 sw=10 sl=64 | p99 | 1,150,123 us | 1,136,643 us | 1,076,937 us | +1.2% | +6.8% |
Raw CSV
config_idx,batch_size,schema_width,string_len,num_batches,total_ms,total_tuples,total_bytes,tuples_per_sec,mb_per_sec,lat_p50_us,lat_p95_us,lat_p99_us
0,10,10,64,20,488.22,200,128000,410,0.250,22947.49,31643.58,31643.58
1,100,10,64,20,2503.58,2000,1280000,799,0.488,123072.30,173136.18,173136.18
2,1000,10,64,20,21590.92,20000,12800000,926,0.565,1074735.03,1150123.35,1150123.35
What changes were proposed in this PR?
The notebook migration service generates a Jupyter notebook and embeds it in the Texera app as a reference view of the migrated workflow. It is meant for reading, not editing. This PR configures the embedded Jupyter container so the notebook renders as a clean, read-only view.
Changes, all scoped to the notebook migration service container assets:
custom.css(new): hides the classic Notebook chrome (header with logo and logout, kernel and trust indicators, the File/Edit/View menu, and the toolbar), and fixes a second, non-functional scrollbar by making#sitethe single scroll container.Dockerfile: copiescustom.cssinto/home/jovyan/.jupyter/custom/custom.css, next to the existingcustom.js.custom.js: read-only hardening. Sets every code cell's CodeMirror editor toreadOnly: "nocursor", callskeyboard_manager.disable()so cells cannot be edited or executed, and overridesMarkdownCell.prototype.unrenderso markdown cells stay rendered. The existing click-to-highlight postMessage integration is unchanged.This does not touch the Texera frontend or backend.
UI Comparison
Before this PR:

After this PR:

Any related issues, documentation, discussions?
Closes #6943
Parent issue #4301
How was this PR tested?
Tested manually by building the container and opening the embedded notebook in the Texera app:
No automated tests were added: the change is static container assets (CSS and client-side JS in the classic Notebook UI) with no code path exercisable by the existing unit test suites.
Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code (Claude Opus 4.8)