Skip to content
Merged
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
24 changes: 7 additions & 17 deletions scripts/build_notebooks.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,27 @@
#!/usr/bin/env python3
"""
Execute all notebooks in the repository (recursive) and export them to
HTML into an output folder.
Execute all notebooks in the repository (recursive) and export them to HTML into an output folder.

Usage:
python scripts/build_notebooks.py <output_dir> [--timeout SECONDS]

By default this will search for all .ipynb files (excluding
.ipynb_checkpoints) and:
By default this will search for all .ipynb files (excluding .ipynb_checkpoints) and:
- execute them with a timeout
- export resulting notebook to HTML and place the HTML in <output_dir>
preserving folder structure
- export resulting notebook to HTML and place the HTML in <output_dir> preserving folder structure
"""
import sys
import subprocess
from pathlib import Path


def find_notebooks(root="."):
nbs = []
for p in Path(root).rglob("*.ipynb"):
# skip checkpoints and files inside .git or site output
if (".ipynb_checkpoints" in p.parts or "site" in p.parts or
"gh-pages" in p.parts):
if (".ipynb_checkpoints" in p.parts or "site" in p.parts or "gh-pages" in p.parts):
continue
nbs.append(p)
return nbs


def main():
if len(sys.argv) < 2:
print("Usage: build_notebooks.py <output_dir> [--timeout SECONDS]")
Expand All @@ -49,16 +43,14 @@ def main():
print(f"Found {len(notebooks)} notebooks. Exporting to {outdir} ...")
for nb in notebooks:
# Handle both absolute and relative paths
if nb.is_absolute():
try:
rel = nb.relative_to(Path.cwd())
else:
except Exception:
rel = nb
target_dir = outdir.joinpath(rel.parent)
target_dir.mkdir(parents=True, exist_ok=True)
print(f"Processing {nb} -> {target_dir}")

# Execute notebook in place into a temp file and convert to HTML
# Use nbconvert CLI to execute and export; capture exit code
try:
subprocess.check_call([
sys.executable, "-m", "jupyter", "nbconvert",
Expand All @@ -70,8 +62,6 @@ def main():
])
except subprocess.CalledProcessError as e:
print(f"ERROR executing {nb}: {e}")
# Create a placeholder HTML with the failure message so
# CI pages report which notebooks failed
fail_html = target_dir.joinpath(nb.stem + ".html")
with open(fail_html, "w", encoding="utf-8") as fh:
error_msg = (
Expand All @@ -83,4 +73,4 @@ def main():


if __name__ == "__main__":
main()
main()
Loading