🕹️ Try the demo
jupyterlite-pyodide-lock#
Build reproducible Jupyter Lite sites with jupyterlite-pyodide-kernel and pyodide-lock.
View the full documentation on ReadTheDocs.
Overview#
jupyterlite-pyodide-lock avoids run time jupyterlite-pyodide-kernel
package management ambiguity with a build time package-lock.json, built in a full
web browser.
This works by:
downloading a
pyodide-lock.jsonrunning a minimal
pyodideruntime in a browser managed by Python(optional) or
selenium
installing a configurable set of packages from the build environment, PyPI, or elsewhere
returning the list to build a new
package-lock.json(optional) copying all downloaded wheels to be served along with the site
configuring
jupyterlite-pyodide-kernelto use the newpyodide-lock.json(optional) rewriting other generated
jupyter-config-datain JupyterLite app pages
Examples#
Use jupyterlite-pyodide-lock to minimally provide a more
predictable baseline pyodide runtime environment, or ensure complex dependencies like
widgets are consistent over time.
Minimal Example#
Ensure pyodide-kernel's dependencies are locked, assuming
pip and firefox.
Create the Minimal Build Environment#
make a
requirements.txtjupyterlite-core ==0.7.0 jupyterlite-pyodide-kernel ==0.7.0 jupyterlite-pyodide-lock ==0.2.0
Run:
pip install -r requirements.txt
Configure the Minimal Site#
build a
jupyter_lite_config.json:{ "PyodideLockAddon": { "enabled": true } }
Build the Minimal Site#
build a
jupyter_lite_config.json:jupyter lite build
Check the Minimal Site Works#
start a simple, local development server
cd _output python -m http.server -b 127.0.0.1
visit the site at
http://127.0.0.1:8000/make a new Notebook
use basic
pythonfeatures
Widgets Example#
Build a JupyterLite site with all the packages needed to run
ipywidgets in a Notebook, assuming mamba.
Create the Widget Build Environment#
make an
environment.ymlchannels: - conda-forge - nodefaults dependencies: - ipywidgets ==8.1.8 - jupyterlite-core ==0.7.0 - jupyterlite-pyodide-kernel ==0.7.0 - jupyterlite-pyodide-lock-recommended ==0.2.0
the
-recommendedpackage includesfirefoxandgeckodriveroptionally use a tool like
conda-lockorpixito create a lockfile for the build environment
Run:
mamba env update --file environment.yml --prefix .venv source activate .venv # or just `activate .venv` on windows
Configure the Widgets Site#
build a
jupyter_lite_config.json:{ "PyodideLockAddon": { "enabled": true, "constraints": ["traitlets ==5.14.3"], "specs": ["ipywidgets ==8.1.8"], "extra_preload_packages": ["ipywidgets"] }, "PyodideLockOfflineAddon": { "enabled": true } }
note the tight
ipywidgetspin, ensuring compatibility with the build environmentwhile not required, the
constraintsoption allows for controlling transitive dependenciesthis feature requires
micropip >=0.9.0, which is only compatible withpyodide >=0.27
Build the Site with Widgets#
build a
jupyter_lite_config.json:jupyter lite build
Check Widgets Works Offline#
disconnect from the internet ✈️
this step is optional, but is the most reliable way to validate a reproducible site
start a simple, local development server
cd _output python -m http.server -b 127.0.0.1
visit the site at
http://127.0.0.1:8000/make a new Notebook
see that
ipywidgetscan be imported, and widgets work:import ipywidgets ipywidgets.FloatSlider()
Motivation#
By default, a
pyodidedistribution provides a precise set of hundreds of package versions known to work together in the browser, described in itspyodide-lock.json.Among these packages is
micropip, which gives site users the ability to install packages not included inpyodide-lock.json. These may be served along with an HTML page, downloaded from PyPI, or anywhere on the internet.jupyterlite-pyodide-kerneluses this capability to install itself, and its dependencies.At run time,
pipliteprovides amicropip-based shim for the IPython%pipmagic, the most portable approach for interactive package management in Notebook documents.
micropip(and%pip) are powerful for interactive usage, but can cause headaches when upstream versions (or their dependencies) change in ways that either no longer provide the same API expected by the exact versions ofpyodide,pyodide-kernel, and JupyterLab extensions in a deployed JupyterLite site.
jupyterlite-pyodide-lock gives content authors tools to manage their effective
pyodide distribution, making it easier to build, verify, and maintain predictable,
interactive computing environments for future site visitors.
Why Use This?#
in a user’s browser
fetches
pyodide-kernel, its dependencies, and configured packages in parallel whilepyodideis starting, skippingmicropip.installand its requests to the PyPI APIdoesn’t require
%pip installfor locked packages and their dependenciesnotebooks and scripts still need to be well-formed, e.g.
import my_packageonce shipped, package versions loaded in the browser won’t change over time
in a site owner’s build environment
doesn’t require rebuilding a full custom
pyodidedistributionbut will patch a custom deployed
pyodideall downloaded wheels can be optionally shipped along with the application
optionally age gate PyPI packages to a known timestamp to ensure newer packages aren’t found during a future solve
supports multiple sources of custom wheels and dependencies
Feature Comparison#
A number of approaches are available for getting reproducible JupyterLite runtime python
environments, either with jupyterlite-pyodide-kernel or other kernels. Choosing one
requires some trades of simplicity, reproducibility, flexibility, and performance.
⏱️ Note
Each tool is evolving, so the tables below should be verified against the different tools when making a decision.
A visitor to a JupyterLite site's needs may be the top priority...
feature |
|
|
||
|---|---|---|---|---|
needs separate |
no (for locked packages) |
yes ( |
no |
no |
allows runtime install by PyPI name |
yes |
yes |
yes |
yes |
allows runtime install from URL |
yes |
yes |
no |
yes |
blocks interaction per package |
run cell |
run cell |
start kernel |
run cell |
caches in the browser |
per package |
per package |
whole environment |
per package |
An author of a JupyterLite site may have additional needs...
feature |
|
|
||
|---|---|---|---|---|
requires “heavy” build dependencies |
yes, (real browser and/or |
no |
minimal, see repo |
many, see repo |
ships local wheels |
yes |
yes |
yes |
yes |
ships noarch PyPI wheels |
yes |
yes |
yes |
yes |
ships pyodide emscripten wheels |
yes |
yes |
no |
yes |
ships arbitrary pyodide zip C libs |
no |
yes |
no |
yes |
ships multiple versions of same package |
no |
yes |
no |
no |
age gates dependencies |
yes (optional) |
no |
no |
n/a |