Skip to content

Commit 564b49c

Browse files
committed
Copy danielballan/interactive-tutorial-demo
1 parent ecf32fa commit 564b49c

21 files changed

+5361
-173
lines changed

.binder/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
numpy

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# GitHub syntax highlighting
2+
pixi.lock linguist-language=YAML linguist-generated=true

.github/workflows/cd.yml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
name: Publish
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
schedule:
9+
- cron: '0 5 * * 1'
10+
# Allows you to run this workflow manually from the Actions tab
11+
workflow_dispatch:
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
19+
build:
20+
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
21+
name: Build Jupyter Notebooks and HTML
22+
runs-on: ubuntu-latest
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Setup GitHub Pages
28+
uses: actions/configure-pages@v5
29+
30+
- name: Setup pixi
31+
uses: prefix-dev/setup-pixi@v0.8.8
32+
with:
33+
cache: true
34+
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
35+
36+
- name: Build executed notebooks and HTML
37+
run: pixi run build
38+
39+
- name: Upload executed notebooks as GitHub artifact
40+
uses: actions/upload-artifact@v4
41+
with:
42+
name: executed-notebooks
43+
path: build/jupyter_execute/recipes
44+
if-no-files-found: error
45+
46+
- name: Prepare for Jupyter Lite
47+
run: |
48+
cp README.md docs/recipes/
49+
# Convert Jupytext to ipynb format.
50+
pixi run ./convert_all.sh ipynb
51+
52+
- name: Build Jupyter Lite
53+
run: pixi run -e jupyterlite jupyter lite build --contents docs/recipes --output-dir build/html/jupyterlite
54+
55+
- name: Upload HTML as GitHub artifact
56+
uses: actions/upload-pages-artifact@v3
57+
with:
58+
path: build/html
59+
60+
deploy-gh-pages:
61+
name: Deploy HTML to GitHub Pages
62+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
63+
permissions:
64+
contents: read
65+
pages: write
66+
id-token: write
67+
68+
environment:
69+
name: github-pages
70+
url: ${{ steps.deployment.outputs.page_url }}
71+
runs-on: ubuntu-latest
72+
needs: build
73+
steps:
74+
- name: Deploy HTML to GitHub Pages
75+
id: deployment
76+
uses: actions/deploy-pages@v4
77+
78+
deploy-notebooks:
79+
name: Push to 'notebooks' branch ipynb-formatted version
80+
# Sets permissions of the GITHUB_TOKEN to allow pushing to 'notebooks' branch
81+
permissions:
82+
contents: write
83+
runs-on: ubuntu-latest
84+
needs: build
85+
steps:
86+
87+
- name: Checkout
88+
uses: actions/checkout@v4
89+
90+
- name: Setup pixi
91+
uses: prefix-dev/setup-pixi@v0.8.1
92+
93+
- name: Publish ipynb-formatted variant to 'notebooks' branch of this repo
94+
run: |
95+
git fetch origin
96+
git checkout -B notebooks
97+
git config user.name "github-actions[bot]"
98+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
99+
pixi run ./convert_all.sh ipynb
100+
git add .
101+
git commit -am "Convert jupytext to ipynb format"
102+
git push origin notebooks --force-with-lease

.github/workflows/ci.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
name: Test notebooks
3+
4+
on:
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
schedule:
12+
- cron: '0 5 * * 1'
13+
workflow_dispatch:
14+
15+
jobs:
16+
test:
17+
name: Test all executable examples
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout
21+
uses: actions/checkout@v4
22+
23+
- name: Setup pixi
24+
uses: prefix-dev/setup-pixi@v0.8.1
25+
26+
- name: Test all files
27+
run: pixi run ./test.sh --all

.gitignore

