Interactive Textual TUI for building and running rpicam-still/rpicam-vid commands
Project description
rpicam-tui
An interactive terminal UI for building and running rpicam-still / rpicam-vid
commands on the Raspberry Pi Camera Module 3, without hand-typing long CLI
invocations every time.
This is a guided wrapper around the real CLI, not an abstraction that hides
it. Every control in the settings form is labeled with the actual flag it maps
to (--awb, --autofocus-mode, ...), and the command preview pane always
shows the exact command that will run. Runs are executed with
asyncio.create_subprocess_exec against the real rpicam-still/rpicam-vid
binaries — argv in, argv out, no picamera2 abstraction layer in between.
Layout
- Left pane — the settings form, grouped into collapsible sections (common/capture, autofocus, exposure, white balance/color, still-specific, video-specific).
- Top-right pane — a live, syntax-highlighted preview of the exact command that will run.
- Bottom-right pane — tabs for streamed process output and run history. Select a history row to reload its settings back into the form.
Running on the Pi
Dependencies are managed with uv:
curl -LsSf https://astral.sh/uv/install.sh | sh # if uv isn't installed yet
uv sync
uv run python -m rpicam_tui
# or: uv run rpicam-tui
uv sync creates a .venv and installs exactly what's pinned in uv.lock.
rpicam-still/rpicam-vid must be on PATH (they ship with rpicam-apps on
Raspberry Pi OS with a Camera Module 3 attached).
Developing off-Pi (dry-run mode)
The app runs fine on a laptop with no camera attached:
- If
rpicam-still/rpicam-vidisn't found onPATH, the runner automatically falls back to logging the command instead of executing it — you'll see a warning notification on startup and a note in the command preview. - You can also force this at any time with Ctrl+D (toggle dry-run), or by
launching with
uv run rpicam-tui --dry-run. - In dry-run, "running" a capture just prints
[dry-run] would run: ...to the output log and records a (fake, zero-duration) entry in run history, so the whole picking-settings → preview → run → history loop is exercisable without hardware.
Keybindings
| Key | Action |
|---|---|
Ctrl+R |
Run capture |
Ctrl+X |
Cancel running capture (SIGINT) |
Ctrl+T |
Toggle still/video mode |
Ctrl+S |
Save current settings as a preset |
Ctrl+L |
Load a preset |
Ctrl+Y |
Copy the current command to clipboard |
Ctrl+D |
Toggle dry-run mode |
Ctrl+Q |
Quit (cancels any running capture) |
Presets
Presets are JSON snapshots of the full settings form, stored at
~/.rpicam_tui/presets/*.json. A few are seeded on first run (copied from
rpicam_tui/presets/ in the package):
default-still— general-purpose full-resolution still capture.default-video— general-purpose 1080p30 video capture.vehicle-mount— manual focus at ~10m (--lens-position 0.1), a fast--shutter 8000to fight rolling-shutter blur from vibration, and a higher--bitrate 10000000.
Run history
Every run (including dry runs) is appended to ~/.rpicam_tui/history.json
with its timestamp, full command, exit code, duration, and output path.
Selecting a row in the History tab reloads that run's settings back into the
form so you can tweak and rerun.
Project layout
rpicam_tui/
command_builder.py # pure Settings -> argv logic, unit-testable, no I/O
runner.py # async subprocess execution + cancellation
field_specs.py # declarative form schema (flags, help text, groups)
presets.py # preset save/load
history.py # run history persistence
widgets.py # reusable Textual form/preview widgets
app.py # the Textual App tying it all together
presets/ # seed preset JSON files
tests/
test_command_builder.py
run.py # `python3 run.py` / `uv run python run.py` convenience entry point
pyproject.toml # uv/PEP 621 project + dependency metadata
uv.lock # pinned dependency versions
Tests
uv sync # installs the `dev` dependency group (pytest) too
uv run pytest
command_builder.py has no Textual or subprocess dependency, so its tests
run instantly and cover the argv-building logic directly.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rpicam_tui-0.1.0.tar.gz.
File metadata
- Download URL: rpicam_tui-0.1.0.tar.gz
- Upload date:
- Size: 28.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
840d794c9fb65f6fdec424989862ea67425318176015180cf83645a9113db61d
|
|
| MD5 |
90ece33335d90f8ad06d3ae197d3cd05
|
|
| BLAKE2b-256 |
87871a89cd7a641032af90d94b7006aad7dd1bc8bd016c300bef626d9438bc8b
|
Provenance
The following attestation bundles were made for rpicam_tui-0.1.0.tar.gz:
Publisher:
python-publish.yml on markosnarinian/rpicam-tui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rpicam_tui-0.1.0.tar.gz -
Subject digest:
840d794c9fb65f6fdec424989862ea67425318176015180cf83645a9113db61d - Sigstore transparency entry: 2072648715
- Sigstore integration time:
-
Permalink:
markosnarinian/rpicam-tui@55940a2f97d72ba701660d1ad1ce790ff7e84120 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/markosnarinian
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@55940a2f97d72ba701660d1ad1ce790ff7e84120 -
Trigger Event:
release
-
Statement type:
File details
Details for the file rpicam_tui-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rpicam_tui-0.1.0-py3-none-any.whl
- Upload date:
- Size: 20.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a50c4bd50972a8e15e42aa3a1bee525bc1f9a97cd166f1a85b95d6191705094
|
|
| MD5 |
e9cca911d4e54f9150aeb6e872573fd9
|
|
| BLAKE2b-256 |
af87017dd87f686eb2d7b821f915e63c3bc4fc093e88ef369e2ed3b5b264355b
|
Provenance
The following attestation bundles were made for rpicam_tui-0.1.0-py3-none-any.whl:
Publisher:
python-publish.yml on markosnarinian/rpicam-tui
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rpicam_tui-0.1.0-py3-none-any.whl -
Subject digest:
9a50c4bd50972a8e15e42aa3a1bee525bc1f9a97cd166f1a85b95d6191705094 - Sigstore transparency entry: 2072648721
- Sigstore integration time:
-
Permalink:
markosnarinian/rpicam-tui@55940a2f97d72ba701660d1ad1ce790ff7e84120 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/markosnarinian
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@55940a2f97d72ba701660d1ad1ce790ff7e84120 -
Trigger Event:
release
-
Statement type: