configmodule¶
The configmodule package handles environment variables, repository discovery, settings parsing, and lab loading.
-
otto.configmodule.configmodule.all_hosts(pattern: Pattern[str] | None =
None, *, include_containers: bool =False, term: str | None =None, transfer: str | None =None, ssh_options: SshOptions | None =None, telnet_options: TelnetOptions | None =None, sftp_options: SftpOptions | None =None, scp_options: ScpOptions | None =None, ftp_options: FtpOptions | None =None, nc_options: NcOptions | None =None) Generator[RemoteHost, Any, Any]¶ Yield the active lab’s real remote hosts, optionally filtered by regex.
This is the fleet generator: it yields every network-reached
RemoteHostin the active lab — bothUnixHost(SSH/telnet to a shell) andEmbeddedHost(telnet to an RTOS console).DockerContainerHostentries are skipped by default because containers aren’t operated on as part of the host fleet (e.g.otto monitor, coverage collection); containers remain reachable for targeted use via tab completion andget_host. Passinclude_containers=Trueto yield container hosts as well.- Parameters:¶
pattern – Compiled regex matched against each host’s
idviapattern.search(). When None (the default), all hosts are yielded.include_containers – When
True, also yieldDockerContainerHostentries. Defaults toFalse.term, transfer – optional active-protocol override; see
_apply_option_overrides.ssh_options, telnet_options, sftp_options, scp_options,
ftp_options, nc_options – Optional per-call option overrides. When supplied, each yielded host is a fresh
dataclasses.replace()-style copy whose corresponding*_optionsfield is replaced by the caller’s instance (wholesale replacement, not per-key merge). The new host has a freshConnectionManagerconstructed with the override options, so the override values shape whichever connection opens first. Stored hosts inlab.hostsare untouched. Override keys that don’t correspond to a field on a given host are silently dropped — e.g.ssh_optionsis ignored for anEmbeddedHost, which only carriestelnet_options. When no applicable overrides remain, the stored instance is yielded as-is so identity is preserved. Hop resolution is internal and is not affected by overrides.
- Yields:¶
RemoteHost – Each matching
UnixHostorEmbeddedHostfrom the lab configuration.
Examples
Filter the active lab’s hosts by id pattern (see Using otto as a library for a runnable, in-memory example):
import re seeds = list(all_hosts(re.compile(r"tomato")))
-
async otto.configmodule.configmodule.do_for_all_hosts(method: Callable[[...], Awaitable[T]], *args: Any, pattern: Pattern[str] | None =
None, concurrent: bool =True, include_containers: bool =False, term: str | None =None, transfer: str | None =None, ssh_options: SshOptions | None =None, telnet_options: TelnetOptions | None =None, sftp_options: SftpOptions | None =None, scp_options: ScpOptions | None =None, ftp_options: FtpOptions | None =None, nc_options: NcOptions | None =None, **kwargs: Any) dict[str, T | BaseException]¶ Call an async host method on every matching host.
- Parameters:¶
method – Unbound async method (e.g.
UnixHost.oneshot).*args – Positional arguments forwarded to method after the host.
pattern – Compiled regex filter passed to
all_hosts().concurrent – When
True(default), run all calls viaasyncio.gatherwithreturn_exceptions=True. WhenFalse, execute serially.include_containers – Forwarded to
all_hosts(). WhenFalse(default), container hosts are excluded.term, transfer – optional active-protocol override; see
_apply_option_overrides.ssh_options, telnet_options, sftp_options, scp_options,
ftp_options, nc_options – Optional per-call option overrides forwarded to
all_hosts(). See its docstring for semantics.**kwargs – Keyword arguments forwarded to method.
- Returns:¶
A dict keyed by host ID. Values are the return of method, or a
BaseExceptionif that host’s call failed.
Examples
Call an unbound async method on every matching host:
import re from otto.host import UnixHost results = await do_for_all_hosts( UnixHost.oneshot, "uname -a", pattern=re.compile(r"router"), )
-
async otto.configmodule.configmodule.run_on_all_hosts(cmds: list[str] | str, pattern: Pattern[str] | None =
None, concurrent: bool =True, timeout: float | None =None, *, include_containers: bool =False, term: str | None =None, transfer: str | None =None, ssh_options: SshOptions | None =None, telnet_options: TelnetOptions | None =None, sftp_options: SftpOptions | None =None, scp_options: ScpOptions | None =None, ftp_options: FtpOptions | None =None, nc_options: NcOptions | None =None) dict[str, RunResult | BaseException]¶ Run commands on every matching host via
run().Convenience wrapper around
do_for_all_hosts()for the most common use case.- Parameters:¶
cmds – Command string or list of command strings.
pattern – Compiled regex filter passed to
all_hosts().concurrent – When
True(default), run all calls viaasyncio.gather. WhenFalse, execute serially.timeout – Per-host timeout forwarded to
run.include_containers – Forwarded to
do_for_all_hosts(). WhenFalse(default), container hosts are excluded.term, transfer – optional active-protocol override; see
_apply_option_overrides.ssh_options, telnet_options, sftp_options, scp_options,
ftp_options, nc_options – Optional per-call option overrides forwarded to
do_for_all_hosts().
- Returns:¶
A dict keyed by host ID. Values are
RunResultinstances, or aBaseExceptionif that host’s call failed.
Examples
Run a command on every matching host:
results = await run_on_all_hosts("uname -a")
-
otto.configmodule.configmodule.get_host(host_id: str, *, term: str | None =
None, transfer: str | None =None, ssh_options: SshOptions | None =None, telnet_options: TelnetOptions | None =None, sftp_options: SftpOptions | None =None, scp_options: ScpOptions | None =None, ftp_options: FtpOptions | None =None, nc_options: NcOptions | None =None) UnixHost¶ Return the host registered under host_id in the active lab.
- Parameters:¶
host_id – Unique host id (as produced by
UnixHost.id).term, transfer – optional active-protocol override; see
_apply_option_overrides.ssh_options, telnet_options, sftp_options, scp_options,
ftp_options, nc_options – Optional per-call option overrides. Each non-
Noneargument replaces the corresponding*_optionsfield on a returned copy wholesale; the copy is built viadataclasses.replace()so the new host’sConnectionManageris constructed with the override options from the start. The stored host (and any connection it owns) is untouched. With no overrides, the stored instance is returned unchanged soget_host('x') is get_host('x')still holds. Hop resolution is internal and is not affected by overrides.
Environment variables that are needed before parsing CLI arguments
-
otto.configmodule.env.validate_path(path: Path | None, must_exist: bool =
True) None¶ Validate that path exists when must_exist is
True.Raises
FileNotFoundErrorif the path is set but does not exist on disk. ANonepath is always accepted (the env var was not set).
- otto.configmodule.env.load_otto_env() OttoEnvSettings¶
Construct the OTTO_* env settings and validate that every sut_dir exists, raising FileNotFoundError (the historical OttoEnv() startup contract).
- class otto.configmodule.lab.Lab(name: 'str', resources: 'set[str]' = <factory>, hosts: 'dict[str, Host]' = <factory>)¶
Bases:
object
-
otto.configmodule.lab.load_lab(labnames: str | list[str], search_paths: list[Path] | None =
None, preferences: dict[str, dict[str, Any]] | None =None, repository: LabRepository | None =None) Lab¶ Build a Lab object from one or more lab names.
Parameters¶
- labnamesstr | list[str]
Name(s) of lab data to retrieve (a comma-separated string is split).
- search_pathslist[Path] | None
Directories searched by the default json backend. Ignored when
repositoryis supplied.- preferencesdict[str, dict[str, Any]] | None
The unified
{selector: {capability: [...] | option_table: {key: val}}}product-preference table applied to every host in the resulting lab.Nonereproduces today’s behavior.- repositoryLabRepository | None
A pre-built host-source backend (e.g. from
otto.storage.build_lab_repository()). WhenNone, a built-in json backend oversearch_pathsis used — preserving library/script behavior.
Returns¶
- Lab
Fully defined lab instance.
-
class otto.configmodule.repo.DockerImage(name: str, dockerfile: Path, context: Path, target: str | None =
None, build_args: tuple[tuple[str, str], ...] =())¶ Bases:
objectA Dockerfile-built image declared by a project.
-
class otto.configmodule.repo.DockerCompose(path: Path, default_host: str | None =
None, services: tuple[str, ...] =())¶ Bases:
objectA docker-compose file contributed by a project.
-
class otto.configmodule.repo.DockerSettings(registry_url: str =
'docker.io', images: tuple[DockerImage, ...] =(), composes: tuple[DockerCompose, ...] =())¶ Bases:
objectPer-repo docker configuration parsed from [docker] in settings.toml.
-
registry_url : str =
'docker.io'¶ Default registry. Overridable per-image via the image’s tag prefix.
-
images : tuple[DockerImage, ...] =
()¶ Images this project knows how to build.
-
composes : tuple[DockerCompose, ...] =
()¶ Compose files this project contributes.
-
registry_url : str =
- class otto.configmodule.repo.CollectedTest(nodeid: str, name: str, path: Path, cls_name: str | None)¶
Bases:
objectA single test item collected from a SUT repo’s test directories.
Attributes¶
- nodeid :
Full pytest node ID, e.g.
dir/test_x.py::ClassName::test_fn. Suitable for use directly as theSUITEargument tootto test.- name :
Test function name only, e.g.
test_fn.- path :
Absolute path to the test file.
- cls_name :
Class name if the test belongs to a class, else
None.
- class otto.configmodule.repo.Repo(sut_dir: pathlib.Path, settings: dict[str, typing.Any] = <factory>)¶
Bases:
object- valid_labs : list[str]¶
Lab names this repo supports (by
labsmembership), e.g. an embedded product that only runs in an embedded lab. Empty when the key is unset.Parsed here; enforcement — rejecting a selected
--labthat is not in this list, and treating an empty list as “the repo must declare its labs” rather than allow-all — is intentionally deferred to lab-selection time and not yet wired in. Parsing must not silently treat unset as allow-all.
- init : list[str]¶
Module paths that need to be imported during otto init.
Modules containing instructions are an example of modules that need to be imported eagerly.
- host_preferences : dict[str, dict[str, Any]]¶
Unified per-selector product preferences:
{regex_selector: {capability: [ordered backends] | option_table: {key: val}}}. The factory matches each host’sidagainst the selectors (definition-order cascade) and partitions the result into capability selections (forwarded to the resolver) and option-value defaults (applied per-key, product-wins).
- os_profiles : dict[str, OsProfile]¶
Named OS profiles declared by this repo’s
[os_profiles]settings, keyed by profile name. Each is also registered into the global os-profile registry at parse time so lab-data entries can select it by name in theos_typefield. Seeotto.host.os_profile.register_os_profile().
- docker_settings : DockerSettings¶
Parsed [docker] table — image build definitions, compose files, and registry URL. Defaults to an empty
DockerSettingswhen the section is absent.
- get_instructions_panel() Panel¶
Build a Rich panel listing all instructions contributed by this repo.
Instructions are attributed to this repo by matching each registered instruction’s module against the module prefixes in
init.
- collect_tests() list[CollectedTest]¶
Collect all tests from this repo’s configured test directories.
Performs a single pytest collection pass (no tests are executed). The returned list can be passed to any of the
get*Panelmethods so that multiple listing options share one collection run.Returns¶
- list[CollectedTest]
One entry per discovered test item, in collection order.
- get_tests_panel(items: list[CollectedTest]) Panel¶
Rich panel listing every individual test with its full run syntax.
Each line shows
otto test <absolute-path>::[Class::]test_fnwhich can be copy-pasted directly to run that specific test regardless of the current working directory.Parameters¶
- items :
Pre-collected tests from
collect_tests().
- get_test_files_panel(items: list[CollectedTest]) Panel¶
Rich panel listing unique test files with their run syntax.
Each line shows
otto test <absolute-path>which runs all tests in that file.Parameters¶
- items :
Pre-collected tests from
collect_tests().
- get_test_suites_panel(items: list[CollectedTest]) Panel¶
Rich panel listing unique test suites with their run syntax.
Only class-based tests are listed, using just
ClassName— the subcommand name passed directly tootto test ClassName. Bare functions (not part of a class) are omitted since they have no correspondingotto testsubcommand. Entries are de-duplicated and preserve collection order.Parameters¶
- items :
Pre-collected tests from
collect_tests().
- get_otto_settings_path() Path¶
Create the path to the otto settings TOML file.
Returns¶
Path to the otto settings TOML file.
Raises¶
- FileNotFoundError
If the TOML file is not found.
- property reservation_settings : dict[str, Any]¶
Return the
[reservations]settings sub-dict with ${sut_dir} expanded.Returns an empty dict when the section is absent. Every string value (including nested tables) has
${sut_dir}substituted so the reservation backend can use the same path-expansion convention as the other repo settings.
- property lab_settings : dict[str, Any]¶
Return the
[lab]settings sub-dict with${sut_dir}expanded.Returns an empty dict when the section is absent, so the host-source factory falls back to the built-in
jsonbackend over this repo’slabssearch paths.
- import_test_files() None¶
Import test_*.py files from each configured tests directory.
This triggers
@register_suite()decorators, which populateotto.suite.register._SUITE_REGISTRYat import time. The registry is later consumed bycli/test.pyto add sub-Typers totesting_app.
- apply_settings()¶
- async set_git_description()¶
- async set_commit_hash()¶
- property commit¶
- property description¶
- async run_git_command(cmd: str) CommandStatus¶