Skip to content

Commit 65b3ac5

Browse files
authored
Merge 74c40c1 into d423263
2 parents d423263 + 74c40c1 commit 65b3ac5

8 files changed

Lines changed: 656 additions & 88 deletions

File tree

.github/workflows/execute.yaml

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Execute notebooks
22

33
on:
44
schedule:
5-
# Weekly: Mondays 04:00 UTC re-executes ALL notebooks against latest releases.
5+
# Weekly: Mondays 04:00 UTC; re-executes ALL notebooks against latest releases.
66
- cron: "0 4 * * 1"
77
pull_request:
88
branches: [main]
@@ -22,36 +22,45 @@ jobs:
2222
timeout-minutes: 60
2323
steps:
2424
- uses: actions/checkout@v5
25-
with:
26-
# Need full history so we can diff PR HEAD against the merge base.
27-
fetch-depth: 0
2825

2926
- uses: actions/setup-python@v5
3027
with:
3128
python-version: "3.13"
29+
cache: pip
30+
cache-dependency-path: pyproject.toml
3231

3332
- name: Cache pooch datasets
3433
uses: actions/cache@v4
3534
with:
3635
path: ~/.cache/pooch
37-
key: pooch-${{ runner.os }}-${{ hashFiles('**/*.ipynb') }}
36+
# Datasets are pinned by URL inside notebook code, not by the
37+
# notebook's surrounding markdown — bump the v* suffix when an
38+
# actually-new dataset URL lands.
39+
key: pooch-${{ runner.os }}-v1
3840
restore-keys: |
3941
pooch-${{ runner.os }}-
4042
4143
- name: Install execution environment
4244
run: |
4345
pip install --upgrade pip
44-
pip install -e ".[exec]" nbdime
46+
pip install -e ".[exec]"
47+
48+
- name: Detect changed notebooks (PR only)
49+
if: github.event_name == 'pull_request'
50+
id: changed
51+
uses: tj-actions/changed-files@v45
52+
with:
53+
files: |
54+
tutorials/**/*.ipynb
55+
examples/**/*.ipynb
4556
4657
- name: Determine notebooks to execute
4758
id: pick
4859
run: |
49-
# On the weekly schedule and manual dispatch, run all notebooks.
50-
# On PR, run only notebooks the PR touched, to keep CI fast as the
51-
# gallery grows. (sklearn does the same.)
5260
if [ "${{ github.event_name }}" = "pull_request" ]; then
53-
base="${{ github.event.pull_request.base.sha }}"
54-
nbs=$(git diff --name-only --diff-filter=AMR "$base"...HEAD -- '*.ipynb' | grep -E '^(tutorials|examples)/' || true)
61+
nbs="${{ steps.changed.outputs.all_changed_files }}"
62+
# tj-actions emits space-separated; one-per-line for the loop below.
63+
nbs=$(printf '%s\n' $nbs)
5564
else
5665
nbs=$(find tutorials examples -name "*.ipynb" -not -path "*/.ipynb_checkpoints/*" 2>/dev/null || true)
5766
fi
@@ -75,15 +84,3 @@ jobs:
7584
echo "Executing $nb"
7685
jupyter nbconvert --to notebook --execute --inplace "$nb"
7786
done <<< "${{ steps.pick.outputs.files }}"
78-
79-
- name: Diff outputs against committed
80-
if: steps.pick.outputs.files != ''
81-
run: |
82-
# If outputs drift from what's committed, fail the job. Authors are
83-
# expected to commit re-executed notebooks; CI catches drift between
84-
# commits (e.g., upstream lib changes).
85-
if ! git diff --quiet -- '*.ipynb'; then
86-
echo "Notebook outputs drifted from committed state:"
87-
nbdime diff
88-
exit 1
89-
fi

.github/workflows/preview.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ jobs:
3333
with:
3434
repository: scverse/spatialdata-plot
3535
path: lib
36-
fetch-depth: 0
3736

3837
- name: Mount PR notebooks into lib's submodule path
3938
run: |
@@ -69,7 +68,10 @@ jobs:
6968
const pr = context.issue.number;
7069
const owner = context.repo.owner;
7170
const repo = context.repo.repo;
72-
const url = `https://${owner}.github.io/${repo}/pr-${pr}/gallery.html`;
71+
// Use the canonical scverse.org URL directly. The github.io URL
72+
// 301-redirects there because of the org-wide CNAME, which makes
73+
// the displayed link confusingly different from the destination.
74+
const url = `https://scverse.org/${repo}/pr-${pr}/gallery.html`;
7375
const marker = '<!-- preview-link -->';
7476
const body = `${marker}\n📖 **Docs preview**: ${url}\n\n_Built from ${context.sha.substring(0, 7)}; redeployed on every push._`;
7577
const { data: comments } = await github.rest.issues.listComments({ owner, repo, issue_number: pr });

.pre-commit-config.yaml

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,27 @@
1+
# pre-commit config. Auto-run on PRs by pre-commit.ci (see ci: block below);
2+
# run locally with `pre-commit run --all-files` after `pip install pre-commit`.
3+
4+
ci:
5+
# Auto-fix PRs where possible; tag the commit so it's clearly bot-authored.
6+
autofix_commit_msg: |
7+
[pre-commit.ci] auto fixes from pre-commit.com hooks
8+
9+
for more information, see https://pre-commit.ci
10+
autofix_prs: true
11+
autoupdate_branch: ""
12+
autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate"
13+
autoupdate_schedule: monthly
14+
skip: []
15+
submodules: false
16+
117
fail_fast: false
218
default_language_version:
319
python: python3
420
minimum_pre_commit_version: 3.0.0
521

622
repos:
723
- repo: https://github.com/pre-commit/pre-commit-hooks
8-
rev: v5.0.0
24+
rev: v6.0.0
925
hooks:
1026
- id: check-yaml
1127
- id: check-toml
@@ -20,14 +36,26 @@ repos:
2036
exclude: \.ipynb$
2137

2238
- repo: https://github.com/astral-sh/ruff-pre-commit
23-
rev: v0.7.4
39+
rev: v0.15.12
2440
hooks:
25-
- id: ruff
41+
- id: ruff-check
2642
args: [--fix]
2743
- id: ruff-format
44+
# Notebook cells use a chained fluent API; ruff-format collapses
45+
# short chains onto one line which hurts readability. Lint notebooks
46+
# via nbqa-ruff (below) instead.
47+
exclude: \.ipynb$
2848

2949
- repo: https://github.com/nbQA-dev/nbQA
30-
rev: 1.9.0
50+
rev: 1.9.1
3151
hooks:
3252
- id: nbqa-ruff
3353
args: [--fix]
54+
55+
- repo: local
56+
hooks:
57+
- id: strip-widget-metadata
58+
name: Strip Jupyter widget metadata from notebooks
59+
entry: python scripts/strip_widget_metadata.py
60+
language: system
61+
files: \.ipynb$

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ exec = [
2020
"squidpy",
2121
"jupyter",
2222
"ipykernel",
23+
"watermark",
2324
]
2425
dev = [
2526
"pre-commit>=3.0",

scripts/strip_widget_metadata.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env python3
2+
"""Strip Jupyter widget metadata + outputs from .ipynb files.
3+
4+
Anything using `tqdm.notebook` (pooch downloads, scanpy progress bars in a
5+
Jupyter kernel) emits widget output blobs whose UUIDs regenerate on every
6+
execution. Stripping them keeps committed notebooks small and produces
7+
clean PR diffs that reflect real source changes only.
8+
9+
Usage: strip_widget_metadata.py <notebook> [<notebook> ...]
10+
Exits 0 if no changes, 1 if files were modified (so pre-commit reports the
11+
fix the way other auto-fixers do).
12+
"""
13+
14+
from __future__ import annotations
15+
16+
import json
17+
import sys
18+
from pathlib import Path
19+
20+
WIDGET_MIME = "application/vnd.jupyter.widget-view+json"
21+
22+
23+
def strip(path: Path) -> bool:
24+
nb = json.loads(path.read_text())
25+
changed = False
26+
27+
if "widgets" in nb.get("metadata", {}):
28+
nb["metadata"].pop("widgets")
29+
changed = True
30+
31+
for cell in nb.get("cells", []):
32+
for output in cell.get("outputs", []):
33+
data = output.get("data", {})
34+
if WIDGET_MIME in data:
35+
data.pop(WIDGET_MIME)
36+
changed = True
37+
38+
if changed:
39+
path.write_text(json.dumps(nb, indent=1) + "\n")
40+
return changed
41+
42+
43+
def main() -> int:
44+
if len(sys.argv) < 2:
45+
print("usage: strip_widget_metadata.py <notebook> [<notebook> ...]", file=sys.stderr)
46+
return 2
47+
any_changed = False
48+
for arg in sys.argv[1:]:
49+
if strip(Path(arg)):
50+
print(f"stripped widgets: {arg}")
51+
any_changed = True
52+
return 1 if any_changed else 0
53+
54+
55+
if __name__ == "__main__":
56+
sys.exit(main())

tutorials/getting_started.ipynb

Lines changed: 113 additions & 59 deletions
Large diffs are not rendered by default.

tutorials/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ spatial elements, and styling a publication-ready figure.
88
:maxdepth: 1
99
1010
getting_started
11+
visium_mouse_brain
1112
```

tutorials/visium_mouse_brain.ipynb

Lines changed: 429 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)