0
# CLI Creation
1
2
Automatic CLI creation functions that generate command-line interfaces from function and class signatures with minimal boilerplate code. These functions analyze type hints and docstrings to automatically create ArgumentParser instances, parse arguments, and execute the target components.
3
4
## Capabilities
5
6
### Automatic CLI Functions
7
8
High-level functions for creating complete command-line interfaces automatically from Python functions, classes, or modules.
9
10
```python { .api }
11
def auto_cli(
12
components: Optional[Union[Callable, List, Dict, Type]] = None,
13
args: Optional[List[str]] = None,
14
config_help: str = "Path to a configuration file.",
15
set_defaults: Optional[Dict[str, Any]] = None,
16
as_positional: bool = True,
17
fail_untyped: bool = True,
18
parser_class: Type[ArgumentParser] = ArgumentParser,
19
**kwargs
20
) -> Any:
21
"""
22
Create a CLI from components and run it.
23
24
Args:
25
components: Function, class, list, or dict to create CLI from
26
args: Command line arguments to parse (defaults to sys.argv)
27
config_help: Help text for configuration file option
28
set_defaults: Default values to set in parser
29
as_positional: Whether to add component as positional argument
30
fail_untyped: Whether to fail on untyped parameters
31
parser_class: ArgumentParser class to use
32
**kwargs: Additional arguments for ArgumentParser
33
34
Returns:
35
Any: Result of running the CLI component
36
"""
37
38
def CLI(*args, **kwargs) -> Any:
39
"""
40
Alias for auto_cli() function.
41
42
Args:
43
*args: Positional arguments passed to auto_cli
44
**kwargs: Keyword arguments passed to auto_cli
45
46
Returns:
47
Any: Result of running the CLI component
48
"""
49
50
def auto_parser(
51
components: Optional[Union[Callable, List, Dict, Type]] = None,
52
as_positional: bool = True,
53
fail_untyped: bool = True,
54
parser_class: Type[ArgumentParser] = ArgumentParser,
55
**kwargs
56
) -> ArgumentParser:
57
"""
58
Create an ArgumentParser from components without running it.
59
60
Args:
61
components: Function, class, list, or dict to create parser from
62
as_positional: Whether to add component as positional argument
63
fail_untyped: Whether to fail on untyped parameters
64
parser_class: ArgumentParser class to use
65
**kwargs: Additional arguments for ArgumentParser
66
67
Returns:
68
ArgumentParser: Configured parser ready for parsing
69
"""
70
```
71
72
## Usage Examples
73
74
### Simple Function CLI
75
76
```python
77
from jsonargparse import auto_cli
78
79
def greet(
80
name: str,
81
age: int = 25,
82
formal: bool = False,
83
greeting: str = "Hello"
84
) -> None:
85
"""Greet a person.
86
87
Args:
88
name: Person's name
89
age: Person's age
90
formal: Use formal greeting
91
greeting: Greeting word to use
92
"""
93
style = "formally" if formal else "casually"
94
print(f"{greeting} {name}! You are {age} years old. Greeting you {style}.")
95
96
if __name__ == "__main__":
97
# Creates CLI automatically from function signature
98
auto_cli(greet)
99
```
100
101
Usage:
102
```bash
103
python script.py --name Alice --age 30 --formal
104
python script.py --name Bob --greeting "Hi"
105
```
106
107
### Class-Based CLI
108
109
```python
110
from dataclasses import dataclass
111
from jsonargparse import auto_cli
112
113
@dataclass
114
class ProcessorConfig:
115
input_file: str
116
output_file: str
117
batch_size: int = 32
118
verbose: bool = False
119
120
class DataProcessor:
121
def __init__(self, config: ProcessorConfig):
122
self.config = config
123
124
def process(self) -> None:
125
"""Process the data."""
126
if self.config.verbose:
127
print(f"Processing {self.config.input_file} with batch size {self.config.batch_size}")
128
# Process data here
129
print(f"Output saved to {self.config.output_file}")
130
131
def main(config: ProcessorConfig) -> None:
132
"""Main processing function."""
133
processor = DataProcessor(config)
134
processor.process()
135
136
if __name__ == "__main__":
137
auto_cli(main)
138
```
139
140
Usage:
141
```bash
142
python script.py --config.input_file data.csv --config.output_file results.csv --config.verbose
143
```
144
145
### Multiple Components CLI
146
147
```python
148
from jsonargparse import auto_cli
149
from typing import Literal
150
151
def train(
152
model_type: Literal["cnn", "rnn", "transformer"],
153
epochs: int = 10,
154
learning_rate: float = 0.001
155
) -> None:
156
"""Train a model."""
157
print(f"Training {model_type} for {epochs} epochs with lr={learning_rate}")
158
159
def evaluate(
160
model_path: str,
161
test_data: str,
162
metrics: list[str] = ["accuracy", "f1"]
163
) -> None:
164
"""Evaluate a model."""
165
print(f"Evaluating model {model_path} on {test_data} using {metrics}")
166
167
if __name__ == "__main__":
168
# CLI with subcommands
169
auto_cli({
170
"train": train,
171
"evaluate": evaluate
172
})
173
```
174
175
Usage:
176
```bash
177
python script.py train --model_type cnn --epochs 20
178
python script.py evaluate --model_path model.pkl --test_data test.csv
179
```
180
181
### Parser Creation Without Execution
182
183
```python
184
from jsonargparse import auto_parser
185
186
def process_data(
187
input_path: str,
188
output_path: str,
189
format: str = "json"
190
) -> dict:
191
"""Process data from input to output."""
192
# Processing logic here
193
return {"status": "success", "format": format}
194
195
# Create parser without running
196
parser = auto_parser(process_data)
197
198
# Add additional arguments
199
parser.add_argument("--debug", action="store_true", help="Enable debug mode")
200
201
# Parse arguments manually
202
config = parser.parse_args()
203
204
# Call function with parsed config
205
if hasattr(config, 'debug') and config.debug:
206
print("Debug mode enabled")
207
208
result = process_data(
209
input_path=config.input_path,
210
output_path=config.output_path,
211
format=config.format
212
)
213
print(result)
214
```
215
216
### Configuration File Integration
217
218
```python
219
from jsonargparse import auto_cli
220
221
def train_model(
222
data_dir: str,
223
model_name: str,
224
epochs: int = 100,
225
batch_size: int = 32,
226
learning_rate: float = 0.001,
227
optimizer: str = "adam"
228
) -> None:
229
"""Train a machine learning model.
230
231
Args:
232
data_dir: Directory containing training data
233
model_name: Name of the model architecture
234
epochs: Number of training epochs
235
batch_size: Training batch size
236
learning_rate: Learning rate for optimizer
237
optimizer: Optimizer type (adam, sgd, rmsprop)
238
"""
239
print(f"Training {model_name} model")
240
print(f"Data: {data_dir}")
241
print(f"Config: epochs={epochs}, batch_size={batch_size}, lr={learning_rate}")
242
print(f"Optimizer: {optimizer}")
243
244
if __name__ == "__main__":
245
auto_cli(train_model)
246
```
247
248
With configuration file `config.yaml`:
249
```yaml
250
data_dir: "/path/to/data"
251
model_name: "resnet50"
252
epochs: 200
253
batch_size: 64
254
learning_rate: 0.0001
255
optimizer: "adam"
256
```
257
258
Usage:
259
```bash
260
# Use config file with command line overrides
261
python script.py --config config.yaml --epochs 300 --learning_rate 0.0005
262
```
263
264
### Advanced Component Specification
265
266
```python
267
from jsonargparse import auto_cli
268
from typing import Union, Optional
269
270
class ModelA:
271
def __init__(self, hidden_size: int = 128, dropout: float = 0.1):
272
self.hidden_size = hidden_size
273
self.dropout = dropout
274
275
def train(self):
276
print(f"Training ModelA: hidden={self.hidden_size}, dropout={self.dropout}")
277
278
class ModelB:
279
def __init__(self, layers: int = 3, activation: str = "relu"):
280
self.layers = layers
281
self.activation = activation
282
283
def train(self):
284
print(f"Training ModelB: layers={self.layers}, activation={self.activation}")
285
286
def main(
287
model: Union[ModelA, ModelB],
288
epochs: int = 10,
289
verbose: bool = False
290
) -> None:
291
"""Train a model."""
292
if verbose:
293
print(f"Starting training for {epochs} epochs")
294
model.train()
295
296
if __name__ == "__main__":
297
auto_cli(main)
298
```
299
300
Usage:
301
```bash
302
# Specify model class and its parameters
303
python script.py --model ModelA --model.hidden_size 256 --model.dropout 0.2 --epochs 50
304
python script.py --model ModelB --model.layers 5 --model.activation tanh --verbose
305
```
306
307
## Component Types
308
309
### Supported Component Types
310
311
- **Functions**: Regular functions and methods with type hints
312
- **Classes**: Classes that can be instantiated from parsed arguments
313
- **Dataclasses**: Dataclasses with field type annotations
314
- **Lists**: Multiple components as subcommands
315
- **Dictionaries**: Named components as subcommands
316
- **Modules**: Modules with callable components
317
318
### Type Hint Support
319
320
- **Basic types**: `str`, `int`, `float`, `bool`
321
- **Collections**: `List`, `Dict`, `Set`, `Tuple`
322
- **Optional types**: `Optional[T]`, `Union[T, None]`
323
- **Literal values**: `Literal["option1", "option2"]`
324
- **Union types**: `Union[TypeA, TypeB]`
325
- **Generic types**: `List[int]`, `Dict[str, float]`
326
- **Custom classes**: User-defined classes with type hints
327
- **Path types**: `pathlib.Path` and custom path types