plesty.lib.experiment.preflight =============================== .. py:module:: plesty.lib.experiment.preflight .. autoapi-nested-parse:: Build a rig, check it, and ask the operator when a device is not there. Every experiment starts the same way: connect the device servers, make sure each one is the device it is supposed to be, and only then run. When a server is down or an address points at the wrong server, the operator must learn it at once — with the device, its address and the variable that set it — and decide: retry after fixing it, abort, or (for a sub-device the experiment can do without) continue without it. :func:`connect_rig` is that start, for any composite:: rig, skipped = connect_rig( lambda skip: PolPlRig(with_powermeter="pm" not in skip), optional={"pm"}, ) Non-interactive processes (no terminal on stdin) do not wait for an answer: the diagnosis is logged and :class:`RigNotReadyError` is raised. Exceptions ---------- .. autoapisummary:: plesty.lib.experiment.preflight.RigNotReadyError Functions --------- .. autoapisummary:: plesty.lib.experiment.preflight.connect_rig Module Contents --------------- .. py:exception:: RigNotReadyError(problems: dict[str, str], message: str) Bases: :py:obj:`RuntimeError` The rig failed its preflight and the operator did not (or could not) recover it. :ivar problems: Sub-device name → one-line problem. Keep the per-device problems next to the message. .. py:attribute:: problems .. py:function:: connect_rig(build: collections.abc.Callable[[frozenset[str]], plesty.lib.device.composite_device.CompositeDevice], *, optional: collections.abc.Iterable[str] = (), ask: Optional[collections.abc.Callable[[str], str]] = None, env_prefix: Optional[str] = None, out: collections.abc.Callable[[str], None] = print) -> tuple[plesty.lib.device.composite_device.CompositeDevice, frozenset[str]] Build the rig, run its preflight, and ask the operator on a failure. :param build: Factory building the composite without the given (optional) sub-devices; called again on every retry, so an edited ``.env`` or a freshly started server is picked up. :param optional: Sub-devices the experiment can run without; when only these fail, the operator may choose to continue without them. :param ask: Reads the operator's answer to a prompt. Defaults to ``input`` when stdin is a terminal, else to no prompt at all (the diagnosis is logged and :class:`RigNotReadyError` raised). :param env_prefix: Deployment prefix of the ``_ADDRESS`` variables, for the diagnosis. :param out: Where the diagnosis and the prompt go (``print``). :returns: The ready composite and the set of optional sub-devices skipped. :raises RigNotReadyError: If the operator aborts, or nobody can be asked.