Skip to content

ENH: wire the JupyterLite build into the docs (JupyterLite split 5/5) - #14157

Open
natinew77-creator wants to merge 31 commits into
mne-tools:mainfrom
natinew77-creator:lite-docs-wiring
Open

ENH: wire the JupyterLite build into the docs (JupyterLite split 5/5)#14157
natinew77-creator wants to merge 31 commits into
mne-tools:mainfrom
natinew77-creator:lite-docs-wiring

Conversation

@natinew77-creator

@natinew77-creator natinew77-creator commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

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_docs is red until #14144 and #14150 land, and default just mirrors it. Parts 1 and 2 have merged, so the data and wheel steps now pass and it stops in conf.py: jupyterlite_cell_notes.py imports jupyterlite_setup_cell, which #14150 adds, and that in turn reads the renderer from #14144. Every other check is green, since nothing but Sphinx reads conf.py.

Checked on #13925, where the same wiring builds with every page executed and no sphinx warnings.

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.
@natinew77-creator
natinew77-creator marked this pull request as ready for review August 17, 2026 20:18
# 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.
natinew77-creator and others added 3 commits September 8, 2026 09:36
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.
Comment thread .circleci/config.yml Outdated
Comment on lines +279 to +285
# Ensure the data the JupyterLite notebooks need is on disk so conf.py can
# copy the required subset for the build. lite_data fetches only the
# curated files the browser notebooks use (from the MNE-lite-data OSF
# project) instead of the full sample/kiloword/erp_core/mtrf/eegbci
# datasets, which slims the build. The curated files share hashes with the
# full datasets, so on a full build that already downloaded them nothing
# extra is fetched.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would shorten this to say Download MNE-lite-data to run JupyterLite notebooks or something more concise.

Comment thread doc/sphinxext/jupyterlite_cell_notes.py Outdated
Comment on lines +45 to +59
"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",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

you can use """ to avoid needing linebreaks

Comment thread doc/conf.py Outdated
Comment on lines +497 to +504
# 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/, ...).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

make this comment shorter

Comment thread doc/conf.py Outdated
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():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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

Comment thread doc/conf.py Outdated
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"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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)
  ...
@larsoner

Copy link
Copy Markdown
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants