Skip to content

Commit d58f2a0

Browse files
authored
Merge pull request #3 from PhilHem/feature/workshop-updates
Add workshop environment setup and configuration files
2 parents 8220ead + 223bf14 commit d58f2a0

File tree

6 files changed

+2603
-0
lines changed

6 files changed

+2603
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Test Environment
2+
3+
on:
4+
push:
5+
paths:
6+
- "pyproject.toml"
7+
- "uv.lock"
8+
pull_request:
9+
paths:
10+
- "pyproject.toml"
11+
- "uv.lock"
12+
13+
jobs:
14+
test-environment:
15+
runs-on: ubuntu-latest
16+
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v4
20+
21+
- name: Install uv
22+
uses: astral-sh/setup-uv@v3
23+
with:
24+
version: "latest"
25+
26+
- name: Set up Python
27+
run: uv python install 3.8
28+
29+
- name: Install dependencies
30+
run: uv sync
31+
32+
- name: Test notebook imports
33+
run: uv run python scripts/test_environment.py
34+
35+
- name: Verify notebooks can be parsed
36+
run: |
37+
echo "Checking that all notebooks can be parsed..."
38+
for notebook in *.ipynb; do
39+
echo "Parsing $notebook..."
40+
uv run python -c "import nbformat; nbformat.read('$notebook', as_version=4)"
41+
done
42+
echo "✅ All notebooks parsed successfully"

.gitignore

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Python
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
*.so
6+
.Python
7+
build/
8+
develop-eggs/
9+
dist/
10+
downloads/
11+
eggs/
12+
.eggs/
13+
lib/
14+
lib64/
15+
parts/
16+
sdist/
17+
var/
18+
wheels/
19+
*.egg-info/
20+
.installed.cfg
21+
*.egg
22+
23+
# Virtual environments
24+
.env
25+
.venv
26+
env/
27+
venv/
28+
ENV/
29+
env.bak/
30+
venv.bak/
31+
32+
# uv
33+
.uv/
34+
35+
# Jupyter Notebook
36+
.ipynb_checkpoints
37+
38+
# IPython
39+
profile_default/
40+
ipython_config.py
41+
42+
# pyenv
43+
.python-version
44+
45+
# IDE
46+
.vscode/
47+
.idea/
48+
*.swp
49+
*.swo
50+
51+
# OS
52+
.DS_Store
53+
Thumbs.db
54+
55+
# Workshop specific
56+
test.py # Created by teaching examples
57+
worktrees.json
58+
.history/

README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,39 @@
22

33
# Workshop Parallel Jupyter
44

5+
## Quick Start
6+
7+
This workshop uses a modern Python environment managed with `uv`. To get started:
8+
9+
1. **Install uv** (if not already installed):
10+
```bash
11+
curl -LsSf https://astral.sh/uv/install.sh | sh
12+
```
13+
14+
2. **Set up the environment**:
15+
```bash
16+
uv sync
17+
```
18+
19+
3. **Test the environment**:
20+
```bash
21+
uv run python scripts/test_environment.py
22+
```
23+
24+
4. **Start Jupyter**:
25+
```bash
26+
uv run jupyter lab
27+
```
28+
29+
## Environment Testing
30+
31+
The environment is automatically tested via GitHub Actions whenever dependencies change. You can also test locally:
32+
33+
- **Test all imports**: `uv run python scripts/test_environment.py`
34+
- **Verify notebooks**: All notebooks are automatically validated for syntax
35+
36+
## Prerequisites
37+
538
Participants must have already completed these basics:
639
* Functioning user account on [bwUniCluster](https://wiki.bwhpc.de/e/Category:BwUniCluster_2.0), i.e.
740
* bwIDM entitlement 'bwUniCluster' of your home institution

pyproject.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[project]
2+
name = "1761731486678-8220ea"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.8,<3.9"
7+
dependencies = [
8+
"bokeh>=2.4.0",
9+
"bottleneck>=1.3.0",
10+
"dask>=2021.10.0",
11+
"dask-jobqueue>=0.8.5",
12+
"dask-ml>=2024.4.4",
13+
"distributed>=2021.10.0",
14+
"graphviz>=0.16.0",
15+
"ipykernel>=6.4.0",
16+
"ipython>=7.29.0",
17+
"jupyter>=1.0.0",
18+
"matplotlib>=3.4.0",
19+
"mpi4py>=3.0.0",
20+
"numba>=0.53.0",
21+
"numpy>=1.21.0",
22+
"pandas>=1.3.0",
23+
"pyarrow>=4.0.0",
24+
"s3fs>=2021.7.0",
25+
"scikit-learn>=1.0.0",
26+
"scipy>=1.7.0",
27+
"seaborn>=0.11.0",
28+
]
29+
30+
[dependency-groups]
31+
dev = ["nbconvert>=7.16.6", "pytest>=8.3.5", "pytest-html>=4.1.1"]

scripts/test_environment.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
"""Quick test to verify notebook imports work."""
3+
4+
import sys
5+
from pathlib import Path
6+
import nbformat
7+
8+
9+
def main():
10+
print("🔍 Testing notebook imports...")
11+
12+
# Get all notebooks
13+
notebooks = [f for f in Path(".").glob("*.ipynb") if not f.name.startswith("test_")]
14+
15+
# Extract and test imports
16+
all_imports = set()
17+
for nb in notebooks:
18+
try:
19+
with open(nb, "r") as f:
20+
nb_data = nbformat.read(f, as_version=4)
21+
for cell in nb_data.cells:
22+
if cell.cell_type == "code":
23+
for line in cell.source.split("\n"):
24+
line = line.strip()
25+
if line.startswith(
26+
("import ", "from ")
27+
) and not line.startswith("#"):
28+
all_imports.add(line.split("#")[0].strip())
29+
except Exception as e:
30+
print(f"❌ Error reading {nb.name}: {e}")
31+
return False
32+
33+
# Test imports
34+
failed = []
35+
for imp in sorted(all_imports):
36+
if imp.strip() == "import test": # Skip teaching example
37+
continue
38+
try:
39+
exec(imp)
40+
print(f"✅ {imp}")
41+
except Exception as e:
42+
print(f"❌ {imp}: {e}")
43+
failed.append(imp)
44+
45+
if failed:
46+
print(f"\n{len(failed)} imports failed")
47+
return False
48+
else:
49+
print(f"\n🎉 All {len(all_imports)} imports work!")
50+
return True
51+
52+
53+
if __name__ == "__main__":
54+
sys.exit(0 if main() else 1)

0 commit comments

Comments
 (0)