CLI Integration¶
Vidhi provides automatic CLI argument parsing for your configuration classes.
Basic Usage¶
Use parse_cli_args() to parse command-line arguments into a typed config:
from vidhi import frozen_dataclass, field, parse_cli_args
@frozen_dataclass
class Config:
host: str = field("localhost", help="Server host")
port: int = field(8080, help="Server port")
workers: int = field(4, help="Number of workers")
config = parse_cli_args(Config)
Running python app.py --help:
usage: app.py [options]
Built-in Options:
-h, --help show this help message and exit
--config <path> load configuration from YAML file
--install-shell-completions [shell]
install shell completions and exit
--export-json-schema [path]
export JSON schema for IDE autocomplete
Options:
--host <str> [localhost]
Server host
--port <int> [8080]
Server port
--workers <int> [4]
Number of workers
Field Metadata¶
Use the field() helper to add CLI metadata:
from vidhi import frozen_dataclass, field
@frozen_dataclass
class Config:
# Basic field with help text
host: str = field("localhost", help="Server hostname")
# Field with custom CLI name (alias)
learning_rate: float = field(0.001, help="Learning rate", name="lr")
# Field with multiple aliases
output_dir: str = field(
"./output",
help="Output directory",
aliases=["out", "o"]
)
This generates:
--host <str> [localhost]
Server hostname
--lr <float> [0.001]
Learning rate
--output_dir, --out, --o <str> [./output]
Output directory
Nested Configurations¶
Nested configs use dot notation in CLI arguments:
from dataclasses import field
from vidhi import frozen_dataclass
@frozen_dataclass
class DatabaseConfig:
host: str = "localhost"
port: int = 5432
@frozen_dataclass
class AppConfig:
name: str = "MyApp"
database: DatabaseConfig = field(default_factory=DatabaseConfig)
CLI usage:
python app.py --database.host db.example.com --database.port 5433
Boolean Arguments¶
Boolean fields require explicit true or false values:
@frozen_dataclass
class Config:
debug: bool = False
use_cache: bool = True
CLI usage:
python app.py --debug true
python app.py --use_cache false
Accepted values: true/false, yes/no, 1/0
The --help output shows boolean fields with {true,false} choices:
--debug {true,false} [False]
Enable debug mode
--use_cache {true,false} [True]
Enable caching
List Arguments¶
List fields accept multiple values:
from typing import List
@frozen_dataclass
class Config:
hosts: List[str] = field(default_factory=list)
ports: List[int] = field(default_factory=lambda: [8080, 8081])
CLI usage:
python app.py --hosts server1 server2 server3
python app.py --ports 9000 9001 9002
Polymorphic Type Selection¶
For polymorphic configs, use --<field>.type to select the variant:
@frozen_dataclass
class AppConfig:
cache: BaseCacheConfig = field(default_factory=MemoryCacheConfig)
scheduler: BaseSchedulerConfig = field(default_factory=FifoScheduler)
CLI usage:
# Select cache type
python app.py --cache.type redis --cache.host redis.example.com
# Select scheduler type
python app.py --scheduler.type priority --scheduler.levels 10
# Nested polymorphic (pool inside redis cache)
python app.py --cache.type redis --cache.pool.type sentinel \
--cache.pool.sentinels "host1:26379,host2:26379"
The --help output groups options by variant:
Cache Options:
Select variant with --cache.type {memory,redis,memcached}
Cache -> memory
--cache.ttl_seconds <int> [3600]
--cache.max_entries <int> [10000]
--cache.eviction_policy <str> [lru]
Cache -> redis
--cache.ttl_seconds <int> [3600]
--cache.host <str> [localhost]
--cache.port <int> [6379]
YAML File Loading¶
Use --config to load configuration from a YAML file:
python app.py --config config.yaml
# CLI arguments override YAML values
python app.py --config config.yaml --port 9000
Overriding Programmatic Defaults¶
Use with_cli_overrides() when you define defaults in code:
from vidhi import with_cli_overrides
def create_config():
return AppConfig(
model="resnet50",
batch_size=32,
)
# Allows CLI to override the programmatic defaults
config = with_cli_overrides(create_config())
Priority order: CLI args > YAML file > code defaults