CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jsonargparse

Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables.

Pending
Overview
Eval results
Files

cli-creation.mddocs/

CLI Creation

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.

Capabilities

Automatic CLI Functions

High-level functions for creating complete command-line interfaces automatically from Python functions, classes, or modules.

def auto_cli(
    components: Optional[Union[Callable, List, Dict, Type]] = None,
    args: Optional[List[str]] = None,
    config_help: str = "Path to a configuration file.",
    set_defaults: Optional[Dict[str, Any]] = None,
    as_positional: bool = True,
    fail_untyped: bool = True,
    parser_class: Type[ArgumentParser] = ArgumentParser,
    **kwargs
) -> Any:
    """
    Create a CLI from components and run it.
    
    Args:
        components: Function, class, list, or dict to create CLI from
        args: Command line arguments to parse (defaults to sys.argv)
        config_help: Help text for configuration file option
        set_defaults: Default values to set in parser
        as_positional: Whether to add component as positional argument
        fail_untyped: Whether to fail on untyped parameters
        parser_class: ArgumentParser class to use
        **kwargs: Additional arguments for ArgumentParser
        
    Returns:
        Any: Result of running the CLI component
    """

def CLI(*args, **kwargs) -> Any:
    """
    Alias for auto_cli() function.
    
    Args:
        *args: Positional arguments passed to auto_cli
        **kwargs: Keyword arguments passed to auto_cli
        
    Returns:
        Any: Result of running the CLI component
    """

def auto_parser(
    components: Optional[Union[Callable, List, Dict, Type]] = None,
    as_positional: bool = True,
    fail_untyped: bool = True,
    parser_class: Type[ArgumentParser] = ArgumentParser,
    **kwargs
) -> ArgumentParser:
    """
    Create an ArgumentParser from components without running it.
    
    Args:
        components: Function, class, list, or dict to create parser from
        as_positional: Whether to add component as positional argument
        fail_untyped: Whether to fail on untyped parameters
        parser_class: ArgumentParser class to use
        **kwargs: Additional arguments for ArgumentParser
        
    Returns:
        ArgumentParser: Configured parser ready for parsing
    """

Usage Examples

Simple Function CLI

from jsonargparse import auto_cli

def greet(
    name: str,
    age: int = 25,
    formal: bool = False,
    greeting: str = "Hello"
) -> None:
    """Greet a person.
    
    Args:
        name: Person's name
        age: Person's age  
        formal: Use formal greeting
        greeting: Greeting word to use
    """
    style = "formally" if formal else "casually"
    print(f"{greeting} {name}! You are {age} years old. Greeting you {style}.")

if __name__ == "__main__":
    # Creates CLI automatically from function signature
    auto_cli(greet)

Usage:

python script.py --name Alice --age 30 --formal
python script.py --name Bob --greeting "Hi"

Class-Based CLI

from dataclasses import dataclass
from jsonargparse import auto_cli

@dataclass
class ProcessorConfig:
    input_file: str
    output_file: str
    batch_size: int = 32
    verbose: bool = False

class DataProcessor:
    def __init__(self, config: ProcessorConfig):
        self.config = config
    
    def process(self) -> None:
        """Process the data."""
        if self.config.verbose:
            print(f"Processing {self.config.input_file} with batch size {self.config.batch_size}")
        # Process data here
        print(f"Output saved to {self.config.output_file}")

def main(config: ProcessorConfig) -> None:
    """Main processing function."""
    processor = DataProcessor(config)
    processor.process()

if __name__ == "__main__":
    auto_cli(main)

Usage:

python script.py --config.input_file data.csv --config.output_file results.csv --config.verbose

Multiple Components CLI

from jsonargparse import auto_cli
from typing import Literal

def train(
    model_type: Literal["cnn", "rnn", "transformer"],
    epochs: int = 10,
    learning_rate: float = 0.001
) -> None:
    """Train a model."""
    print(f"Training {model_type} for {epochs} epochs with lr={learning_rate}")

def evaluate(
    model_path: str,
    test_data: str,
    metrics: list[str] = ["accuracy", "f1"]
) -> None:
    """Evaluate a model."""
    print(f"Evaluating model {model_path} on {test_data} using {metrics}")

