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

types-validation.mddocs/

Types and Validation

Advanced type system with built-in validators, custom type registration, and predefined types for common validation patterns. The jsonargparse type system extends Python's type hints with specialized validators and path types for robust CLI argument validation.

Capabilities

Type Decorators and Registration

Functions for registering custom types and extending the type system with validation.

def register_type(custom_type: Type, serializer: Optional[Callable] = None) -> None:
    """
    Register a custom type for use in parsers.
    
    Args:
        custom_type: Type class to register
        serializer: Optional function to serialize instances of this type
    """

def extend_base_type(base_type: Type, **kwargs) -> Type:
    """
    Extend a base type with additional validation.
    
    Args:
        base_type: Base type to extend
        **kwargs: Validation parameters
        
    Returns:
        Type: Extended type with validation
    """

def final(cls: Type) -> Type:
    """
    Mark a class as final (cannot be subclassed).
    
    Args:
        cls: Class to mark as final
        
    Returns:
        Type: Final class
    """

def is_final_class(cls: Type) -> bool:
    """
    Check if a class is marked as final.
    
    Args:
        cls: Class to check
        
    Returns:
        bool: True if class is final
    """

Restricted Number Types

Factory functions for creating number types with validation constraints.

def restricted_number_type(
    base_type: Union[Type[int], Type[float]],
    minimum: Optional[Union[int, float]] = None,
    maximum: Optional[Union[int, float]] = None,
    exclusive_minimum: Optional[Union[int, float]] = None,
    exclusive_maximum: Optional[Union[int, float]] = None,
    multiple_of: Optional[Union[int, float]] = None
) -> Type:
    """
    Create a restricted number type with validation.
    
    Args:
        base_type: Base numeric type (int or float)
        minimum: Minimum allowed value (inclusive)
        maximum: Maximum allowed value (inclusive) 
        exclusive_minimum: Minimum allowed value (exclusive)
        exclusive_maximum: Maximum allowed value (exclusive)
        multiple_of: Value must be multiple of this number
        
    Returns:
        Type: Restricted number type
    """

Restricted String Types

Factory function for creating string types with validation patterns.

def restricted_string_type(
    pattern: Optional[str] = None,
    min_length: Optional[int] = None,
    max_length: Optional[int] = None,
    format: Optional[str] = None
) -> Type:
    """
    Create a restricted string type with validation.
    
    Args:
        pattern: Regular expression pattern to match
        min_length: Minimum string length
        max_length: Maximum string length
        format: String format validation ('email', 'uri', etc.)
        
    Returns:
        Type: Restricted string type
    """

Path Type Factory

Factory function for creating path types with access validation.

def path_type(mode: str) -> Type:
    """
    Create a path type with specified access mode validation.
    
    Args:
        mode: Access mode string (combinations of 'f', 'd', 'r', 'w', 'x', 'c', 'u')
        
    Returns:
        Type: Path type with validation
    """

Predefined Number Types

Ready-to-use numeric types with common validation patterns.

# Positive numbers (> 0)
PositiveInt: Type  # Positive integer
PositiveFloat: Type  # Positive float

# Non-negative numbers (>= 0)  
NonNegativeInt: Type  # Non-negative integer
NonNegativeFloat: Type  # Non-negative float

# Unit interval types
ClosedUnitInterval: Type  # Float in [0, 1]
OpenUnitInterval: Type  # Float in (0, 1)

Predefined String Types

Ready-to-use string types with common validation patterns.

NotEmptyStr: Type  # Non-empty string
Email: Type  # Email address validation
SecretStr: Type  # Secure string handling (masked in output)

Predefined Path Types

Ready-to-use path types for common file system access patterns.

Path_fr: Type  # File, readable
Path_fc: Type  # File, creatable  
Path_dw: Type  # Directory, writable
Path_dc: Type  # Directory, creatable
Path_drw: Type  # Directory, readable and writable

Usage Examples

Custom Type Registration

from jsonargparse import ArgumentParser, register_type
from datetime import datetime

class DateTimeType:
    def __init__(self, dt_string: str):
        self.datetime = datetime.fromisoformat(dt_string)
    
    def __str__(self):
        return self.datetime.isoformat()

# Register custom type
register_type(DateTimeType)

parser = ArgumentParser()
parser.add_argument("--start-time", type=DateTimeType, help="Start time in ISO format")

config = parser.parse_args()
print(f"Start time: {config.start_time.datetime}")

Usage:

python script.py --start-time "2023-01-01T10:30:00"

Restricted Number Validation

from jsonargparse import ArgumentParser, restricted_number_type

# Create custom numeric types
Percentage = restricted_number_type(float, minimum=0.0, maximum=100.0)
Port = restricted_number_type(int, minimum=1024, maximum=65535)
BatchSize = restricted_number_type(int, minimum=1, multiple_of=8)

parser = ArgumentParser()
parser.add_argument("--accuracy", type=Percentage, help="Model accuracy percentage")
parser.add_argument("--port", type=Port, help="Network port number")  
parser.add_argument("--batch-size", type=BatchSize, help="Training batch size")

config = parser.parse_args()
print(f"Accuracy: {config.accuracy}%")
print(f"Port: {config.port}")
print(f"Batch size: {config.batch_size}")

