feat: display Jupyter notebook in cluster detail page#181
Merged
glaubervila merged 5 commits intoJun 30, 2026
Conversation
Add GET /api/metadata/user_tables/{id}/notebook/ action to
UserTableViewSet. The endpoint queries a single row from the dynamic
user table using the same filter mechanism as the data/ endpoint,
substitutes the row data into a Jinja-style .ipynb template, and
returns the notebook rendered as HTML via nbconvert.
Also add nbconvert and nbformat to requirements and ship the initial
cluster_detail_template.ipynb with placeholders for meta_id, meta_ra,
meta_dec, and meta_radius_arcmin.
… panel Add getNotebookHtml service that calls the new notebook/ endpoint using catalog.property_id as the dynamic filter key and record.meta_id as the value, avoiding any assumption about fixed column names. In ClusterDetail, fetch the notebook HTML with useQuery and render it in an iframe using srcDoc. A Skeleton fills the panel while loading; once the iframe fires onLoad, its scrollHeight is measured and the Paper expands to the exact content height, replacing the Skeleton.
Replace simple template string substitution with in-process notebook execution for the cluster detail view. The notebook now receives the main record, its table metadata, and (for cluster catalogs) the related members table data and metadata as Python literals injected into a dedicated `# canvas-variables` cell. Key changes: - Add `_execute_notebook_inprocess` to run notebook code cells in-process, capturing stdout/stderr streams and matplotlib figures as outputs - Add `query_data` helper that fetches rows and maps UCD-based virtual fields (meta_id, meta_ra, meta_dec, meta_radius_arcmin) onto each row - Add `ucds` field to `NestedTableSerializer` exposing a UCD→column-name map consumed by the notebook - For cluster catalogs, also fetch the related members table data and pass it to the notebook - Add `ipykernel` and `matplotlib` dependencies; exclude .ipynb files from ruff linting
- Remove height: 100% from page Box so the page can grow beyond the viewport
- Remove height: 100% from ClusterDetail outer Box; Grid items already have
explicit heights so the constraint was unnecessary and clipped the notebook
- Fix Skeleton height: replace flex:1 (collapsed without a parent height) with
a fixed height={500}
- Re-measure iframe height 500ms after onLoad to capture late-painted content
(images, CSS) that affects scrollHeight after initial load
- Add bottom spacer Box below the notebook Paper for page breathing room
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.
Adds a pre-rendered Jupyter notebook panel at the bottom of the Cluster Detail page. The notebook is executed server-side with the cluster's data injected as variables and returned as HTML, displayed in an iframe below the Members/Aladin section.
Backend:
Frontend:
Test plan
Open a cluster detail page for a catalog with a notebook template configured
Verify the Skeleton appears while the notebook loads
Verify the notebook renders fully below the Members/Aladin section
Scroll to the bottom and confirm the full notebook content is visible with spacing at the end
Verify the Members tab, Properties tab, and Aladin viewer still work correctly
Open a cluster from a catalog without a notebook — confirm no iframe or skeleton appears