-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
ENH: build the dev MNE wheel for JupyterLite (JupyterLite split 2/5) #14135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
natinew77-creator
wants to merge
22
commits into
mne-tools:main
Choose a base branch
from
natinew77-creator:lite-wheel-build
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
a48b2cd
ENH: build the dev MNE wheel for the JupyterLite browser kernel
natinew77-creator abd1bda
DOC: add the changelog entry for the JupyterLite wheel build
natinew77-creator 8caccea
Merge branch 'main' into lite-wheel-build
natinew77-creator 49d7057
Merge branch 'main' into lite-wheel-build
natinew77-creator 4b598a5
Merge branch 'main' into lite-wheel-build
natinew77-creator 15cd2c8
Merge branch 'main' into lite-wheel-build
natinew77-creator c355342
MAINT: only relax matplotlib for the browser wheel
natinew77-creator ce98cef
Merge branch 'main' into lite-wheel-build
natinew77-creator 86e1e21
Merge branch 'main' into lite-wheel-build
natinew77-creator 24efce3
MAINT: move the browser build to Pyodide 314
natinew77-creator fb9a0b0
Merge branch 'main' into lite-wheel-build
natinew77-creator bd1b66a
Merge branch 'main' into lite-wheel-build
natinew77-creator b0e07f4
Merge branch 'main' into lite-wheel-build
natinew77-creator 8c37209
DOC: bring the Pyodide override comment up to date
natinew77-creator 10ae765
DOC: correct the scipy version Pyodide 314 ships
natinew77-creator a5b688d
Merge branch 'main' into lite-wheel-build
natinew77-creator cf09b9e
Merge branch 'main' into lite-wheel-build
natinew77-creator 35a269f
Merge branch 'main' into lite-wheel-build
natinew77-creator 0db81ed
Merge branch 'main' into lite-wheel-build
natinew77-creator 343580a
MAINT: address review on the JupyterLite wheel build
natinew77-creator 075b1ee
Merge branch 'main' into lite-wheel-build
natinew77-creator 2a1c7fb
Merge branch 'main' into lite-wheel-build
natinew77-creator File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Add a build script and CI step that produce the development MNE wheel the JupyterLite browser kernel installs, by `Natneal B`_. |
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| """Build the development MNE wheel for the JupyterLite browser kernel. | ||
|
|
||
| Run this once before building the docs, either in CI or locally:: | ||
|
|
||
| python doc/sphinxext/build_lite_wheel.py | ||
|
|
||
| The wheel is written to ``doc/pypi``, where the jupyterlite-pyodide-kernel | ||
| PipliteAddon discovers, copies and indexes it (adding it to ``pipliteUrls`` in | ||
| ``jupyter-lite.json``), so the browser kernel installs the current development | ||
| MNE rather than the older release from PyPI. See | ||
| https://jupyterlite.readthedocs.io/en/latest/howto/pyodide/wheels.html | ||
|
|
||
| Both functions are importable, so a docs build can reuse a wheel that is already | ||
| present rather than building one on every invocation:: | ||
|
|
||
| from build_lite_wheel import build_wheel, find_wheels | ||
|
|
||
| wheels = find_wheels() or build_wheel() | ||
| """ | ||
|
|
||
| # Authors: The MNE-Python contributors. | ||
| # License: BSD-3-Clause | ||
| # Copyright the MNE-Python contributors. | ||
|
|
||
| import json | ||
| import os | ||
| import shutil | ||
| import subprocess | ||
| import sys | ||
| import urllib.request | ||
| from pathlib import Path | ||
|
|
||
| REPO_ROOT = Path(__file__).resolve().parents[2] | ||
| PYPI_WHEELS_DIR = REPO_ROOT / "doc" / "pypi" | ||
|
|
||
|
|
||
| def find_wheels(): | ||
| """Return the MNE wheels already present in ``doc/pypi``. | ||
|
|
||
| Returns | ||
| ------- | ||
| wheels : list of pathlib.Path | ||
| Paths of the MNE wheels found, empty if there are none. | ||
| """ | ||
| return sorted(PYPI_WHEELS_DIR.glob("mne-*.whl")) | ||
|
|
||
|
|
||
| def _latest_pypi_version(): | ||
| """Return the newest MNE version on PyPI, or None if it cannot be reached. | ||
|
|
||
| Returns | ||
| ------- | ||
| version : str | None | ||
| The version string, or None if PyPI could not be queried. | ||
| """ | ||
| # Broad on purpose: this only ever runs while raising, so a network problem | ||
| # here must not replace the real error with a less useful one. | ||
| try: | ||
| url = "https://pypi.org/pypi/mne/json" | ||
| with urllib.request.urlopen(url, timeout=10) as response: | ||
| return json.load(response)["info"]["version"] | ||
| except Exception: | ||
| return None | ||
|
|
||
|
|
||
| def build_wheel(): | ||
| """Build the development MNE wheel into ``doc/pypi``. | ||
|
|
||
| Returns | ||
| ------- | ||
| wheels : list of pathlib.Path | ||
| Paths of the MNE wheels that were built. | ||
| """ | ||
| # The version below is pinned, so each build writes the same filename and | ||
| # wheels do not pile up. Clearing first is about determinism instead: this | ||
| # directory is the piplite index, so it should hold the wheel this build | ||
| # produced and nothing else, including anything left by a manual pip wheel. | ||
| shutil.rmtree(PYPI_WHEELS_DIR, ignore_errors=True) | ||
| PYPI_WHEELS_DIR.mkdir(parents=True, exist_ok=True) | ||
|
|
||
| # The wheel is built from pyproject.toml as it stands: Pyodide 314 ships | ||
| # matplotlib 3.10.8, scipy 1.18.0 and numpy 2.4.3, all of which satisfy the | ||
| # minimums MNE declares, so none of them needs relaxing for the browser. | ||
| os.environ["SETUPTOOLS_SCM_PRETEND_VERSION"] = "9999.0.1" | ||
| # NB: build isolation is left ON (the default). MNE uses the hatchling build | ||
| # backend, so pip must create an isolated build env to install | ||
| # hatchling/hatch-vcs; --no-build-isolation fails with "Cannot import | ||
| # 'hatchling.build'" on CI, where those build deps are not in the base | ||
| # environment. | ||
| subprocess.run( | ||
| [ | ||
| sys.executable, | ||
| "-m", | ||
| "pip", | ||
| "wheel", | ||
| REPO_ROOT, | ||
| "--no-deps", | ||
| "-w", | ||
| PYPI_WHEELS_DIR, | ||
| ], | ||
| check=True, | ||
| ) | ||
|
|
||
| # Fail loudly rather than silently letting the browser kernel fall back to | ||
| # the released MNE from PyPI. | ||
| wheels = find_wheels() | ||
| if not wheels: | ||
| latest = _latest_pypi_version() | ||
| fallback = f"MNE {latest}" if latest else "the latest MNE release" | ||
| raise RuntimeError( | ||
| f"JupyterLite: no MNE wheel was built into {PYPI_WHEELS_DIR}; the " | ||
| f"browser kernel would fall back to {fallback} from PyPI. Check the " | ||
| "'pip wheel' output above." | ||
| ) | ||
| return wheels | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| built = ", ".join(str(wheel) for wheel in build_wheel()) | ||
| print(f"[JupyterLite] Built MNE wheel(s) for the browser kernel: {built}") | ||
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
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
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.