plesty.server.model.fleet

The fleet.yaml model — which device servers this bench runs, and how.

A fleet file declares the devices once; plesty-server fleet up installs and starts them, fleet run keeps them up headless. The same file is what the GUI reads and writes.

version: 1
home: ~/.plesty/server            # optional
index_url: https://hub.plesty.net/api/modules/   # optional
devices:
  pm100d:                         # instance name → venv, log and state key
    package: plesty-pm100d        # PyPI distribution
    version: 0.2.1                # pinned; omit for the newest release
    # git: https://gitlab.com/plesty/hub/devices/thorlab/plesty-pm100d.git
    # ref: exp                    # branch/tag/sha; default tag v<version>
    args: [--tcp-port, "5555", -a, "USB0::0x1313::0x8078::P0000000::INSTR"]
    env:                          # process environment; plesty-lib reads it
      PLESTY_REPORT_ARCHIVE: /shares/plesty/reports
    autostart: true
experiments:
  pol-pl:                         # instance name → run and job key
    package: plesty-pol-pl
    git: https://gitlab.com/plesty/hub/experiments/plesty-pol-pl.git
    ref: exp
    config: config/default.yaml   # relative to the checkout
    env:
      HWP_ADDRESS: tcp://127.0.0.1:5555

An experiment has no port and no autostart: it binds nothing, nothing probes it, and fleet up does not start it — it runs once, when an operator runs it. It is normally declared with git: rather than a version, because its config/*.yaml and .env.example are in the repository and not in the wheel, so a release install would leave nothing to configure.

A git: URL installs from the repository instead of PyPI — the form hub-registry advertises for modules without a release; ref names the branch, tag or commit and defaults to the tag v<version> when a version is given, else the default branch.

An experiment module’s setup (plesty.server.model.setup) is a fleet file with benches: beside its devices, so fleet up -f setup.yaml brings its instruments up. The fleet carries that key through as written, and the setup reads it. Such a file is the experiment’s, committed with it: the bench reads it and never writes it (Fleet.is_setup, #48).

Precedence for the probed TCP port: an explicit port key, then --tcp-port/-tp in args, then a *_TCP_PORT value in env, then plesty-lib’s default 5555 (see plesty.server.model.ports).

Attributes

FLEET_VERSION

FLEET_FILENAME

Classes

Fleet

A parsed fleet file.

Functions

load_fleet(→ Fleet)

Read and validate a fleet file.

save_fleet(→ pathlib.Path)

Write a fleet file.

find_fleet(→ pathlib.Path | None)

Locate the fleet file a command should consult.

Module Contents

plesty.server.model.fleet.FLEET_VERSION = 1
plesty.server.model.fleet.FLEET_FILENAME = 'fleet.yaml'
class plesty.server.model.fleet.Fleet

A parsed fleet file.

Variables:
  • devices – Specs keyed by device name, in file order.

  • experiments – Experiment specs keyed by name, in file order.

  • home – home: from the file, or None.

  • index_url – index_url: from the file, or None.

  • path – Where it was read from, or None for an in-memory fleet.

  • benches – benches: as a setup file writes it, carried through unread; see plesty.server.model.setup.parse_setup().

devices: collections.abc.Mapping[str, plesty.server.model.device.DeviceSpec]
experiments: collections.abc.Mapping[str, plesty.server.model.experiment.ExperimentSpec]
home: pathlib.Path | None = None
index_url: str | None = None
path: pathlib.Path | None = None
benches: collections.abc.Mapping[str, Any]
__getitem__(name: str) → plesty.server.model.device.DeviceSpec

The spec of device name; KeyError when undeclared.

Parameters:

name (str)

Return type:

plesty.server.model.device.DeviceSpec

__contains__(name: object) → bool

Whether name is a declared device.

Parameters:

name (object)

Return type:

bool

__iter__() → Any

Iterate over the specs in file order.

Return type:

Any

__len__() → int

Number of declared devices.

Return type:

int

property autostart: list[plesty.server.model.device.DeviceSpec]

The specs fleet up starts.

Return type:

list[plesty.server.model.device.DeviceSpec]

property is_setup: bool

Whether this is an experiment’s setup rather than one of a bench’s fleets.

A setup names its benches:; a bench’s fleet never does. It is committed with the experiment, so the bench only reads it: written back, it lost every comment and gained the ports this bench chose (#48).

Return type:

bool

classmethod from_mapping(raw: collections.abc.Mapping[str, Any], path: pathlib.Path | None = None) → Fleet

Build a fleet from a parsed YAML document.

Parameters:
  • raw (collections.abc.Mapping[str, Any]) – The document.

  • path (pathlib.Path | None) – Where it came from, for error messages and path.

Raises:

FleetError – On a wrong schema version or malformed entries.

Return type:

Fleet

to_mapping() → dict[str, Any]

The YAML document form of this fleet.

Return type:

dict[str, Any]

_copy(**changes: Any) → Fleet

A copy of this fleet with changes applied.

Every mutator goes through here rather than rebuilding the fleet positionally, so a field added between two others cannot silently shift what the next argument means.

Parameters:

changes (Any)

Return type:

Fleet

with_device(spec: plesty.server.model.device.DeviceSpec) → Fleet

A copy with spec added or replaced under its name.

Parameters:

spec (plesty.server.model.device.DeviceSpec)

Return type:

Fleet

without_device(name: str) → Fleet

A copy without device name (no error when absent).

Parameters:

name (str)

Return type:

Fleet

with_experiment(spec: plesty.server.model.experiment.ExperimentSpec) → Fleet

A copy with experiment spec added or replaced under its name.

Raises:

FleetError – If a device already holds that name — a run directory, a job key and a log are keyed by it.

Parameters:

spec (plesty.server.model.experiment.ExperimentSpec)

Return type:

Fleet

without_experiment(name: str) → Fleet

A copy without experiment name (no error when absent).

Parameters:

name (str)

Return type:

Fleet

renamed(old: str, new: str) → Fleet

A copy with device old declared under new, where it already sits.

Rebuilding the mapping rather than dropping and re-adding is the whole point: the fleet file is written in key order, so a device the operator renames stays on the line it was on instead of moving to the bottom.

Parameters:
  • old (str) – The declared name.

  • new (str) – The name to give it; must be free.

Raises:

FleetError – When old is not declared, new already is, or new is not a name every bench can turn into a file name.

Return type:

Fleet

plesty.server.model.fleet.load_fleet(path: str | os.PathLike[str]) → Fleet

Read and validate a fleet file.

Parameters:

path (str | os.PathLike[str]) – The YAML file.

Raises:

FleetError – When the file is missing or malformed.

Return type:

Fleet

plesty.server.model.fleet.save_fleet(fleet: Fleet, path: str | os.PathLike[str]) → pathlib.Path

Write a fleet file.

Parameters:
  • fleet (Fleet) – The fleet to serialize.

  • path (str | os.PathLike[str]) – Destination file; parents are created.

Returns:

The written path.

Return type:

pathlib.Path

plesty.server.model.fleet.find_fleet(explicit: str | os.PathLike[str] | None, home: pathlib.Path) → pathlib.Path | None

Locate the fleet file a command should consult.

Parameters:
  • explicit (str | os.PathLike[str] | None) – A path the user gave (-f); returned as-is when set.

  • home (pathlib.Path) – The bench home, whose fleet.yaml is the last resort after the working directory’s.

Returns:

The first existing candidate, or None when no fleet file exists.

Return type:

pathlib.Path | None