Skip to content

Enable jupyterlite pixi tasks #58

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

Merged
merged 18 commits into from
May 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ jobs:
- name: Setup pixi
uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da # v0.8.8

- name: Build executed notebooks and HTML
- name: Build HTML
run: pixi run build

- name: Build jupyterlite
run: pixi run build_wasm

- name: Upload executed notebooks as GitHub artifact (for debugging)
uses: actions/upload-artifact@v4
with:
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,15 @@ jobs:

- name: Build static site
run: pixi run build

pixi_build_wasm:
name: Build jupyterlite site with pixi
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Setup pixi
uses: prefix-dev/setup-pixi@v0.8.1

- name: Build jupyterlite site
run: pixi run build_wasm
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ _build/*
# No .ipynb files should be stored in this repository.
*.ipynb

# Jupyterlite Database
.jupyterlite.doit.db

# We treat this repository as a library, not an application, and thus we do not
# include the lockfile in source control. For a specific event, like a
# workshop, we suggest committing the lockfile on a branch dedicated to the
Expand Down
6 changes: 6 additions & 0 deletions activate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env bash

set -eux

mkdir -p ${CONDA_PREFIX}/share/jupyter/lab/settings
cp ${PIXI_PROJECT_ROOT}/.binder/overrides.json ${CONDA_PREFIX}/share/jupyter/lab/settings/overrides.json
34 changes: 34 additions & 0 deletions convert_all_jupyterlite.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash

# This is a script which copies the contents of the tutorials
# directory into a build directory (_build/ipynbs).
# The notebook markdown files are converted to ipynbs with other
# files (non-executable md files, static images, etc) are copied
# directly.
# This is intended for jupyterlite to build pointing to the build
# directory since the markdown files do not currently work in
# jupyterlite.

# Find Markdown files convert.
files_to_process=$(find tutorials -type f)

OUTDIR="_build/ipynbs"

# Identify Markdown files that are Jupytext and convert them all.
for file in ${files_to_process}; do
# Ensure result directory exists
echo "Making directory: $OUTDIR/$(dirname $file)"
mkdir -p $OUTDIR/$(dirname $file)

echo loop in $file
# Extract the kernel information from the Jupytext Markdown file.
kernel_info=$(grep -A 10 '^---$' "$file" | grep -E 'kernelspec')
# Copy directly if not a notebook file
if [ -z "$kernel_info" ]; then
cp $file $OUTDIR/$file
continue
fi
# Convert to ipynb format, to be consumed by pytest nbval plugin.
notebook_file="${file%.md}.ipynb"
jupytext --to ipynb "$file" --output $OUTDIR/${notebook_file}
done
70 changes: 57 additions & 13 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ authors = [
"Ross Barnowski <rossbar@caltech.edu>",
"Kyle Sunden <git@ksunden.space>",
]
channels = ["conda-forge"]
channels = ["https://repo.mamba.pm/emscripten-forge", "conda-forge"]
description = "Add a short description here"
name = "executable-tutorials"
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64", "emscripten-wasm32"]
version = "0.1.0"

[tasks]
[feature.base]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]

[feature.base.tasks]
build = { cmd = [
"sphinx-build",
".", # source directory
Expand All @@ -25,22 +28,23 @@ clean = "rm -rf _build/*"
start = "jupyter lab --FileContentsManager.preferred_dir tutorials"
test = "bash ./test.sh"

[activation]
[feature.base.activation]
# Workaround overrides JupyterLab configuration (at the environment level) to
# make double-clicking on a Jupytext Markdown file open that file as a
# notebook. This is important for the development workflow for contributors.
scripts = ["bash .binder/postBuild"]
scripts = ["activate.sh"]

[dependencies]
[feature.base.dependencies]
python = ">=3.11"
matplotlib-base = ">=3.9"
ipympl = ">=0.9"
jupyterlab = ">=4.2"
jupyterlab-myst = ">=2.4"
pytest = ">=8.3.5,<9"
nbval = ">=0.11.0,<0.12"
jupytext = ">=1.17.1,<2"
ipympl = ">=0.9"

[pypi-dependencies]
[feature.base.pypi-dependencies]
sphinx = ">=8.0.2"
myst-nb = ">=1.1"
jupytext = ">=1.16"
Expand All @@ -49,19 +53,59 @@ sphinx-copybutton = ">=0.5"
sphinx-design = "*"
pytest-custom_exit_code = "*"

[feature.py312]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]

[feature.py312.dependencies]
python = "3.12.*"

[feature.py313]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]

[feature.py313.dependencies]
python = "3.13.*"

[feature.jupyterlite.dependencies]
[feature.jupyterlite-runtime]
channels = ["https://repo.mamba.pm/emscripten-forge", "conda-forge"]
platforms = ["emscripten-wasm32"]

[feature.jupyterlite-runtime.dependencies]
xeus-python = "*"
python = ">=3.11"
matplotlib = ">=3.9"
ipympl = ">=0.9"
jupytext = ">=1.16"

[feature.jupyterlite-host]
channels = ["conda-forge"]
platforms = ["linux-64", "osx-64", "osx-arm64", "win-64"]

[feature.jupyterlite-host.dependencies]
jupyterlab = "~=4.2.4"
jupyterlite-core = "==0.4.0"
jupyterlite-pyodide-kernel = "==0.4.1"
jupyterlite-xeus = "*"
notebook = "~=7.2.1"
jupyterlab-myst = ">=2.4"
jupytext = ">=1.16"
ipympl = ">=0.9"

[feature.jupyterlite-host.tasks]
setup_wasm = {cmd = "pixi install -e jupyterlite-runtime", inputs = ["pixi.lock"]}
convert_ipynbs = {cmd = "bash convert_all_jupyterlite.sh", inputs = ["tutorials/"], outputs = ["_build/ipynbs"]}

[feature.jupyterlite-host.tasks.build_wasm]
cmd = "jupyter lite build --XeusAddon.prefix=.pixi/envs/jupyterlite-runtime --contents _build/ipynbs/tutorials --output-dir _build/html/jupyterlite --settings-overrides=.binder/overrides.json --log-level DEBUG"
depends-on = ["setup_wasm", "convert_ipynbs"]
outputs = ["_build/html/jupyterlite/"]
inputs = ["pixi.lock", "tutorials/"]

[feature.jupyterlite-host.tasks.start_wasm]
cmd = "python -m http.server 8000 -d _build/html/jupyterlite/"
depends-on = ["build_wasm"]

[environments]
py312 = ["py312"]
py313 = ["py313"]
jupyterlite = ["jupyterlite"]
default = ["base"]
py312 = ["base", "py312"]
py313 = ["base", "py313"]
jupyterlite-runtime = ["jupyterlite-runtime"]
jupyterlite-host = ["jupyterlite-host"]