Concepts: CLI Generation¶
Dracon's command-line interface (CLI) generation bridges the gap between configuration management and application execution, providing a powerful and type-safe way to interact with your application.
The Core Idea: Model-Driven CLIs¶
Instead of manually writing argument parsing logic using libraries like argparse
or click
, Dracon generates the CLI directly from a Pydantic BaseModel
.
- Define Configuration: You define your application's configuration parameters, their types, defaults, and help text using a Pydantic model.
- Annotate for CLI: You use
typing.Annotated
anddracon.Arg
to customize how specific fields map to CLI arguments (e.g., short flags, positional arguments). - Generate Program: You call
dracon.make_program(YourModel, ...)
to create aProgram
instance. - Parse Arguments: You call
program.parse_args()
which handles:- Parsing standard CLI flags (
--option value
,-o val
) and positional arguments. - Generating a
--help
message automatically. - Handling special Dracon arguments:
+config/file.yaml
: Loads and merges specified YAML configuration files.--define.VAR=value
: Sets context variables for interpolation.- Applying overrides from the CLI onto the defaults and loaded files.
- Validating the final configuration against your Pydantic model.
- Returning the validated Pydantic model instance.
- Parsing standard CLI flags (
Configuration Loading and Precedence¶
This is where Dracon's CLI integrates seamlessly with its configuration loading capabilities. When program.parse_args()
runs, configuration sources are applied in a specific order, with later sources overriding earlier ones:
- Pydantic Model Defaults: Initial values defined in your
BaseModel
(field: int = 10
). +file1.yaml
: The first configuration file specified with+
is loaded and composed (including its own includes, merges, etc.). Its values override the Pydantic defaults.+file2.yaml
: The second+
file is loaded and merged onto the result of step 2 (using Dracon's default merge strategy<<{<+}[<~]
unless customized globally, though CLI merging isn't typically customized).- ... Subsequent
+fileN.yaml
files: Each is merged sequentially. --define.VAR=value
Context: Variables defined via--define.
are added to the context, potentially influencing subsequent interpolations within CLI argument values or during final resolution.-
CLI Argument Overrides (
--key value
, positional args): Values provided directly on the command line override any values from previous steps.- Nested Keys: Use dot notation (
--database.host db.prod
) to target nested fields within your Pydantic model. Dracon internally builds the necessary nested dictionary structure. - File Values: If an argument value starts with
+
(or the correspondingArg
hasis_file=True
), Dracon loads the referenced file/key path and uses its content as the value for that specific CLI argument, merging it appropriately if the target field expects a mapping or sequence. Example:--database +db_override.yaml
would loaddb_override.yaml
and merge its content into thedatabase
field.
- Nested Keys: Use dot notation (
-
Pydantic Validation: The final, merged dictionary representing the configuration is validated against your Pydantic model (
AppConfig.model_validate(...)
). This catches type errors, missing required fields, and runs custom validators.
Argument Mapping¶
- Field Names:
my_field_name
becomes--my-field-name
by default (can be customized withArg(long=...)
). - Types: Pydantic types determine expected input (str, int, float, bool).
bool
fields typically become flags (--verbose
). - Nested Models: Fields that are Pydantic models allow nested overrides using dot notation (
--database.port 5433
). Dracon handles constructing the nested dictionary. If the nested argument itself is marked withArg(is_file=True)
, passing a file path will load that file's content into that nested structure.
This integration means your CLI automatically respects your defined configuration structure, types, defaults, and validation rules, while also benefiting from Dracon's powerful file loading, merging, and interpolation features.