# How to use picamera2 and GPIO with uv on Raspberry Pi


`picamera2`, `libcamera`, and `gpiozero` ship through `apt` on Raspberry Pi OS, not through PyPI. A clean uv venv cannot import them, and `pip install picamera2` inside that venv fails on the missing `libcamera` module. The workaround is to install the system packages with apt, then build a uv venv against `/usr/bin/python3` that inherits the system site-packages. This guide walks through that setup and the constraints it brings.

It assumes uv is already installed on the Pi. If not, start with [How to run Python scripts on a Raspberry Pi with uv](https://pydevtools.com/handbook/how-to/how-to-run-python-scripts-on-a-raspberry-pi-with-uv.md).

## Install the apt packages

Install the Pi-specific bindings through the system package manager:

```bash
sudo apt update
sudo apt install -y python3-picamera2 python3-libcamera python3-gpiozero
```

These packages register themselves under `/usr/lib/python3/dist-packages/`, which is only visible to `/usr/bin/python3` and to venvs that explicitly opt in.

## Create a uv venv that sees the apt packages

In your project directory, point uv at the system Python and pass `--system-site-packages`:

```bash
uv venv --python /usr/bin/python3 --system-site-packages
```

Then install pip-installable dependencies into the same venv:

```bash
uv pip install adafruit-circuitpython-dht
```

The venv now has both stacks. Confirm:

```bash
uv run python -c "from picamera2 import Picamera2; print(Picamera2.global_camera_info())"
```

The command prints the connected camera's info, importing both the apt-installed `picamera2` and any pip-installed dependencies from the same interpreter.

## Constraints to plan around

A few things behave differently with this setup:

- **`uv init` and `uv add` ignore apt packages.** They resolve against `pyproject.toml` and don't know about `python3-picamera2`. Add an explicit `import picamera2` check at the top of your script so a missing apt package fails loudly.
- **`uv sync` won't reinstall the apt packages on another Pi.** Document the `sudo apt install` step in your project's README, or wrap it in a small `setup.sh`.
- **`uv python install` can't manage the Pi-bound Python.** The `picamera2` package binds to `/usr/bin/python3` specifically; staying on system Python is required for projects that need it.
- **Newer Python versions break this path.** If your project needs a Python newer than the one Raspberry Pi OS ships, the apt + system-site-packages approach won't work. Either downgrade to the system Python or accept that the project can't use the apt-only libraries.

## Run as a systemd service on boot

systemd needs an absolute path to the interpreter. For a project venv, point `ExecStart` directly at the venv's Python:

```ini {filename="/etc/systemd/system/camera-logger.service"}
[Unit]
Description=Camera logger
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/camera-logger
ExecStart=/home/pi/camera-logger/.venv/bin/python main.py
Restart=on-failure

[Install]
WantedBy=multi-user.target
```

`/home/pi/camera-logger/.venv/bin/python` resolves through the system-site-packages venv, so it sees `picamera2` and any pip-installed deps. Keep `User=pi` matched to the user that ran `uv venv`; `~/.cache/uv` and `~/.local/share/uv` need to be readable by the service user.

For a single-file script that uses inline metadata, set `ExecStart=/home/pi/.local/bin/uv run /home/pi/script.py`. The inline-metadata path doesn't combine with `--system-site-packages`, though, so picamera2 / GPIO projects should use a venv-based project rather than an inline-metadata script.

## Learn More

- [How to run Python scripts on a Raspberry Pi with uv](https://pydevtools.com/handbook/how-to/how-to-run-python-scripts-on-a-raspberry-pi-with-uv.md) covers the install and the inline-metadata / project flows.
- [How to fix the externally-managed-environment error](https://pydevtools.com/handbook/how-to/how-to-fix-the-externally-managed-environment-error.md) explains why pip can't install into the system Python on Bookworm.
- [picamera2 manual](https://datasheets.raspberrypi.com/camera/picamera2-manual.pdf) from Raspberry Pi.
- [gpiozero documentation](https://gpiozero.readthedocs.io/).
- [`uv venv --system-site-packages` reference](https://docs.astral.sh/uv/reference/cli/#uv-venv) in the uv docs.
