Skip to main content

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-client invocation for that bench; what you cannot do right now is greyed with the reason. r gets 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/model and tests/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 with docker run -d -p 20408:20408 labgrid/coordinator and run uv run pytest -m integration (LABGRID_TUI_TEST_COORDINATOR points elsewhere).
  • scripts/generate-stubs.sh regenerates 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)

Source distribution for labgrid-tui 0.2.0
File Size Uploaded
labgrid_tui-0.2.0.tar.gz 183.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for labgrid-tui 0.2.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

0.2.1

2 release files

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page