labgrid-tui
A terminal dashboard for labgrid
labs. It connects to a labgrid coordinator over gRPC, shows every place and
resource live as it changes, and turns each one into the exact
labgrid-client command line to copy or edit. It has no state or protocol
of its own: a discoverability lens over what the coordinator already
exposes and what labgrid-client already does.
labgrid-tui is an independent, third-party project. It is not affiliated with or endorsed by the labgrid project or its maintainers.
At a glance
- Live fleet view: places, resources, holders and reservations from the coordinator's own event stream; no polling.
- Every action is a real command line: console, power, SSH, file
transfer, SD-mux, video, acquire, release, shown as the exact
labgrid-clientinvocation for that bench; what you cannot do right now is greyed with the reason.rgets a bench in one line, queueing when it is busy. - Several coordinators: named entries, switched at runtime
(
shift+p) or from the CLI. - Shareable command packs: a team's recipes in a small TOML file, placeholders filled in per bench, copy-only by design.
- Reservations and an activity log: queue for a busy bench, see the allocation happen, cancel with the token filled in.
- Keyboard-first, read-only: Vim keys, works in a narrow tmux pane, never mutates anything over gRPC, needs no credentials, manages no places.
Install
uv tool install labgrid-tui
# or: uv tool install git+https://github.com/onurcelep/labgrid-tui
Python 3.11+. labgrid-client on PATH is optional: commands are copied
either way and run in place only when it is present.
Usage
labgrid-tui tour # guided walkthrough on fake data, no coordinator needed
labgrid-tui config init # optional: persist a coordinator address
labgrid-tui # or: labgrid-tui -x coordinator.example.org:20408
Press ? in the dashboard for every key, the table legend and the
operations reference; the in-app help is the only copy of that material.
Configuration
Coordinator address, in order: -x, then LG_COORDINATOR, then the
active named coordinator, then coordinator in config.toml, then
127.0.0.1:20408. A bare host gets the default port. All files live in
~/.config/labgrid-tui/ ($XDG_CONFIG_HOME honoured); none needs to
exist.
config.toml (hand-edited; labgrid-tui config init writes a commented
template, config show prints every resolved value and its source):
coordinator = "coordinator.example.org:20408" # or a named coordinator
prefix = "labgrid-client -x coordinator.example.org:20408" # optional
[capabilities]
MyCustomResource = "power" # resource class -> capability chip
[[commands]] # extra labgrid-client entries
category = "Custom"
label = "Ping DUT"
suffix = "ssh -- ping -c1 10.0.0.1"
class = "NetworkService" # omit for a place-level entry
Named coordinators live in coordinators.toml, written by the tool:
shift+p in the TUI (enter switch, n new, e edit, x delete) or
labgrid-tui coordinator list|add|use|remove|show|edit. -x and
coordinator accept a name from it as well as an address.
LG_PROXY is not supported: if it is set, labgrid-tui refuses to start.
UI state (panels, theme) persists to ~/.local/state/labgrid-tui/ui.toml.
Command packs
A pack is a TOML file of copy-only recipes. Register it explicitly; nothing is discovered on its own:
labgrid-tui pack add PATH|URL # also: list, show, update, remove
A path is re-read on every start; an HTTPS URL is cached and refreshed by
pack update. Each pack is its own tab in the command overlay (c) and
its own palette group; enter copies, the TUI never executes a pack entry.
[pack]
name = "robot"
[[commands]]
label = "Smoke tests on this bench"
command = "robot -v PLACE:{place} -v DUT_IP:{res.NetworkService.address} tests/smoke"
requires = ["res.NetworkService"]
Placeholders: {place}, {coordinator}, {prefix}, {token} (your
reservation for this place), {tag.KEY}, {res.CLASS.PARAM} (first
matched resource of that class; PARAM may be name). requires items:
res.CLASS, tag.KEY, held. An unmet requirement or an unresolvable
placeholder greys the entry with the reason instead of failing. A full
example ships in examples/robot.toml.
Extending
Plugins are Python modules registered under the labgrid_tui.plugins
entry-point group that may define capabilities: dict[str, str]
(resource class to capability) and commands: dict[str, tuple[CommandTemplate, ...]]
(resource class to extra entries). A plugin that raises while loading is
skipped with a warning.
Building a larger shell on top (authentication, another execution
backend, extra status): every widget and screen takes its data through
constructor arguments, LabgridTuiApp is subclassable, and every action
is dispatched through one two-method protocol:
class ActionRunner(Protocol):
def run(self, entry: CommandEntry) -> None: ...
def copy(self, entry: CommandEntry) -> None: ...
Hand the widgets your own runner and the validity engine (which commands
are offered, and why not) stays shared. Extra status-bar segments are
Callable[[], str | None] providers on extra_status_segments.
Unknown keys in coordinators.toml entries survive edits, so a shell can
store its own per-coordinator data there. This surface may change before
1.0.
Development
See CONTRIBUTING.md for the gate to run before opening a PR.
uv sync
uv run pre-commit install # ruff check and format on every commit
uv run ruff check src tests
uv run mypy src
uv run pytest # unit and UI tests against a fake coordinator
tests/modelandtests/coordinator: pure logic and the gRPC layer.tests/ui: widgets and screens, driven through Textual's pilot.tests/integration: a real coordinator, excluded by default. Start one withdocker run -d -p 20408:20408 labgrid/coordinatorand runuv run pytest -m integration(LABGRID_TUI_TEST_COORDINATORpoints elsewhere).scripts/generate-stubs.shregenerates the gRPC stubs from the vendored proto.
Release: bump version in pyproject.toml, tag vX.Y.Z, push the tag.
The publish workflow uploads to PyPI through trusted publishing.
License
Apache-2.0. Copyright 2026 Onur Celep. The package metadata declares
Apache-2.0 AND LGPL-2.1-or-later because of the vendored labgrid file below.
labgrid-tui does not include or import the labgrid Python package. It
contains an unmodified copy of labgrid's coordinator protocol definition
(labgrid-coordinator.proto, LGPL-2.1-or-later, licence text in
LICENSE.labgrid) and gRPC stubs generated from it; it
talks to a labgrid coordinator over the network and runs labgrid-client
as a separate process.
Release files for labgrid-tui 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| labgrid_tui-0.2.0.tar.gz | 183.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| labgrid_tui-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 327.6 kB
Release files / labgrid_tui-0.2.0.tar.gz
| Download URL | labgrid_tui-0.2.0.tar.gz |
|---|---|
| Size | 183.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6312cde19d57d75c1a33c6639bc69c1002a11ed5279e9d6b2ad3e8ac1d889a83
|
|
BLAKE2b-256 checksum How to use checksums |
7f88dfeb953f5182a203f2f50489da12675029abb616c8e1071dbd1d8fbe245d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency logRelease files / labgrid_tui-0.2.0-py3-none-any.whl
| Download URL | labgrid_tui-0.2.0-py3-none-any.whl |
|---|---|
| Size | 144.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ef546b36ed3154fcebaa717e946f2324c6abee0b11caca9a529e3b86367d7b6b
|
|
BLAKE2b-256 checksum How to use checksums |
ce717157dee8f42634de4b899e904f76902fd68f8d80a5357c1d45e21f80944f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 16, 2026.
Transparency log