tyro¶
tyro.cli() is a tool for generating CLI interfaces from type-annotated Python.
We can define configurable scripts using functions:
# Write standard Python
from typing import Literal
def main(
name: str,
greet: Literal["Hello", "Hi"] = "Hi",
) -> None:
"""Print a greeting."""
print(f"{greet}, {name}!")
# Call tyro.cli()
if __name__ == "__main__":
import tyro
tyro.cli(main)
# tyro CLI $ python script.py --help usage: script.py [-h] [OPTIONS] Print a greeting. ╭─ options ──────────────────────────────╮ │ -h, --help show help message │ │ --name STR (required) │ │ --greet {Hello,Hi} (default: Hi) │ ╰────────────────────────────────────────╯ $ python script.py --name World Hi, World!
Or using structures like dataclasses:
# Write standard Python
from dataclasses import dataclass
from typing import Literal
@dataclass
class Args:
"""Configure a greeting."""
name: str
greet: Literal["Hello", "Hi"] = "Hi"
# Call tyro.cli()
if __name__ == "__main__":
import tyro
args = tyro.cli(Args)
print(f"{args.greet}, {args.name}!")
# tyro CLI $ python script.py --help usage: script.py [-h] [OPTIONS] Configure a greeting. ╭─ options ──────────────────────────────╮ │ -h, --help show help message │ │ --name STR (required) │ │ --greet {Hello,Hi} (default: Hi) │ ╰────────────────────────────────────────╯ $ python script.py --name World Hi, World!
Other features include helptext generation, nested structures, subcommands, and shell completion.
Why tyro?¶
Define things once. Standard Python type annotations, docstrings, and default values are parsed to automatically generate command-line interfaces with nice helptext.
Static types. Unlike tools dependent on dictionaries, YAML, or dynamic namespaces, arguments populated by
tyroare better undestood by IDEs and language servers, as well as static checking tools likepyrightandmypy.Modularity.
tyrosupports hierarchical configurations, which make it easy to decentralize definitions, defaults, and documentation.