cyclopts icon indicating copy to clipboard operation
cyclopts copied to clipboard

Config command defaults (e.g. from toml or yaml file)

Open BrianPugh opened this issue 2 months ago • 5 comments

This PR aims to make it easier to supply configuration defaults from a configuration file by introducing a new cyclopts.App parameter called bound_args_transform.

bound_args_transform is a callable (or list of callables) that has signature:

 def bound_args_transform(commands: Tuple[str, ...], bound: inspect.BoundArguments) -> Any:
     ...

The supplied functions should add/modify the provided bound object based on some external configuration. The commands parameter are the string CLI commands/subcommands that lead up to the function-to-be-executed. For example,

# assuming "cmd" and "subcmd" are cyclopts commands.
$python my-script.py cmd subcmd --foo=bar

would result in commands == ("cmd", "subcmd")

Cyclopts has a few builtin transform classes for common situations for yaml, toml, and json. Example usage:

from cyclopts import App, bound_args_transforms

app = App(
    bound_args_transform=bound_args_transforms.Toml("pyproject.toml", root_keys=["tool", "mytoolname"])
)

Extending the above example, this would:

  1. Search for pyproject.toml in the current directory. If it's not found, do not modify the bound object at all.
  2. If it does exist, look inside for the table [tool.mytoolname.cmd.subcmd] and supply the key/value pairs for unset parameters.

Other nice parameters of the builtin transforms:

  • must_exist=False: whether or not the configuration file must exist.
  • search_parents=False: iteratively search parenting directories until a config file is found.

Resolves #87. @BrendanJM what do you think about the concepts outlined in this post? This branch is not in a functional state yet (and the implementation is not yet ready to be reviewed), but I was wondering if I could get your high level feedback?

BrianPugh avatar Apr 30 '24 05:04 BrianPugh