Metadata-Version: 2.4
Name: vitro
Version: 0.8.0
Summary: Framework to set up an environment by deploying and configuring the devices in such environment.
License-Expression: BSD-3-Clause
Project-URL: Homepage, https://github.com/vitro-dev/vitro
Project-URL: Repository, https://github.com/vitro-dev/vitro
Project-URL: Issues, https://github.com/vitro-dev/vitro/issues
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: Telecommunications Industry
Classifier: Operating System :: OS Independent
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python
Classifier: Topic :: Software Development :: Embedded Systems
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: Testing :: Acceptance
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: ipython>=8.37.0
Requires-Dist: jedi>=0.19.2
Requires-Dist: jsonmerge>=1.9.2
Requires-Dist: netaddr>=1.3.0
Requires-Dist: pexpect>=4.9.0
Requires-Dist: pluggy>=1.2.0
Requires-Dist: ptpython>=3.0.32
Requires-Dist: pytest>=9.0.2
Requires-Dist: requests>=2.32.5
Requires-Dist: rich>=14.2.0
Dynamic: license-file

# 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:

```bash
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:

```python
# 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:

```toml
# 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:

```bash
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](LICENSE).
