Python Command Line Interface Tools for colored output, progress bars, text formatting, and argument handling
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive input validation system with built-in validators for common data types and patterns. The validation framework supports custom error messages, regex patterns, file system validation, and extensible validator chaining for complex input requirements.
Base exception class for all validation errors with message handling.
class ValidationError(Exception):
"""
Exception raised during input validation failures.
Args:
message (str): Error message describing the validation failure
Attributes:
message (str): The validation error message
error_list (list): List containing this error instance
"""
def __init__(self, message):
"""Initialize validation error with message."""Validates input against regular expression patterns with customizable error messages.
class RegexValidator:
"""
Validates input against a regular expression pattern.
Args:
regex (str or compiled regex): Regular expression pattern to match
message (str): Custom error message (optional)
Attributes:
regex: Compiled regular expression object
message (str): Error message displayed on validation failure
"""
def __init__(self, regex=None, message=None):
"""Initialize with regex pattern and optional error message."""
def __call__(self, value):
"""
Validate input against the regex pattern.
Args:
value (str): Input string to validate
Returns:
str: The validated input value
Raises:
ValidationError: If input doesn't match the pattern
"""Usage Examples:
from clint.textui.validators import RegexValidator
# Email validation
email_validator = RegexValidator(
r'^[^@]+@[^@]+\.[^@]+$',
'Please enter a valid email address'
)
# Phone number validation
phone_validator = RegexValidator(
r'^\+?1?-?\.?\s?\(?([0-9]{3})\)?[-\.\s]?([0-9]{3})[-\.\s]?([0-9]{4})$',
'Enter a valid phone number'
)
# Custom pattern validation
username_validator = RegexValidator(
r'^[a-zA-Z0-9_]{3,20}$',
'Username must be 3-20 characters, letters, numbers, underscores only'
)
# Use with prompt
from clint.textui import prompt
email = prompt.query('Email:', validators=[email_validator])Validates that input represents a valid directory path that exists on the filesystem.
class PathValidator:
"""
Validates that input is a valid, existing directory path.
Args:
message (str): Custom error message (optional)
Attributes:
message (str): Error message displayed when path is invalid
"""
def __init__(self, message=None):
"""Initialize with optional custom error message."""
def __call__(self, value):
"""
Validate that input is an existing directory.
Args:
value (str): Path string to validate
Returns:
str: The validated path
Raises:
ValidationError: If path doesn't exist or isn't a directory
"""Usage Examples:
from clint.textui.validators import PathValidator
from clint.textui import prompt
# Basic path validation
path_validator = PathValidator()
config_dir = prompt.query('Config directory:', validators=[path_validator])
# Custom error message
path_validator = PathValidator('The specified directory does not exist')
backup_dir = prompt.query('Backup directory:', validators=[path_validator])Validates that input represents a valid file path that exists on the filesystem.
class FileValidator:
"""
Validates that input is a valid, existing file path.
Args:
message (str): Custom error message (optional)
Attributes:
message (str): Error message displayed when file is invalid
"""
def __init__(self, message=None):
"""Initialize with optional custom error message."""
def __call__(self, value):
"""
Validate that input is an existing file.
Args:
value (str): File path string to validate
Returns:
str: The validated file path
Raises:
ValidationError: If file doesn't exist or isn't a file
"""Usage Examples:
from clint.textui.validators import FileValidator
from clint.textui import prompt
# Configuration file validation
config_validator = FileValidator('Configuration file not found')
config_file = prompt.query('Config file:', validators=[config_validator])
# Script validation
script_validator = FileValidator()
script_path = prompt.query('Script to execute:', validators=[script_validator])Validates that input can be converted to an integer and returns the integer value.
class IntegerValidator:
"""
Validates that input is a valid integer and converts it.
Args:
message (str): Custom error message (optional)
Attributes:
message (str): Error message displayed when conversion fails
"""
def __init__(self, message=None):
"""Initialize with optional custom error message."""
def __call__(self, value):
"""
Validate and convert input to integer.
Args:
value (str): String to convert to integer
Returns:
int: The converted integer value
Raises:
ValidationError: If input cannot be converted to integer
"""Usage Examples:
from clint.textui.validators import IntegerValidator
from clint.textui import prompt
# Basic integer validation
age = prompt.query('Enter your age:', validators=[IntegerValidator()])
# Custom error message
port_validator = IntegerValidator('Port must be a valid number')
port = prompt.query('Port number:', validators=[port_validator])
# Combined with regex for range validation
from clint.textui.validators import RegexValidator
port_validators = [
IntegerValidator('Must be a number'),
RegexValidator(r'^([1-9]\d{3,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$',
'Port must be between 1000-65535')
]
port = prompt.query('Port:', validators=port_validators)Validates that input is one of a predefined set of valid options.
class OptionValidator:
"""
Validates that input is in a list of acceptable options.
Args:
options (list): List of valid option values
message (str): Custom error message (optional)
Attributes:
options (list): List of acceptable values
message (str): Error message displayed when option is invalid
"""
def __init__(self, options, message=None):
"""Initialize with list of valid options and optional error message."""
def __call__(self, value):
"""
Validate that input is in the options list.
Args:
value (str): Input value to validate
Returns:
str: The validated input value
Raises:
ValidationError: If input is not in the options list
"""Usage Examples:
from clint.textui.validators import OptionValidator
from clint.textui import prompt
# Environment selection
env_validator = OptionValidator(['dev', 'test', 'prod'])
environment = prompt.query('Environment (dev/test/prod):', validators=[env_validator])
# Log level validation
log_levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
level_validator = OptionValidator(log_levels, 'Invalid log level')
log_level = prompt.query('Log level:', validators=[level_validator])
# Case variations
bool_validator = OptionValidator(['yes', 'no', 'y', 'n', 'true', 'false'])
confirm = prompt.query('Confirm:', validators=[bool_validator])Multiple validators can be used together to create complex validation rules:
from clint.textui.validators import RegexValidator, IntegerValidator
from clint.textui import prompt
# Port number: must be integer AND in valid range
port_validators = [
IntegerValidator('Must be a valid number'),
RegexValidator(r'^([1-9]\d{2,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$',
'Port must be between 100-65535')
]
port = prompt.query('Port number:', validators=port_validators)
# Username: regex pattern AND length check
username_validators = [
RegexValidator(r'^[a-zA-Z0-9_]+$', 'Only letters, numbers, and underscores allowed'),
RegexValidator(r'^.{3,20}$', 'Username must be 3-20 characters long')
]
username = prompt.query('Username:', validators=username_validators)Create custom validators by implementing the callable pattern:
from clint.textui.validators import ValidationError
class PasswordStrengthValidator:
def __init__(self, message="Password must be at least 8 characters with numbers"):
self.message = message
def __call__(self, value):
if len(value) < 8:
raise ValidationError(self.message)
if not any(c.isdigit() for c in value):
raise ValidationError(self.message)
return value
# Usage
from clint.textui import prompt
password = prompt.query('Password:', validators=[PasswordStrengthValidator()])When validation fails, the validator raises a ValidationError with a descriptive message. The prompt system catches these errors, displays the message in yellow text, and re-prompts the user:
# Example of validation failure flow:
# User input: "invalid-email"
# Validator: RegexValidator(r'^[^@]+@[^@]+\.[^@]+$', 'Enter a valid email')
# Output: "Enter a valid email" (in yellow)
# Prompt repeats: "Email address: "Install with Tessl CLI
npx tessl i tessl/pypi-clint