rocrate_action_recorder.adapters.cyclopts¶
Adapter for Cyclopts CLI framework.
Attributes¶
Marker for Annotated argument that represent input file. |
|
Marker for Annotated argument that represent multiple input files. |
|
Marker for Annotated argument that represent input directory. |
|
Marker for Annotated argument that represent multiple input directories. |
|
Marker for Annotated argument that represent output file. |
|
Marker for Annotated argument that represent multiple output files. |
|
Marker for Annotated argument that represent output directory. |
|
Marker for Annotated argument that represent multiple output directories. |
|
Marker for Annotated boolean argument that trigger recording. |
|
Marker for Annotated Path argument that specifies the RO-Crate directory. |
|
Classes¶
Functions¶
|
Collect Annotated-style metadata from an annotation tree. |
|
Recursively collect all subcommands from a Cyclopts App. |
|
Extract plaintext description from a Cyclopts App's docstring. |
|
Extract Program information from a Cyclopts App. |
|
Check if a value is a Pydantic BaseModel instance. |
|
Check if a value is an attrs instance. |
|
Search recursively for a field value within parsed Cyclopts arguments. |
|
Resolve an argument value from Cyclopts bound arguments. |
|
Lookup a nested field value using dot notation. |
|
Resolve a CRATE_DIR-marked value to a concrete path. |
Resolve named Cyclopts arguments to path-bearing IOArgumentPath entries. |
|
|
Collect IOArgumentPaths from Cyclopts inputs. |
Extract markers from Pydantic model fields. |
|
|
Extract markers from attrs class fields. |
|
Check if an annotation is a Pydantic BaseModel class. |
|
Check if an annotation is an attrs class. |
Collect IO markers and record trigger from an argument collection. |
|
|
Collect IO markers and record trigger from a bound argument value. |
|
Collect IO markers and record trigger from parsed bound arguments. |
Auto-detect input/output arguments and optional record trigger from Annotated metadata. |
|
|
Evaluate whether recording should occur for this invocation. |
|
Find the app node that owns the executed default command. |
|
|
|
Return whether a SystemExit represents a successful exit. |
|
Takes {"mysub": {"something": "valuefromconfig"}} and returns {"mysub.something"}. |
|
|
|
Context manager to record a Cyclopts CLI invocation in an RO-Crate. |
Module Contents¶
- rocrate_action_recorder.adapters.cyclopts.logger¶
- rocrate_action_recorder.adapters.cyclopts.INPUT_FILE: LiteralString = 'INPUT_FILE'¶
Marker for Annotated argument that represent input file.
- rocrate_action_recorder.adapters.cyclopts.INPUT_FILES: LiteralString = 'INPUT_FILES'¶
Marker for Annotated argument that represent multiple input files.
- rocrate_action_recorder.adapters.cyclopts.INPUT_DIR: LiteralString = 'INPUT_DIR'¶
Marker for Annotated argument that represent input directory.
- rocrate_action_recorder.adapters.cyclopts.INPUT_DIRS: LiteralString = 'INPUT_DIRS'¶
Marker for Annotated argument that represent multiple input directories.
- rocrate_action_recorder.adapters.cyclopts.OUTPUT_FILE: LiteralString = 'OUTPUT_FILE'¶
Marker for Annotated argument that represent output file.
- rocrate_action_recorder.adapters.cyclopts.OUTPUT_FILES: LiteralString = 'OUTPUT_FILES'¶
Marker for Annotated argument that represent multiple output files.
- rocrate_action_recorder.adapters.cyclopts.OUTPUT_DIR: LiteralString = 'OUTPUT_DIR'¶
Marker for Annotated argument that represent output directory.
- rocrate_action_recorder.adapters.cyclopts.OUTPUT_DIRS: LiteralString = 'OUTPUT_DIRS'¶
Marker for Annotated argument that represent multiple output directories.
- rocrate_action_recorder.adapters.cyclopts.RECORD_TRIGGER: LiteralString = 'RECORD_TRIGGER'¶
Marker for Annotated boolean argument that trigger recording.
- rocrate_action_recorder.adapters.cyclopts.CRATE_DIR: LiteralString = 'CRATE_DIR'¶
Marker for Annotated Path argument that specifies the RO-Crate directory.
- rocrate_action_recorder.adapters.cyclopts._annotation_markers(annotation: Any, extra_metadata: collections.abc.Iterable[Any] = ()) list[Any][source]¶
Collect Annotated-style metadata from an annotation tree.
This unwraps nested
Annotatedvalues that may be wrapped insideOptional/union annotations.
- rocrate_action_recorder.adapters.cyclopts._collect_subcommands(app: cyclopts.App, parent_name: str, seen: set[str] | None = None) dict[str, rocrate_action_recorder.core.Program][source]¶
Recursively collect all subcommands from a Cyclopts App.
- Parameters:
app – The Cyclopts App instance to collect from.
parent_name – The accumulated name path of parent commands.
seen – Set of app name strings to track visited apps and avoid infinite recursion.
- Returns:
Dictionary mapping command names to Program objects.
- rocrate_action_recorder.adapters.cyclopts._plaintext_doc(app: cyclopts.App) str[source]¶
Extract plaintext description from a Cyclopts App’s docstring.
- rocrate_action_recorder.adapters.cyclopts.program_from_app(app: cyclopts.App) rocrate_action_recorder.core.Program[source]¶
Extract Program information from a Cyclopts App.
- Parameters:
app – The Cyclopts App instance.
- Returns:
Program with command and selected subcommand information.
- rocrate_action_recorder.adapters.cyclopts._is_pydantic_model(value: Any) bool[source]¶
Check if a value is a Pydantic BaseModel instance.
- rocrate_action_recorder.adapters.cyclopts._is_attrs_instance(value: Any) bool[source]¶
Check if a value is an attrs instance.
- rocrate_action_recorder.adapters.cyclopts._search_argument_value(value: Any, field_name: str) Any | None[source]¶
Search recursively for a field value within parsed Cyclopts arguments.
- Parameters:
value – Value to inspect.
field_name – Field name to resolve.
- Returns:
The resolved value, or None if the field cannot be found.
- rocrate_action_recorder.adapters.cyclopts._lookup_argument_value(arguments: dict[str, Any], field_name: str) Any | None[source]¶
Resolve an argument value from Cyclopts bound arguments.
Cyclopts stores grouped parameters, such as dataclass-backed option groups, under their parent parameter name in
bound_args.arguments. This helper resolves both top-level and nested field values.- Parameters:
arguments – Parsed Cyclopts bound arguments.
field_name – Field name to resolve. Supports dot notation for nested fields.
- Returns:
The resolved value, or None if the field cannot be found.
- rocrate_action_recorder.adapters.cyclopts._lookup_nested_field(value: Any, field_path: str) Any | None[source]¶
Lookup a nested field value using dot notation.
- Parameters:
value – The value to search in (Pydantic model, dataclass, attrs, dict, etc.).
field_path – Dot-separated field path (e.g., “io.input”).
- Returns:
The resolved value, or None if the field cannot be found.
- rocrate_action_recorder.adapters.cyclopts._resolve_crate_dir_value(value: Any, field_name: str) pathlib.Path | None[source]¶
Resolve a CRATE_DIR-marked value to a concrete path.
- Parameters:
value – Parsed argument value.
field_name – Argument name used for developer-facing errors.
- Returns:
A resolved crate directory path, or None when the value is intentionally unset.
- Raises:
ValueError – If the CRATE_DIR marker is applied to a non-path-like value.
- rocrate_action_recorder.adapters.cyclopts._resolve_io_argument_paths(names: list[str], name_info: dict[str, tuple[str, str]], arguments: dict[str, Any]) list[rocrate_action_recorder.core.IOArgumentPath][source]¶
Resolve named Cyclopts arguments to path-bearing IOArgumentPath entries.
- Parameters:
names – IO argument names to resolve.
name_info – Mapping from CLI argument name to bound field name and help text.
arguments – Parsed Cyclopts bound arguments.
- Returns:
Resolved IO argument path entries.
- rocrate_action_recorder.adapters.cyclopts._collect_ioargs(bound_args: inspect.BoundArguments, ios: rocrate_action_recorder.adapters.shared.IOArgumentNames, argument_collection: cyclopts.argument.ArgumentCollection) rocrate_action_recorder.core.IOArgumentPaths[source]¶
Collect IOArgumentPaths from Cyclopts inputs.
- Parameters:
bound_args – Parsed Cyclopts bound arguments.
ios – Parameter names that map to input/output files and directories.
argument_collection – Assembled Cyclopts argument collection (from the executed subapp).
- Returns:
A IOArgumentPaths instance
- rocrate_action_recorder.adapters.cyclopts._extract_markers_from_pydantic_fields(model_cls: Any, prefix: str = '') list[tuple[str, str]][source]¶
Extract markers from Pydantic model fields.
- Parameters:
model_cls – Pydantic model class.
prefix – Field name prefix for nested fields.
- Returns:
List of (field_path, marker) tuples.
- rocrate_action_recorder.adapters.cyclopts._extract_markers_from_attrs_fields(attrs_cls: Any, prefix: str = '') list[tuple[str, str]][source]¶
Extract markers from attrs class fields.
- Parameters:
attrs_cls – attrs class.
prefix – Field name prefix for nested fields.
- Returns:
List of (field_path, marker) tuples.
- rocrate_action_recorder.adapters.cyclopts._is_pydantic_model_type(ann: Any) bool[source]¶
Check if an annotation is a Pydantic BaseModel class.
- rocrate_action_recorder.adapters.cyclopts._is_attrs_type(ann: Any) bool[source]¶
Check if an annotation is an attrs class.
- rocrate_action_recorder.adapters.cyclopts._collect_ios_from_argument_collection(collection: cyclopts.argument.ArgumentCollection, ios: rocrate_action_recorder.adapters.shared.IOArgumentNames, record_trigger_name: str | None, crate_dir_name: str | None) tuple[str | None, str | None][source]¶
Collect IO markers and record trigger from an argument collection.
- Parameters:
collection – Argument collection to inspect.
ios – IO marker accumulator.
record_trigger_name – Current record trigger name, if any.
crate_dir_name – Current crate dir argument name, if any.
- Returns:
Updated record trigger name and crate dir argument name.
- rocrate_action_recorder.adapters.cyclopts._collect_ios_from_bound_value(value: Any, ios: rocrate_action_recorder.adapters.shared.IOArgumentNames, record_trigger_name: str | None, crate_dir_name: str | None, prefix: str = '') tuple[str | None, str | None][source]¶
Collect IO markers and record trigger from a bound argument value.
- Parameters:
value – Bound argument value to inspect.
ios – IO marker accumulator.
record_trigger_name – Current record trigger name, if any.
crate_dir_name – Current crate dir argument name, if any.
prefix – Optional field prefix for nested models.
- Returns:
Updated record trigger name and crate dir argument name.
- rocrate_action_recorder.adapters.cyclopts._collect_ios_from_bound_arguments(bound_args: inspect.BoundArguments, ios: rocrate_action_recorder.adapters.shared.IOArgumentNames, record_trigger_name: str | None, crate_dir_name: str | None) tuple[str | None, str | None][source]¶
Collect IO markers and record trigger from parsed bound arguments.
- Parameters:
bound_args – Parsed Cyclopts bound arguments.
ios – IO marker accumulator.
record_trigger_name – Current record trigger name, if any.
crate_dir_name – Current crate dir argument name, if any.
- Returns:
Updated record trigger name and crate dir argument name.
- rocrate_action_recorder.adapters.cyclopts._detect_ios_and_trigger(argument_collection: cyclopts.argument.ArgumentCollection, command: Any | None = None, meta_argument_collection: cyclopts.argument.ArgumentCollection | None = None, bound_args: inspect.BoundArguments | None = None) tuple[rocrate_action_recorder.adapters.shared.IOArgumentNames, str | None, str | None][source]¶
Auto-detect input/output arguments and optional record trigger from Annotated metadata.
- Parameters:
argument_collection – Assembled Cyclopts argument collection.
command – The command function to check for *args.
meta_argument_collection – Optional meta app argument collection to check for triggers.
- Returns:
A tuple of (IOArgumentNames, trigger_arg_name_or_None, crate_dir_arg_name_or_None).
- rocrate_action_recorder.adapters.cyclopts._should_record(bound_args: inspect.BoundArguments, record_trigger_name: str | None) bool[source]¶
Evaluate whether recording should occur for this invocation.
- Parameters:
bound_args – Parsed Cyclopts bound arguments.
record_trigger_name – Optional trigger argument name.
- Returns:
True when recording is enabled, otherwise False.
- rocrate_action_recorder.adapters.cyclopts._resolve_executed_subapp(app: cyclopts.App, command: Any) cyclopts.App | None[source]¶
Find the app node that owns the executed default command.
- Parameters:
app – App node to inspect.
command – Resolved callable returned by
parse_args.
- Returns:
Matching app instance, or None when no match is found.
- rocrate_action_recorder.adapters.cyclopts._parse_tokens(tokens: str | collections.abc.Iterable[str] | None = None) list[str][source]¶
- rocrate_action_recorder.adapters.cyclopts._is_successful_system_exit(error: SystemExit) bool[source]¶
Return whether a SystemExit represents a successful exit.
- class rocrate_action_recorder.adapters.cyclopts.Info[source]¶
-
- crate_dir: pathlib.Path | None = None¶
- rocrate_action_recorder.adapters.cyclopts._flatten_keys(d: dict, separator='.') set[str][source]¶
Takes {“mysub”: {“something”: “valuefromconfig”}} and returns {“mysub.something”}.
- rocrate_action_recorder.adapters.cyclopts.collect_info(app: cyclopts.App, tokens: str | collections.abc.Iterable[str] | None = None, software_version: str | None = None) Info[source]¶
- rocrate_action_recorder.adapters.cyclopts.record_cyclopts(app: cyclopts.App, tokens: str | collections.abc.Iterable[str] | None = None, dataset_license: str | None = None, crate_dir: pathlib.Path | None = None, software_version: str | None = None, current_user: str | None = None) collections.abc.Generator[cyclopts.App]¶
Context manager to record a Cyclopts CLI invocation in an RO-Crate.
Hint
Marker metadata (for example
INPUT_FILEandOUTPUT_FILE) is auto-detected fromtyping.Annotatedparameters and nested models. Recording writesro-crate-metadata.jsononly when execution finishes successfully and recording is enabled.Examples
Full runnable example: https://github.com/i-VRESSE/rocrate-action-recorder/tree/main/example/cyclopts
Basic positional input/output tracking:
from pathlib import Path from typing import Annotated from cyclopts import App from rocrate_action_recorder.adapters.cyclopts import ( INPUT_FILE, OUTPUT_FILE, record_cyclopts, ) app = App(version="1.2.3") @app.default def main( input: Annotated[Path, INPUT_FILE], output: Annotated[Path, OUTPUT_FILE], /, ): output.write_text(input.read_text().upper()) # Call as: myscript.py input.txt output.txt with record_cyclopts(app, dataset_license="CC-BY-4.0"): app()
Toggle recording with a boolean trigger flag:
from typing import Annotated from cyclopts import App, Parameter from rocrate_action_recorder.adapters.cyclopts import RECORD_TRIGGER, record_cyclopts app = App() @app.default def main(*, prov: Annotated[bool, Parameter(negative=""), RECORD_TRIGGER] = False): pass # Records only when --prov is passed. # Call as: myscript.py --prov with record_cyclopts(app): app()
Track nested configuration fields (for example dataclass or Pydantic models):
from dataclasses import dataclass from pathlib import Path from typing import Annotated from cyclopts import App from rocrate_action_recorder.adapters.cyclopts import INPUT_FILE, OUTPUT_FILE, record_cyclopts @dataclass class IO: input: Annotated[Path, INPUT_FILE] output: Annotated[Path, OUTPUT_FILE] app = App() @app.default def main(io: IO): io.output.write_text(io.input.read_text().upper()) # Call as: myscript.py input.txt output.txt with record_cyclopts(app): app()
Record multiple inputs/outputs from list markers:
from pathlib import Path from typing import Annotated from cyclopts import App from rocrate_action_recorder.adapters.cyclopts import ( INPUT_FILES, OUTPUT_FILES, record_cyclopts, ) app = App() @app.default def main( *, inputs: Annotated[list[Path], INPUT_FILES], outputs: Annotated[list[Path], OUTPUT_FILES], ): for src, dst in zip(inputs, outputs, strict=True): dst.write_text(src.read_text().upper()) # Call as: myscript.py --inputs in1.txt --inputs in2.txt --outputs out1.txt --outputs out2.txt with record_cyclopts(app): app()
Let CLI arguments choose the crate destination using
CRATE_DIR:from pathlib import Path from typing import Annotated from cyclopts import App from rocrate_action_recorder.adapters.cyclopts import CRATE_DIR, record_cyclopts app = App() @app.default def main(*, session_dir: Annotated[Path, CRATE_DIR]): pass # The CRATE_DIR-marked value overrides record_cyclopts(crate_dir=...). # Call as: myscript.py --session-dir ./runs/session-001 with record_cyclopts(app, crate_dir=Path("fallback-crate")): app()
Subcommands are supported; wrap the root app once and invoke normally:
app = App(name="tool") process = App(name="process") @process.default def run(...): ... app.command(process) # Call as: tool process with record_cyclopts(app): app()
Use config file to override default prov trigger value:
from typing import Annotated from cyclopts import App, Parameter from cyclopts.config import Toml from rocrate_action_recorder.adapters.cyclopts import RECORD_TRIGGER, record_cyclopts app = App(config=Toml("myconfig.toml")) @app.default def main(*, prov: Annotated[bool, Parameter(negative=""), RECORD_TRIGGER] = False): pass with record_cyclopts(app): app()
Create a myconfig.toml file containing:
prov = true
When script is called then provenance is always recorded.
- Parameters:
app – Root Cyclopts App instance.
tokens – Optional command arguments used for parsing and action id generation.
dataset_license – Optional dataset license string. If absent ro-crate will be invalid.
crate_dir – Optional path to RO-Crate directory. If a parsed argument is annotated with
CRATE_DIR, that value takes precedence.software_version – Optional software version override. Otherwise extracted from App instance.
current_user – Optional user override. Uses current system user if None.