if __name__ == "__main__":
    # CLI with subcommands
    auto_cli({
        "train": train,
        "evaluate": evaluate
    })

Usage:

python script.py train --model_type cnn --epochs 20
python script.py evaluate --model_path model.pkl --test_data test.csv

Parser Creation Without Execution

from jsonargparse import auto_parser

def process_data(
    input_path: str,
    output_path: str,
    format: str = "json"
) -> dict:
    """Process data from input to output."""
    # Processing logic here
    return {"status": "success", "format": format}

# Create parser without running
parser = auto_parser(process_data)

# Add additional arguments
parser.add_argument("--debug", action="store_true", help="Enable debug mode")

# Parse arguments manually
config = parser.parse_args()

# Call function with parsed config
if hasattr(config, 'debug') and config.debug:
    print("Debug mode enabled")

result = process_data(
    input_path=config.input_path,
    output_path=config.output_path, 
    format=config.format
)
print(result)

Configuration File Integration

from jsonargparse import auto_cli

def train_model(
    data_dir: str,
    model_name: str,
    epochs: int = 100,
    batch_size: int = 32,
    learning_rate: float = 0.001,
    optimizer: str = "adam"
) -> None:
    """Train a machine learning model.
    
    Args:
        data_dir: Directory containing training data
        model_name: Name of the model architecture
        epochs: Number of training epochs
        batch_size: Training batch size
        learning_rate: Learning rate for optimizer
        optimizer: Optimizer type (adam, sgd, rmsprop)
    """
    print(f"Training {model_name} model")
    print(f"Data: {data_dir}")
    print(f"Config: epochs={epochs}, batch_size={batch_size}, lr={learning_rate}")
    print(f"Optimizer: {optimizer}")

if __name__ == "__main__":
    auto_cli(train_model)

With configuration file config.yaml:

data_dir: "/path/to/data"
model_name: "resnet50"
epochs: 200
batch_size: 64
learning_rate: 0.0001
optimizer: "adam"

Usage:

# Use config file with command line overrides
python script.py --config config.yaml --epochs 300 --learning_rate 0.0005

Advanced Component Specification

from jsonargparse import auto_cli
from typing import Union, Optional

class ModelA:
    def __init__(self, hidden_size: int = 128, dropout: float = 0.1):
        self.hidden_size = hidden_size
        self.dropout = dropout
    
    def train(self):
        print(f"Training ModelA: hidden={self.hidden_size}, dropout={self.dropout}")

class ModelB:
    def __init__(self, layers: int = 3, activation: str = "relu"):
        self.layers = layers  
        self.activation = activation
    
    def train(self):
        print(f"Training ModelB: layers={self.layers}, activation={self.activation}")

def main(
    model: Union[ModelA, ModelB],
    epochs: int = 10,
    verbose: bool = False
) -> None:
    """Train a model."""
    if verbose:
        print(f"Starting training for {epochs} epochs")
    model.train()

if __name__ == "__main__":
    auto_cli(main)

Usage:

# Specify model class and its parameters
python script.py --model ModelA --model.hidden_size 256 --model.dropout 0.2 --epochs 50
python script.py --model ModelB --model.layers 5 --model.activation tanh --verbose

Component Types

Supported Component Types

  • Functions: Regular functions and methods with type hints
  • Classes: Classes that can be instantiated from parsed arguments
  • Dataclasses: Dataclasses with field type annotations
  • Lists: Multiple components as subcommands
  • Dictionaries: Named components as subcommands
  • Modules: Modules with callable components

Type Hint Support

  • Basic types: str, int, float, bool
  • Collections: List, Dict, Set, Tuple
  • Optional types: Optional[T], Union[T, None]
  • Literal values: Literal["option1", "option2"]
  • Union types: Union[TypeA, TypeB]
  • Generic types: List[int], Dict[str, float]
  • Custom classes: User-defined classes with type hints
  • Path types: pathlib.Path and custom path types

Install with Tessl CLI

npx tessl i tessl/pypi-jsonargparse@4.41.1

docs

advanced-actions.md

cli-creation.md

core-parser.md

index.md

namespace-management.md

settings.md

signature-arguments.md

types-validation.md

utilities.md

tile.json