CLI Argument Parsing
The configuration system supports parsing command-line interface (CLI) arguments into commands, arguments and options using the format:
my-app [<command>] [<arguments>] [--<option-1-name> <option-1-value>] [--<option-2-name>]
Where:
- command: is the first argument, which may be omitted if a default command is defined
- arguments: are one or more positional arguments following the command
- options: are one or more flags before or after the arguments, which can pass in a value or be a standalone boolean flag
Command-line arguments are defined as an argsparse spec in a YAML file (e.g., args.yaml). ConfigArgsParser reads this spec, resolves help and default expressions against the Config it is given and returns a DictConfig.
The values of the DictConfig are set based on the config key for each argument or option, with the command stored under the path <key>.command (where key is passed into ConfigArgsParser and defaults to None). This DictConfig can then be added to the override layer of the configuration using add_overrides.
Arguments and options automatically:
- Resolve expressions using the provided configuration
- Save override configuration values to the path specified by the
configkey - Provide help text and validation
- Support type conversion
- Support short option names (e.g.,
-yfor--auto-confirm)
If the command contains an argument or option that is invalid, or does not contain a required argument or option, a short usage line is printed with an error message.
If -h or --help is passed, the complete help for the current command will be displayed, with the epilog from the arguments configuration for that command appended at the end. The epilog can be used to include examples or other text which further clarifies the command.
Argument Spec
The top-level spec declares a default_command, global_options (flags accepted before or after any command), and commands, with the latter usually split into per-command files via includes:
# args.yaml
includes:
- commands/run.yaml
cli:
default_command: run
global_options:
verbose:
short_name: v
type: bool
action: store_true
help: "Enable verbose logging"
config: logging.verboseEach command declares positional arguments and named options. This run command exercises the full grammar:
# commands/run.yaml
cli:
commands:
run:
description: Run the application server.
epilog: |
Examples:
myapp run ./app.yaml
myapp run ./app.yaml --host 0.0.0.0 --port 8080 --workers 4 --reload
arguments: # positional, in declaration order (always required when defined)
config_file:
type: str
help: "Path to the app config file"
config: run.config_file
options: # named flags
host:
type: str
default: localhost
help: "Interface to bind (default: ${server.host})"
config: server.host
port:
short_name: p # also accepts -p
type: int
default: 8080
help: "Port to listen on"
config: server.port
workers:
type: int
required: true # options are optional unless required
help: "Number of worker processes"
config: server.workers
log-level:
type: str
choices: [debug, info, warning, error]
default: info
help: "Logging verbosity"
config: logging.level
reload:
type: bool
action: store_true # boolean flag; consumes no value
help: "Restart workers when files change"
config: server.reloadThe argument parser reads the YAML spec file and uses it to parse the command and its arguments and options. The parsed values are then saved to the configuration at the path specified by the config key for each argument or option.
For example, given this code:
from .global_config import config
args_config = ConfigArgsParser.parse(config=config, spec="args.yaml", key="cli")
config.add_overrides(args_config)Running myapp run ./app.yaml -p 9000 --reload would:
- Store the resolved comment name at
cli.command(thekeyyou passed toparse). - Store the positional
./app.yamlargument atrun.config_file. - Store the option flags
-p 9000and--reloadatserver.portandserver.reload, respectively. - Store the default values defined for the option flags
hostandlog-level(i.e.,localhostandinfo) intoserver.hostandlogging.level, respectively.
These values would then all be added into the overrides layer, overriding all other values of the configuration.
Argument Grammar
Each entry under arguments (positional) or options / global_options (named flags) accepts:
config: dot-path where the parsed value is written (omit it and the value is parsed but not stored)type:str(default),int,float,bool, or a fully-qualified type path (resolved via theimportmachinery)help: help text; may contain${...}expressions resolved against the provided config.default: value used when the flag is absentchoices: list of allowed valuesaction: an argparse action such asstore_true/store_false(boolean flags consume no value)required: whether the option is required (options only; positionals are always required)short_name: a single-character alias, e.g.,p→-p(options only)
Each command entry (a value under commands) accepts:
description: the command’s full help text, shown in<command> --helphelp: a one-line summary shown in the parent command listing (falls back todescription)epilog: text appended after the help, e.g., usage examplesarguments: positional arguments (a mapping of name to the argument grammar above)options: named flags (a mapping of name to the argument grammar above)commands: nested subcommands, one level deep; each value is itself a command entrydefault_command: the subcommand injected when the user omits it (only meaningful alongsidecommands)
The resolved command is written to {key}.command (subcommands as command:subcommand).
When not using commands, set the default_command to default and define your arguments and options under cli.commands.default.