ENH: wire the JupyterLite build into the docs (JupyterLite split 5/5) - #14157
Conversation
Enables jupyterlite_sphinx, stages the data the browser notebooks read, prepends the setup cell to each notebook copy, and leaves the launch badge off the pages that cannot run in the browser.
It sits with "Get data and triage examples to run" rather than after test-doc. Same effect, since all it has to do is precede make html, and it keeps the step away from the wheel build's insertion point.
find_wheels() returns Path objects since the wheel build moved to pathlib,
so the log line was rendering as [PosixPath('...')].
# Conflicts: # doc/documentation/datasets.rst
The tutorial crops the white margins off brain.screenshot(), and vtk.js cannot hand a framebuffer back to Python, so there is no screenshot to crop.
Two entries had gone stale: upstream renamed decoding_rsa_sgskip.py and montage_sgskip.py, so both examples were badged again despite still needing the datasets they were excluded for. Also excludes the new 21_interactive_dipole_fit, which is a tour of mne.gui.dipolefit and needs a picker vtk.js does not provide.
Stage the served data from a sphinxext module only when MNE_DOC_BUILD_JUPYTERLITE=1, which make html sets, so pattern and noplot builds skip the copy and the lite build; skip files already staged; drop the exclusions for the pages that now run through the backend; fix stale text.
There was a problem hiding this comment.
I would shorten this to say Download MNE-lite-data to run JupyterLite notebooks or something more concise.
| "forward/20_source_alignment.ipynb", | ||
| "mne.gui.coregistration", | ||
| "**This cell does not run in the browser.**\n" | ||
| "\n" | ||
| "`mne.gui.coregistration` sets the fiducials by clicking on the scalp\n" | ||
| "surface, and the vtk.js renderer used here draws scenes without a\n" | ||
| "picker, so there is nothing for those clicks to hit. Run it from a\n" | ||
| "local MNE install instead:\n" | ||
| "\n" | ||
| "```python\n" | ||
| 'mne.gui.coregistration(subject="sample", subjects_dir=subjects_dir)\n' | ||
| "```\n" | ||
| "\n" | ||
| "The video above walks through the same steps, and the rest of this\n" | ||
| "notebook runs normally.\n", |
There was a problem hiding this comment.
you can use """ to avoid needing linebreaks
| # Inject the required subset of MNE-sample-data for JupyterLite. The data is | ||
| # placed under doc/lite_extra/mne_data and served at the docs root via | ||
| # html_extra_path (added below). The JupyterLite setup cell fetches these | ||
| # files over HTTP into the Pyodide kernel: the /drive virtual-filesystem | ||
| # bridge needs cross-origin-isolation (COOP/COEP) headers that static | ||
| # artifact servers (e.g. CircleCI) do not send, so it is unusable there. | ||
| # lite_data (mne.datasets.lite_data) extracts the curated subset here, with the | ||
| # files under their original dataset folders (MNE-sample-data/, ...). |
| f"{(mne_data_base / 'MNE-sample-data').exists()}, " | ||
| f"curated archive={src_sample_data.exists()}" | ||
| ) | ||
| if (mne_data_base / "MNE-sample-data").exists() or src_sample_data.exists(): |
There was a problem hiding this comment.
is there a way to get a list of files from mne-lite-data instead of listing them below in the required_files? it would make this DRYer if we didn't need to list them again here
| lite_data_base.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| src_ssvep = mne_data_base / "ssvep-example-data" | ||
| dst_ssvep = lite_data_base / "ssvep-example-data" |
There was a problem hiding this comment.
is there a reason that the lite_data doesn't ship with the ssvep or eeglab data?
* upstream/main: (25 commits) ENH: add the JupyterLite notebook setup cell (JupyterLite split 4/5) (mne-tools#14150) FIX: Ver [circle deploy] [skip azp] [skip actions] Hotfix fix EDF round-trip (mne-tools#14296) Brain GUI modernization (Phase 7) (mne-tools#14270) Fix bug with SciPy 1.18.0 EEGLAB reading (mne-tools#14293) remove plotting abs as the defauls for plotting volumetric (mne-tools#13989) Coregistration GUI modernisation (phase 4) (mne-tools#14285) Dipole GUI interactivity and visual enhancements (phase 2) (mne-tools#14291) Width [circle deploy] [skip azp] [skip actions] Post-release deprecations (mne-tools#14290) FIX: Come on [circle deploy] [skip azp] [skip actions] PyVista try again [circle deploy] [skip azp] [skip actions] FIX: PyVista [circle deploy] [skip azp] [skip actions] FIX: Really [circle deploy] [skip azp] [skip actions] FIX: Doc Release commit [circle deploy] MAINT: Update code credit (mne-tools#14289) MAINT: Update pre-commit hook versions (mne-tools#14288) BUG: use fixed normalized CTPS cutoff for automatic ECG detection (mne-tools#14279) ...
|
I am about to push changes now that #14150 was merged. I want to slim down the files that are used since it's currently 1.2 GB, which is a lot. |
* upstream/main: No PyQt5 [circle deploy] [skip azp] [skip actions]
* upstream/main: Fix for NumPy eig change [circle deploy] (mne-tools#14300)
* upstream/main: Small documentation fix for "Frequency and time-frequency sensor analysis" tutorial (mne-tools#14304) FIX: don't mutate cached ICA sources in plot_sources properties (mne-tools#14303) Fix bug with lite backend closing (mne-tools#14302)
|
Okay this example works great!
Thanks @natinew77-creator ! |
|
thanks @natinew77-creator for all your contributions over your GSoC. it's great to have this resource! thanks @larsoner for all your help to getting this across this finish line! I still learn so much watching you work :) |


Part 5 of the split of #13925, and the last one. Parts 1 to 4 are #14128, #14135, #14144 and #14150.
Wires the previous four together: enables
jupyterlite_sphinx, serves the data subset the browser notebooks read, and prepends the setup cell to each notebook copy. It also carries the list of pages that do not get an "Open in JupyterLite" badge, since sphinx-gallery adds one to every example. Only the badge is dropped, the notebook source is untouched.build_docsis red until #14144 and #14150 land, anddefaultjust mirrors it. Parts 1 and 2 have merged, so the data and wheel steps now pass and it stops inconf.py:jupyterlite_cell_notes.pyimportsjupyterlite_setup_cell, which #14150 adds, and that in turn reads the renderer from #14144. Every other check is green, since nothing but Sphinx readsconf.py.Checked on #13925, where the same wiring builds with every page executed and no sphinx warnings.