Usage:

python script.py --accuracy 95.5 --port 8080 --batch-size 64
python script.py --accuracy 150  # Error: exceeds maximum
python script.py --batch-size 33  # Error: not multiple of 8

Restricted String Validation

from jsonargparse import ArgumentParser, restricted_string_type

# Create string types with validation
Username = restricted_string_type(
    pattern=r"^[a-zA-Z0-9_]{3,20}$",
    min_length=3,
    max_length=20
)

IPv4Address = restricted_string_type(
    pattern=r"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$"
)

parser = ArgumentParser()
parser.add_argument("--username", type=Username, help="Username (alphanumeric, 3-20 chars)")
parser.add_argument("--server-ip", type=IPv4Address, help="Server IP address")

config = parser.parse_args()
print(f"Username: {config.username}")
print(f"Server IP: {config.server_ip}")

Predefined Types Usage

from jsonargparse import ArgumentParser, PositiveInt, Email, Path_fr, ClosedUnitInterval

parser = ArgumentParser()
parser.add_argument("--workers", type=PositiveInt, help="Number of worker processes")
parser.add_argument("--email", type=Email, help="Contact email address")
parser.add_argument("--config-file", type=Path_fr, help="Configuration file path")
parser.add_argument("--dropout", type=ClosedUnitInterval, help="Dropout rate (0.0-1.0)")

config = parser.parse_args()
print(f"Workers: {config.workers}")
print(f"Email: {config.email}")
print(f"Config: {config.config_file}")
print(f"Dropout: {config.dropout}")

Usage:

python script.py --workers 4 --email user@example.com --config-file config.yaml --dropout 0.2
python script.py --workers -1  # Error: must be positive
python script.py --dropout 1.5  # Error: must be in [0, 1]

Path Type Validation

from jsonargparse import ArgumentParser, Path_fr, Path_dw, path_type

# Use predefined path types
parser = ArgumentParser()
parser.add_argument("--input", type=Path_fr, help="Input file (must exist and be readable)")
parser.add_argument("--output-dir", type=Path_dw, help="Output directory (must be writable)")

# Create custom path types
ExecutableFile = path_type("frx")  # File, readable, executable
parser.add_argument("--script", type=ExecutableFile, help="Script to execute")

config = parser.parse_args()
print(f"Input: {config.input}")
print(f"Output dir: {config.output_dir}")
print(f"Script: {config.script}")

Secure String Handling

from jsonargparse import ArgumentParser, SecretStr

parser = ArgumentParser()
parser.add_argument("--password", type=SecretStr, help="Database password")
parser.add_argument("--api-key", type=SecretStr, help="API key")

config = parser.parse_args()

# SecretStr values are masked in output
print(f"Config: {config}")  # Shows masked values
print(f"Password length: {len(str(config.password))}")

# Access actual values when needed
actual_password = str(config.password)

Type Extension and Composition

from jsonargparse import ArgumentParser, extend_base_type

# Extend float with custom validation
LearningRate = extend_base_type(
    float,
    minimum=1e-6,
    maximum=1.0,
    description="Learning rate for optimizer"
)

# Use in dataclass
from dataclasses import dataclass

@dataclass
class OptimizerConfig:
    learning_rate: LearningRate = 0.001
    momentum: ClosedUnitInterval = 0.9
    weight_decay: NonNegativeFloat = 1e-4

parser = ArgumentParser()
parser.add_class_arguments(OptimizerConfig, "optimizer")

config = parser.parse_args()
opt_config = OptimizerConfig(**config.optimizer.as_dict())
print(f"Optimizer: lr={opt_config.learning_rate}, momentum={opt_config.momentum}")

Final Class Validation

from jsonargparse import final, is_final_class

@final
class ProductionConfig:
    def __init__(self, debug: bool = False):
        if debug:
            raise ValueError("Debug mode not allowed in production")
        self.debug = debug

# Check if class is final
print(f"Is final: {is_final_class(ProductionConfig)}")  # True

# This would raise an error:
# class ExtendedConfig(ProductionConfig):  # Error: cannot subclass final class
#     pass

Type Reference

Path Mode Characters

  • f: Must be a file
  • d: Must be a directory
  • r: Must be readable
  • w: Must be writable
  • x: Must be executable
  • c: File can be created (parent directory writable)
  • u: Path can be a URL

Common Predefined Types

TypeDescriptionExample Values
PositiveIntInteger > 01, 100, 9999
NonNegativeIntInteger >= 00, 1, 100
PositiveFloatFloat > 0.00.1, 1.5, 100.0
ClosedUnitIntervalFloat in [0, 1]0.0, 0.5, 1.0
OpenUnitIntervalFloat in (0, 1)0.1, 0.5, 0.9
NotEmptyStrNon-empty string"hello", "test"
EmailValid email format"user@example.com"
SecretStrMasked string"[HIDDEN]" in output

Common Path Types

TypeModeDescription
Path_fr"fr"Existing readable file
Path_fc"fc"File that can be created
Path_dw"dw"Writable directory
Path_dc"dc"Directory that can be created
Path_drw"drw"Readable and writable directory

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