Skip to content

Commit 0c5d91c

Browse files
committed
Switch to JupyterLite from BinderHub
1 parent 32113af commit 0c5d91c

File tree

8 files changed

+89
-3
lines changed

8 files changed

+89
-3
lines changed

.github/workflows/book.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
# Build the page
4848
- name: Build the book
4949
run: |
50-
make html
50+
make web
5151
5252
- uses: actions/upload-artifact@v4
5353
if: failure()

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ _references.bib
1010
*.ipynb
1111
*.orig
1212
node_modules/
13+
.jupyterlite.doit.db

Makefile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
PYTHON ?= python
22
PIP_INSTALL_CMD ?= $(PYTHON) -m pip install
33
BUILD_DIR=_build/html
4+
JL_DIR=_build/jl
45

56
html:
67
# Check for ipynb files in source (should all be .Rmd).
78
if compgen -G "*.ipynb" 2> /dev/null; then (echo "ipynb files" && exit 1); fi
89
jupyter-book build -W .
910
$(PYTHON) _scripts/make_redirects.py
1011

11-
github: html
12+
jl:
13+
# Jupyter-lite files for book build.
14+
$(PIP_INSTALL_CMD) -r jl-build-requirements.txt
15+
rm -rf $(JL_DIR)
16+
mkdir $(JL_DIR)
17+
cp -r data images $(JL_DIR)
18+
$(PYTHON) _scripts/process_notebooks.py . $(JL_DIR)
19+
$(PYTHON) -m jupyter lite build \
20+
--contents $(JL_DIR) \
21+
--output-dir $(BUILD_DIR)/interact \
22+
--lite-dir $(JL_DIR)
23+
24+
web: html jl
25+
26+
github: web
1227
ghp-import -n _build/html -p -f
1328

1429
clean: rm-ipynb

_config.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ launch_buttons:
4444
# Example jupyterhub link:
4545
# https://ds.lis.2i2c.cloud/hub/user-redirect/git-pull?repo=https%3A//github.com/lisds/textbook&urlpath=lab/tree/textbook/code-basics/variables_intro.Rmd&branch=main
4646
# The URL of the BinderHub (e.g., https://mybinder.org)
47-
binderhub_url: "https://mybinder.org"
47+
# binderhub_url: "https://mybinder.org"
48+
# Jupyterlite URL
49+
jupyterlite_url: "interact/lab/index.html"
50+
# Extension (if different from source file).
51+
jupyterlite_ext: ".ipynb"
52+
# Example jupyterlite link:
53+
# https://odsti.github.io/cfd-textbook/interact/lab/index.html?path=variables_intro.ipynb
4854
# The URL of Google Colab (e.g., https://colab.research.google.com)
4955
# colab_url: "https://colab.research.google.com"
5056
# thebe: true

_scripts/process_notebooks.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#!/usr/bin/env python3
2+
""" Process notebooks
3+
4+
* Replace local kernel with Pyodide kernel in metadata.
5+
* Write notebooks to output directory.
6+
* Write JSON jupyterlite file.
7+
"""
8+
9+
from argparse import ArgumentParser, RawDescriptionHelpFormatter
10+
from pathlib import Path
11+
12+
import jupytext
13+
14+
_JL_JSON_FMT = r'''\
15+
{{
16+
"jupyter-lite-schema-version": 0,
17+
"jupyter-config-data": {{
18+
"contentsStorageName": "rss-{language}"
19+
}}
20+
}}
21+
'''
22+
23+
def process_dir(input_dir, output_dir, in_nb_suffix='.Rmd',
24+
kernel_name='python',
25+
kernel_dname='Python (Pyodide)',
26+
out_nb_suffix='.ipynb'
27+
):
28+
output_dir.mkdir(exist_ok=True, parents=True)
29+
for path in input_dir.glob('*' + in_nb_suffix):
30+
nb = jupytext.read(path)
31+
nb['metadata']['kernelspec'] = {
32+
'name': kernel_name,
33+
'display_name': kernel_dname}
34+
jupytext.write(nb, output_dir / (path.stem + out_nb_suffix))
35+
36+
37+
def get_parser():
38+
parser = ArgumentParser(description=__doc__, # Usage from docstring
39+
formatter_class=RawDescriptionHelpFormatter)
40+
parser.add_argument('input_dir',
41+
help='Directory containing input notebooks')
42+
parser.add_argument('output_dir',
43+
help='Directory to which we will output notebooks')
44+
return parser
45+
46+
47+
def main():
48+
parser = get_parser()
49+
args = parser.parse_args()
50+
out_path = Path(args.output_dir)
51+
process_dir(Path(args.input_dir), out_path)
52+
(out_path / 'jupyter-lite.json').write_text(
53+
_JL_JSON_FMT.format(language='python'))
54+
55+
56+
if __name__ == '__main__':
57+
main()

build_requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Build requirements
22
-r requirements.txt
3+
sphinx-book-theme@git+https://github.com/matthew-brett/sphinx-book-theme@jupyterlite-links
34
-e .
45
jupyter-book
56
jupytext

jl-build-requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Build requirements
2+
-r requirements.txt
3+
jupyterlite-core
4+
jupyterlite-pyodide-kernel
5+
jupyterlab_server

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ dependencies = [
4141
'statsmodels',
4242
'sqlalchemy',
4343
'jupyter_server',
44+
'sphinx-book-theme@git+https://github.com/matthew-brett/sphinx-book-theme@jupyterlite-links',
4445
'jupyter-book',
4546
'jupytext',
4647
'oktools',

0 commit comments

Comments
 (0)