Skip to content

Python notebook environments with uv

Use a separate Python environment for an analysis when its notebooks need their own package versions. The uv prototype creates an environment in your analysis folder and registers it as a kernel you can select in JupyterLab. Several notebooks in the same folder can share that environment.

Open a Terminal in Neurodesktop’s JupyterLab and run the commands as your normal notebook user, without sudo. You need a recent Neurodesktop image with uv, the image’s Python, and the Neurodesk kernel wrapper:

Terminal window
neurodesk-uv --help
uv --version

If a check fails, use a newer Neurodesktop image before trying the prototype. The helper uses the image’s Python automatically. Initial setup and installing new packages need access to the package index.

Choose a folder on persistent storage. Use an analysis subfolder, such as ~/analyses/demo, rather than your home directory or the root of a mounted drive. The prototype refuses existing unmanaged .venv directories and projects inside uv workspaces; start with a fresh analysis folder for your first trial.

Create an environment and select its kernel

Section titled “Create an environment and select its kernel”
Terminal window
mkdir -p "$HOME/analyses/demo"
neurodesk-uv init "$HOME/analyses/demo"

This creates or updates:

  • pyproject.toml, which declares the project’s dependencies.
  • uv.lock, which records the resolved package versions.
  • .venv, which contains the project’s Python environment.
  • .neurodesk_uv_prototype.json, a local ownership record beside .venv.
  • A user kernel registration named Python (uv prototype: demo).

The helper records ipykernel as a development dependency. A new project uses version 6.31.0, the compatibility version selected for this prototype. Running init again reuses the registration rather than creating a duplicate. Existing projects without uv.lock get a lockfile, including projects that already declare ipykernel.

Open or create a notebook in the analysis folder. Click its kernel name and select Python (uv prototype: demo). If it is not listed, reload JupyterLab and reopen the kernel selector. Confirm the environment from a notebook cell:

import sys
print(sys.executable)

The path should end in analyses/demo/.venv/bin/python. Selecting a kernel does not move a notebook into that folder; save related notebooks alongside the project files.

In the JupyterLab terminal, run:

Terminal window
uv add --project "$HOME/analyses/demo" numpy nibabel

Restart the notebook kernel after changing packages. You can then import them in a cell:

import numpy as np
import nibabel as nib

Use uv add to keep dependency changes in pyproject.toml and uv.lock. The prototype does not install pip by default, so %pip install is not its supported package-management workflow. Ad hoc installations would not update the lockfile.

Packages from Neurodesktop’s default Python environment are not automatically available in this environment. For interactive widgets, add their Python packages (for example, uv add --project "$HOME/analyses/demo" ipywidgets). Neurodesk’s kernel wrapper still initializes its tool/module paths when the kernel starts. Use Conda or Neurodesk containers when your workflow needs software distributed through those systems.

Keep your notebooks, pyproject.toml, and uv.lock together, and commit the latter two files if you use Git. Do not commit .venv; it can be recreated and is tied to its filesystem location. Keep .neurodesk_uv_prototype.json with the folder when moving it. This record contains a local absolute path; keep it out of version control. It lives outside .venv so uv can recreate the environment without losing ownership information.

Kernel registration is local to your Neurodesktop user and is not carried by the notebook or lockfile.

Preserve Jupyter’s user data directory and your project folder across container replacement. The helper is supplied by the image. The default Jupyter data location is ~/.local/share/jupyter; installations can override it. Keeping uv’s cache and any uv-managed Python installations persistent also avoids repeated downloads.

Kernel startup runs the prepared environment directly. It does not download packages, synchronize dependencies, or update the lockfile. After manually editing dependencies, synchronize explicitly before restarting your kernel:

Terminal window
uv sync --project "$HOME/analyses/demo" --locked --group dev

--locked fails if the manifest and lockfile disagree. Prefer uv add for normal package changes so both files stay in step.

If you previously downloaded the helper, first update to an image that provides neurodesk-uv. Shut down affected notebook kernels, then run init on each project at its current location. This updates its kernel registration to the installed command and migrates its ownership record:

Terminal window
neurodesk-uv init "$HOME/analyses/demo"

Keep the downloaded helper until you have updated every project registration that uses it. You can then delete that downloaded file.

If uv recreated .venv after an interpreter change and the original helper now reports Existing .venv is unmanaged, the updated helper can recover using the project’s existing kernel registration. Run rebuild with the updated helper at the original project path before moving the folder or removing its registration:

Terminal window
neurodesk-uv rebuild "$HOME/analyses/demo"

Recovery requires either a prototype ownership record or a matching registration, and the existing environment must be uv-created. The helper continues to refuse unmanaged and symlinked environments. Do not remove ownership records as a troubleshooting step.

To recreate the environment from its existing manifest and lockfile:

Terminal window
neurodesk-uv rebuild "$HOME/analyses/demo"

A rebuild needs both pyproject.toml and uv.lock. It can work offline if the required Python interpreter and packages are already available locally; a lockfile alone does not contain those packages.

After moving the folder, rebuild at the new path and remove the old kernel registration. For example, after moving demo to renamed-demo:

Terminal window
neurodesk-uv rebuild "$HOME/analyses/renamed-demo"
neurodesk-uv remove "$HOME/analyses/demo"

Select Python (uv prototype: renamed-demo) in each affected notebook. Old registrations continue to refer to the old path until removed.

Terminal window
neurodesk-uv remove "$HOME/analyses/demo"

If no registration matches the path, the command reports No prototype registration and exits with status 1. Check the old path after a move rather than assuming its kernel was removed.

A successful removal deletes only the kernel registration. It retains notebooks, dependency files, and .venv. Switch affected notebooks to another kernel.