brentyi / tyro

CLI interfaces & config objects, from types
https://brentyi.github.io/tyro
MIT License
467 stars 23 forks source link

Helper for dispatching sub commands? Create the neede dict for subcommand_cli_from_dict() ? #139

Open jedie opened 4 months ago

jedie commented 4 months ago

I come from click. Tyro has some nice new concepts... But i missed a easy way to compose sub commands to a CLI.

https://brentyi.github.io/tyro/examples/02_nesting/05_subcommands_func/ described to use tyro.extras.subcommand_cli_from_dict(), but then i have to specify a dict to map the functions :(

Think this can be done with a small helper. So that i just need to add a decorator to the sub command function, like clicks @click.command()

It there something like this around?!?

brentyi commented 4 months ago

Hi @jedie!

This unfortunately doesn't exist, and unless we decide to extend the tyro API you'd have to write a utility yourself. But for the basic functionality, yes, it'd just be a small helper, eg:

# script.py

from cli_helper import command, run_cli

@command
def checkout(branch: str) -> None:
    """Check out a branch."""
    print(f"{branch=}")

@command
def commit(message: str, all: bool = False) -> None:
    """Make a commit."""
    print(f"{message=} {all=}")

if __name__ == "__main__":
    run_cli()
# cli_helper.py

from typing import Callable, TypeVar

import tyro

_subcommands = []
CallableT = TypeVar("CallableT", bound=Callable)

def command(func: CallableT) -> CallableT:
    _subcommands.append(func)
    return func

def run_cli() -> None:
    tyro.extras.subcommand_cli_from_dict({v.__name__: v for v in _subcommands})

We could also add something like this to tyro.extras.

jedie commented 4 months ago

We could also add something like this to tyro.extras.

Sound a good idea!