Lines changed: 2 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -1,174 +1,3 @@
1-
# Byte-compiled / optimized / DLL files
2-
__pycache__/
3-
*.py[cod]
4-
*$py.class
5-
6-
# C extensions
7-
*.so
8-
9-
# Distribution / packaging
10-
.Python
11-
build/
12-
develop-eggs/
13-
dist/
14-
downloads/
15-
eggs/
16-
.eggs/
17-
lib/
18-
lib64/
19-
parts/
20-
sdist/
21-
var/
22-
wheels/
23-
share/python-wheels/
24-
*.egg-info/
25-
.installed.cfg
26-
*.egg
27-
MANIFEST
28-
29-
# PyInstaller
30-
# Usually these files are written by a python script from a template
31-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32-
*.manifest
33-
*.spec
34-
35-
# Installer logs
36-
pip-log.txt
37-
pip-delete-this-directory.txt
38-
39-
# Unit test / coverage reports
40-
htmlcov/
41-
.tox/
42-
.nox/
43-
.coverage
44-
.coverage.*
45-
.cache
46-
nosetests.xml
47-
coverage.xml
48-
*.cover
49-
*.py,cover
50-
.hypothesis/
51-
.pytest_cache/
52-
cover/
53-
54-
# Translations
55-
*.mo
56-
*.pot
57-
58-
# Django stuff:
59-
*.log
60-
local_settings.py
61-
db.sqlite3
62-
db.sqlite3-journal
63-
64-
# Flask stuff:
65-
instance/
66-
.webassets-cache
67-
68-
# Scrapy stuff:
69-
.scrapy
70-
71-
# Sphinx documentation
72-
docs/_build/
73-
74-
# PyBuilder
75-
.pybuilder/
76-
target/
77-
78-
# Jupyter Notebook
1+
/build/*
792
.ipynb_checkpoints
80-
81-
# IPython
82-
profile_default/
83-
ipython_config.py
84-
85-
# pyenv
86-
# For a library or package, you might want to ignore these files since the code is
87-
# intended to run in multiple environments; otherwise, check them in:
88-
# .python-version
89-
90-
# pipenv
91-
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92-
# However, in case of collaboration, if having platform-specific dependencies or dependencies
93-
# having no cross-platform support, pipenv may install dependencies that don't work, or not
94-
# install all needed dependencies.
95-
#Pipfile.lock
96-
97-
# UV
98-
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
99-
# This is especially recommended for binary packages to ensure reproducibility, and is more
100-
# commonly ignored for libraries.
101-
#uv.lock
102-
103-
# poetry
104-
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
105-
# This is especially recommended for binary packages to ensure reproducibility, and is more
106-
# commonly ignored for libraries.
107-
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
108-
#poetry.lock
109-
110-
# pdm
111-
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
112-
#pdm.lock
113-
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
114-
# in version control.
115-
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
116-
.pdm.toml
117-
.pdm-python
118-
.pdm-build/
119-
120-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
121-
__pypackages__/
122-
123-
# Celery stuff
124-
celerybeat-schedule
125-
celerybeat.pid
126-
127-
# SageMath parsed files
128-
*.sage.py
129-
130-
# Environments
131-
.env
132-
.venv
133-
env/
134-
venv/
135-
ENV/
136-
env.bak/
137-
venv.bak/
138-
139-
# Spyder project settings
140-
.spyderproject
141-
.spyproject
142-
143-
# Rope project settings
144-
.ropeproject
145-
146-
# mkdocs documentation
147-
/site
148-
149-
# mypy
150-
.mypy_cache/
151-
.dmypy.json
152-
dmypy.json
153-
154-
# Pyre type checker
155-
.pyre/
156-
157-
# pytype static type analyzer
158-
.pytype/
159-
160-
# Cython debug symbols
161-
cython_debug/
162-
163-
# PyCharm
164-
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
165-
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
166-
# and can be added to the global gitignore or merged into this file. For a more nuclear
167-
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
168-
#.idea/
169-
170-
# Ruff stuff:
171-
.ruff_cache/
172-
173-
# PyPI configuration file
174-
.pypirc
3+
/pixi/*

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Interactive Tutorial Demo
2+
3+
A repository demonstrating one way to manage and distribute interactive tutorials.
4+
See the [Guide to Contributing](https://danielballan.github.io/interactive-tutorial-demo/contributing.html)
5+
for a good overview of what this is like to use.
6+
7+
## Demo Links
8+
9+
- **[Tutorials (a.k.a. recipes)](https://github.com/danielballan/interactive-tutorial-demo/tree/notebooks/docs/recipes)** are written in MyST Markdown.
10+
- They are published in **[Jupyter notebook](https://github.com/danielballan/interactive-tutorial-demo/tree/notebooks/docs/recipes)** format, on the `notebooks` branch of this repo, which can be used in Colab, Binder, etc.
11+
- Executed examples are **[published](https://danielballan.github.io/interactive-tutorial-demo/)** on a GitHub Pages site.
12+
- **[Jupyter Lite (beta)](https://danielballan.github.io/interactive-tutorial-demo/jupyterlite/lab/index.html)** (works only on the basic executable example so far, missing dependencies for others)
13+
- **[Binder](https://mybinder.org/v2/gh/danielballan/interactive-tutorial-demo/notebooks)**
14+
15+
16+
## Goals
17+
18+
- Make content easy to explore and try in a variety of modes:
19+
- interactive and non-interactive
20+
- local and cloud-based
21+
- Jupyter and not-Jupyter
22+
- Document an accessible development workflow, so that non-experts can contribute.
23+
- Keep the infrastructure as simple as possible.
24+
25+
## To Do
26+
27+
- Test notebook execution _of changed recipes only_ in CI on PR.
28+
- Set up devcontainer.
29+
- Add example with additional dependencies.
30+
31+
## Prior Art
32+
33+
Examples that this is drawing from:
34+
35+
- https://github.com/bsipocz/irsa-tutorials
36+
- https://github.com/MotherDuck-Open-Source/sql-tutorial

convert_all.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
3+
# If no arguments were provided, exit with error and show usage.
4+
if [ $# -eq 0 ]; then
5+
echo "Usage: $0 md | ipynb " >&2
6+
exit 1
7+
fi
8+
9+
# Variable to track if any errors occur
10+
error_occurred=0
11+
12+
if [ "$1" = "ipynb" ]; then
13+
files=$(find docs/recipes/ -name "*.md" | grep -v .ipynb_checkpoints)
14+
for file in $files; do
15+
# Extract the kernel information from the Jupytext Markdown file
16+
kernel_info=$(grep -A 10 '^---$' "$file" | grep -E 'kernelspec')
17+
# Skip if no kernel information was found
18+
if [ -z "$kernel_info" ]; then
19+
continue
20+
fi
21+
jupytext --to ipynb "$file" && rm "$file"
22+
if [ $? -ne 0 ]; then
23+
error_occurred=1
24+
echo "Errors when converting $file"
25+
else
26+
echo "Converted $file"
27+
fi
28+
done
29+
elif [ "$1" = "md" ]; then
30+
files=$(find docs/recipes/ -name "*.ipynb" | grep -v .ipynb_checkpoints)
31+
for file in $files; do
32+
jupytext --to markdown "$file" && rm "$file"
33+
if [ $? -ne 0 ]; then
34+
error_occurred=1
35+
echo "Errors when converting $file"
36+
else
37+
echo "Converted $file"
38+
fi
39+
done
40+
fi
41+
42+
if [ $error_occurred -ne 0 ]; then
43+
echo "Some files failed to convert." >&2
44+
exit 1
45+
else
46+
echo "All files converted successfully." >&2
47+
exit 0
48+
fi
49+
Loading

0 commit comments

Comments
 (0)