CLI Options
CLI Options in this project are named parameters passed to commands, typically prefixed with dashes (e.g., --name or -n). They are implemented using a two-layer system: a metadata layer for definition and a core execution layer that integrates with Click.
Defining Options
Options are defined using the typer.Option() function, which returns an OptionInfo object. While options can be defined as default values in function signatures, the recommended modern approach in this codebase is using Annotated.
import typer
from typing import Annotated
app = typer.Typer()
@app.command()
def main(
name: Annotated[str, typer.Option(help="The person to greet")] = "World",
lastname: Annotated[str, typer.Option(prompt=True)] = "Doe"
):
print(f"Hello {name} {lastname}")
When a parameter is defined with typer.Option(), it is treated as a named CLI option. If no explicit name is provided (e.g., "--name"), Typer automatically generates one based on the function parameter name.
The Metadata Layer: OptionInfo and ParameterInfo
The configuration of an option is first captured in typer.models.OptionInfo. This class acts as a data container that stores all the settings provided to typer.Option().
ParameterInfo
OptionInfo inherits from ParameterInfo, which contains metadata shared between both Options and Arguments. This includes:
- Default Values:
defaultanddefault_factoryfor dynamic defaults. - Validation: Constraints like
min,max,clampfor numbers, andexists,file_okay,dir_okayfor paths. - Environment Variables:
envvarallows the option to pull its value from the environment. - Help Metadata:
help,hidden, andrich_help_panel.
OptionInfo
OptionInfo adds option-specific metadata found in typer/models.py:
- Prompts:
prompt,confirmation_prompt, andhide_input. - Counters:
countfor incrementing integer flags (e.g.,-vvv). - Auto-env:
allow_from_autoenvfor automatic environment variable mapping.
The Execution Layer: TyperOption
During command registration in typer/main.py, OptionInfo is converted into a typer.core.TyperOption. This class inherits from click.core.Option and provides the actual logic for CLI interaction.
TyperOption overrides several Click methods to provide enhanced functionality:
get_help_record(): Customizes how the option appears in the help text. It specifically handles Typer's unique boolean flag support where only names forFalsevalues might be provided._get_default_string(): A Typer-specific override to format how default values are displayed in help menus, ensuring consistency with Rich formatting.- Rich Integration: The
rich_help_panelattribute allows grouping options into distinct sections in the help output when Rich is enabled.
Key Features and Behaviors
Prompts and Confirmation
Typer supports interactive prompts if an option is missing. This is configured via OptionInfo and executed by TyperOption.
@app.command()
def delete(
project: Annotated[str, typer.Option(prompt=True, confirmation_prompt=True)]
):
# User will be prompted to enter the project name twice
print(f"Deleting project {project}")
Automatic Flag Detection
In this codebase, boolean parameters are automatically treated as flags. The TyperOption class handles the generation of secondary options (like --no-force for a --force flag).
Note: The
is_flagandflag_valueparameters inOptionInfoare deprecated. Typer relies on thebooltype hint to determine if an option should behave as a flag.
Hidden Options and Help Panels
Options can be excluded from the help text using hidden=True. For complex CLIs, rich_help_panel can be used to organize options into logical groups.
@app.command()
def sync(
config: Annotated[str, typer.Option(rich_help_panel="Config and Setup")] = "base.yaml",
verbose: Annotated[bool, typer.Option(rich_help_panel="Output Settings")] = False,
internal_id: Annotated[str, typer.Option(hidden=True)] = "secret-123"
):
...
Validation Constraints
Because OptionInfo inherits from ParameterInfo, options support a wide range of validations defined in typer/models.py:
| Constraint | Description |
|---|---|
min / max | Numeric range validation for int or float. |
exists | Ensures a Path exists on the filesystem. |
formats | A list of valid datetime formats for parsing. |
case_sensitive | Controls case sensitivity for Enum choices. |
These constraints are passed down to the underlying Click types during the conversion from OptionInfo to TyperOption.