Python notebooks running in a reproducible environment managed by uv, pinned to Python 3.13. Notebook outputs are stripped automatically on commit via nbstripout, keeping diffs clean.
notebooks/— all analysis notebooks (outputs are stripped on commit; run them to reproduce results)data/— local datasets and download caches (gitignored); notebooks reference it as../datascripts/— data-fetching scripts (seescripts/README.md)sql/— queries behind the datasets (seedocs/dataset.md)
Requires Docker + an editor with Dev Containers support (VS Code "Dev Containers"
extension, or any tool that reads .devcontainer/).
- Open the folder and Reopen in Container when prompted.
- The container builds, then
postCreateCommandrunsuv sync(installs Python 3.13 and the dependencies fromuv.lock) andnbstripout --install(wires up the git filters). - Open
notebooks/example.ipynband select the.venvinterpreter to run cells.
No host Python is needed — uv inside the container provides it.
With uv installed on your machine:
uv sync # creates .venv with Python 3.13 + dependencies
uv run nbstripout --install # enable output stripping for this clone (one-time)Run JupyterLab with uv run jupyter lab, or point your editor at .venv/bin/python.
uv add pandas # add a dependency (updates pyproject.toml + uv.lock)
uv run jupyter lab # launch JupyterLab
uv run python script.py # run anything inside the environmentCommit pyproject.toml, uv.lock, and .python-version so the environment stays
reproducible for everyone.
nbstripout --install sets up git filters (stored in .git/config, which is not
committed), so each fresh clone needs it run once — the dev container does this
automatically. The matching *.ipynb filter=nbstripout rules live in the committed
.gitattributes. To check it's active: uv run nbstripout --status.