Skip to main content

Vitro

Vitro is a Python framework for setting up and operating testbed environments — deploying, configuring, and orchestrating the devices that make up a system under test. It is the second-generation successor to Boardfarm, distilling its lessons into a leaner, plugin-driven core.

Background

The previous generation packaged the framework, a large built-in device library, and test integrations together in a single project. Vitro splits those concerns: the core is a small orchestrator that knows nothing about specific devices or test runners. Device drivers, environment helpers, and reservation systems are contributed externally as plugins. A separate, shared template/operations pool can be layered on top to keep multiple plugins interoperable.

The result is a framework you can adopt for a single testbed without pulling in code for every device anyone has ever supported, while still allowing standardised test resources to be assembled across organisations.

What Vitro gives you

  • Two-file environment model. A standardised environment.json (devices and their roles) merged with a testbed-specific inventory.json (connection details) via jsonmerge.
  • Pluggable device registry. Plugins contribute device classes via the vitro_add_devices hook; Vitro wires them up by type string from the config.
  • Lifecycle hooks. Boot and configure phases, distinct for servers, devices, and attached devices, with sync and async variants.
  • Plugin extension surface (pluggy). Reservation, command-line args, config parsing, environment setup, and shutdown are all hookable.
  • Connection helpers. Pexpect-based SSH, serial, and local-command connections in vitro.libraries.connections.
  • vitro CLI. A standalone entry point that drives the full reserve → register → boot → configure cycle from a JSON config pair.

Quick start

Install:

pip install vitro

A minimal device plugin lives in your own package. The device class subclasses VitroDevice and implements lifecycle methods that Vitro discovers by name; a module-level @hookimpl registers the device type string with the framework:

# my_plugin/__init__.py
from vitro import hookimpl
from vitro.devices.base_devices import VitroDevice


class MyBox(VitroDevice):
    """Driver for the device type "my_box"."""

    def vitro_device_boot(self, config, cmdline_args, device_manager):
        """Boot sequence — connect, verify required tools, etc."""
        ...

    def vitro_device_configure(self, config, cmdline_args, device_manager):
        """Apply post-boot configuration."""
        ...


@hookimpl
def vitro_add_devices() -> dict[str, type[VitroDevice]]:
    """Tell Vitro about our device type."""
    return {"my_box": MyBox}

Register the package as a Vitro plugin via a setuptools entry point:

# pyproject.toml
[project.entry-points."vitro"]
my_plugin = "my_plugin"

With an environment.json that references "type": "my_box" for one or more devices, and an inventory.json providing their connection details, run:

vitro --board-name my-testbed \
      --env-config environment.json \
      --inventory-config inventory.json

Vitro will reserve, register, boot, and configure the devices, then keep them available for the next stage of your workflow — interactive exploration, automated tests via pytest-vitro, or any other consumer of the live device manager.

Where it fits

Vitro is deliberately framework-agnostic. It does not assume a particular test runner, a particular device library, or a particular reservation system. Two companion projects layer on top when useful:

  • A pytest bridge (pytest-vitro) exposes the live device manager as fixtures so you can write tests against booted devices.
  • A shared template/operations pool (vitro-commons) can sit between Vitro and your plugins, providing standardised contracts that multiple testbed plugins can conform to. This is the path for sharing tests across organisations.

Both are separate, optional packages — Vitro can be used without either.

Contributing

Contributions are welcome. Please open an issue describing the change you have in mind before sending a substantial pull request.

License

See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

vitro-0.8.1-py3-none-any.whl (47.2 kB view details)

Uploaded Python 3

File details

Details for the file vitro-0.8.1-py3-none-any.whl.

File metadata

  • Download URL: vitro-0.8.1-py3-none-any.whl
  • Upload date:
  • Size: 47.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for vitro-0.8.1-py3-none-any.whl
Algorithm Hash digest
SHA256 68b01d2d87337ff5e6e6cb4756e08969f247d5003139ee2b9183c73a8e174318
MD5 fbd4ecc0a9e3fa1068518c367f8aaf45
BLAKE2b-256 7c10a01823d9f9311fcb049b10a3d334a5c5a54a01888d122bae49a0f93f6eb2

See more details on using hashes here.

Provenance

The following attestation bundles were made for vitro-0.8.1-py3-none-any.whl:

Publisher: publish-to-pypi.yml on vitro-dev/vitro

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.8.1 This release

1 file

0.8.0

1 file

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