CLI Overrides
Override configuration values from the command line with automatic file and override detection.
Auto-Detection Pattern
Dead Simple CLI Integration
Just loop over CLI arguments - config.update() automatically detects whether each string is a file path or an override!
- Strings with
=→ Parsed as overrides (e.g.,key=value,=key=value,~key) - Strings without
=→ Loaded as file paths - No manual separation needed!
Quick Start
Override Syntax
Three operators for fine-grained control:
| Operator | Syntax | Behavior | Example |
|---|---|---|---|
| Compose (default) | key=value |
Merges dicts, extends lists | model::lr=0.001 |
| Replace | =key=value |
Completely replaces value | =model={'_target_': 'ResNet'} |
| Delete | ~key |
Removes key (idempotent) | ~debug |
Type Inference
Values are automatically typed using ast.literal_eval():
lr=0.001→floatepochs=100→intdebug=True→booldevices=[0,1,2]→listconfig={'lr':0.001}→dictname=resnet50→str(fallback)
The = Dual Purpose
- In
key=value→ Assignment operator (CLI syntax) - In
=key=value→ Replace operator prefix (config operator)
Adding Your Own Flags
The examples above show minimal integration. You can add your own flags (e.g., --verbose, --device) alongside the config inputs - Sparkwheel only cares about the arguments you pass to config.update()!
Advanced: Manual Override Parsing
If you need to separate override parsing from application, use parse_overrides():
from sparkwheel import Config, parse_overrides
# Manually parse overrides
overrides = parse_overrides(["model::lr=0.001", "=optimizer={'type':'sgd'}", "~debug"])
# Result: {"model::lr": 0.001, "=optimizer": {"type": "sgd"}, "~debug": None}
config = Config()
config.update("base.yaml")
config.update(overrides)
parse_overrides() Syntax
parse_overrides() only supports key=value syntax (no --key value flag style).
Schema Validation
Add continuous validation with dataclasses:
import argparse
from dataclasses import dataclass
from sparkwheel import Config
@dataclass
class TrainingConfig:
model: dict
optimizer: dict
trainer: dict
parser = argparse.ArgumentParser()
parser.add_argument("inputs", nargs="+")
args = parser.parse_args()
# Validates on every update!
config = Config(schema=TrainingConfig)
for item in args.inputs:
config.update(item) # Raises ValidationError if invalid
config.freeze() # Lock the config
model = config.resolve("model")
Usage:
Validation Errors
Invalid overrides raise ValidationError immediately - helps catch config errors early!
Next Steps
- Configuration Basics - Loading and accessing configs
- Operators - Composition, replacement, and deletion
- Schema Validation - Type-safe configs with dataclasses
- API Reference - Full API documentation