utils¶
Shared utilities: status enums, CLI overlay sentinels, and async helpers.
- otto.utils.split_on_commas(values: list[str] | str) list[str]¶
Split a string or list of strings on commas into a flat list.
- Parameters:¶
values – A single comma-separated string, or a list of such strings.
- Returns:¶
A flat list of the individual values.
>>> split_on_commas("a,b,c") ['a', 'b', 'c'] >>> split_on_commas(["a,b", "c,d"]) ['a', 'b', 'c', 'd'] >>> split_on_commas("single") ['single']
- otto.utils.complete_comma_list(candidates: list[str], incomplete: str) list[str]¶
Filter candidates for tab-completing one entry of a comma-separated option.
Options like
--lab a,band--tests x,ytake a comma-joined value, which the shell hands to the completer as a singleincompleteword. Complete only the final (in-progress) segment, keep the already-typed prefix intact, and drop candidates already present earlier in the list so completion never re-offers them.>>> complete_comma_list(["tech1", "tech2", "prod"], "tech") ['tech1', 'tech2'] >>> complete_comma_list(["tech1", "tech2", "prod"], "tech1,te") ['tech1,tech2']
- otto.utils.async_typer_command(f: Callable[[P], Coroutine[Any, Any, R]]) Callable[[P], R]¶
Wrap an async Typer command so it runs under the active
OttoContextscope.Calls
asyncio.runon the coroutine. If anOttoContextis already open (i.e.try_get_context()returns one), the coroutine runs inside its async context manager scope; otherwise it runs bare.
-
class otto.utils.Arg(variadic: bool =
False, elem_type: type | None =None, name: str | None =None, help: str | None =None)¶ Bases:
objectCLI overlay: force a parameter to a positional argument.
variadic=Truemakes it a space-separated list ofelem_type(used for Python-union list params Typer can’t read, e.g.str | Sequence[...]).elem_typealso overrides the CLI type for a scalar union.namesets the argument’s displayed metavar (e.g.Arg(name="SOURCE")showsSOURCEin--helpinstead of the parameter’s Python name); it does not change how the argument is passed, since positional arguments have no flag. Imports no typer.
-
class otto.utils.Opt(elem_type: type | None =
None, name: str | None =None, help: str | None =None)¶ Bases:
objectCLI overlay: force a parameter to a
--option. Imports no typer.nameoverrides the synthesized flag (e.g.Opt(name="--dest")makes the CLI flag--destregardless of the parameter’s Python name); the value is still bound to the original Python parameter. When omitted, the flag defaults to--<param-name>as usual.
-
otto.utils.cli_exposed(fn: Callable[[...], Any] | None =
None, *, name: str | None =None, help_: str | None =None, success: str | None =None, output_dir: bool =True) Callable[[...], Any]¶ Mark a host coroutine method for auto-exposure as an
otto hostsubcommand.namedefaults to the method name with underscores dashed.successis an optional message printed on a successful(Status, "")result (e.g. “Transfer complete.”).output_dir=Falsemarks a read-only verb that creates no per-invocation output directory (e.g.exists/lsmod); the defaultTruekeeps one.Usable bare (
@cli_exposed) or called (@cli_exposed(name=..., ...)).
- otto.utils.is_literal(value: Any, literal_type: type[T]) T¶
Raise a TypeError if value is not a valid member of the Literal type.