CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-voluptuous

Python data validation library for validating nested data structures with comprehensive error reporting

Pending
Overview
Eval results
Files

range-collection-validators.mddocs/

Range & Collection Validation

Numeric range validation, sequence length validation, membership testing, and complex sequence validation patterns. These validators handle constraints on numeric values, collection sizes, and collection contents.

Capabilities

Numeric Range Validation

Validate that numeric values fall within specified ranges with configurable boundary inclusion.

class Range:
    def __init__(self, min=None, max=None, min_included=True, max_included=True, msg=None):
        """
        Validate numeric value is within range.
        
        Parameters:
        - min: Minimum allowed value (None for no minimum)
        - max: Maximum allowed value (None for no maximum)
        - min_included: Whether minimum value is included in valid range (default True)
        - max_included: Whether maximum value is included in valid range (default True)
        - msg: Custom error message
        
        Returns:
        Original numeric value if within range
        
        Raises:
        RangeInvalid: If value is outside specified range
        """

Usage Examples:

from voluptuous import Schema, Range, All, Coerce

# Basic range validation
age_validator = Range(min=0, max=150)
percentage_validator = Range(min=0.0, max=100.0)

# Open ranges
positive_validator = Range(min=0)         # No maximum
negative_validator = Range(max=0)         # No minimum

# Exclusive ranges
exclusive_range = Range(min=0, max=10, min_included=False, max_included=False)  # 0 < x < 10

# Combined with type coercion
flexible_range = Schema(All(
    Coerce(float),                # Convert to float first
    Range(min=0.0, max=1.0),     # Then validate range
))

# Schema usage
product_schema = Schema({
    'price': All(Coerce(float), Range(min=0.01)),  # Positive price
    'discount': Range(min=0, max=100),              # Percentage
    'quantity': All(int, Range(min=1)),             # At least 1
})

# Valid examples
product_schema({
    'price': '19.99',             # Coerced to 19.99
    'discount': 25,               # 25% discount
    'quantity': 5,                # 5 items
})

Numeric Clamping

Automatically adjust numeric values to stay within specified bounds instead of rejecting them.

class Clamp:
    def __init__(self, min=None, max=None, msg=None):
        """
        Clamp numeric value to specified range.
        
        Parameters:
        - min: Minimum allowed value (values below are set to min)
        - max: Maximum allowed value (values above are set to max)
        - msg: Custom error message (rarely used since values are adjusted)
        
        Returns:
        Numeric value clamped to specified range
        
        Raises:
        Invalid: If input is not numeric
        """

Usage Examples:

from voluptuous import Schema, Clamp, All, Coerce

# Clamp values instead of rejecting them
volume_control = Clamp(min=0, max=100)    # Volume: 0-100
opacity_clamp = Clamp(min=0.0, max=1.0)   # Opacity: 0.0-1.0

# One-way clamping
non_negative = Clamp(min=0)               # No upper limit
max_limit = Clamp(max=1000)               # No lower limit

# Usage examples
settings_schema = Schema({
    'volume': All(Coerce(int), volume_control),
    'opacity': All(Coerce(float), opacity_clamp),
    'timeout': All(Coerce(int), Clamp(min=1, max=3600)),  # 1 second to 1 hour
})

# Clamping in action:
volume_control(150)   # -> 100 (clamped to maximum)
volume_control(-10)   # -> 0 (clamped to minimum)
opacity_clamp(1.5)    # -> 1.0 (clamped to maximum)

Length Validation

Validate the length of sequences, strings, and other objects with len().

class Length:
    def __init__(self, min=None, max=None, msg=None):
        """
        Validate length of sequences, strings, etc.
        
        Parameters:
        - min: Minimum allowed length (None for no minimum)
        - max: Maximum allowed length (None for no maximum)
        - msg: Custom error message
        
        Returns:
        Original object if length is within range
        
        Raises:
        LengthInvalid: If length is outside specified range
        """

Usage Examples:

from voluptuous import Schema, Length, All

# String length validation
username_length = Length(min=3, max=20)
password_length = Length(min=8)          # At least 8 characters
description_length = Length(max=500)     # At most 500 characters

# List length validation
tags_length = Length(min=1, max=10)      # 1-10 tags
items_length = Length(min=0, max=100)    # 0-100 items

# Combined validation
user_schema = Schema({
    'username': All(str, username_length),
    'password': All(str, password_length),
    'bio': All(str, description_length),
    'tags': All([str], tags_length),
})

# Dictionary length (number of keys)
config_schema = Schema(All(
    dict,
    Length(min=1),                # At least one configuration key
))

# Valid examples
user_schema({
    'username': 'john_doe',       # 8 characters (valid)
    'password': 'secretpassword', # 14 characters (valid)
    'bio': 'Software developer',  # 18 characters (valid)
    'tags': ['python', 'web'],    # 2 tags (valid)
})

Numeric Precision Validation

Validate numeric precision and scale for high-precision financial or scientific calculations.

class Number:
    def __init__(self, precision=None, scale=None, msg=None, yield_decimal=False):
        """
        Validate numeric precision and scale.
        
        Parameters:
        - precision: Maximum total number of digits (None for no limit)
        - scale: Maximum number of digits after decimal point (None for no limit)
        - msg: Custom error message
        - yield_decimal: Return Decimal object instead of original number
        
        Returns:
        Original number or Decimal object if yield_decimal=True
        
        Raises:
        Invalid: If number exceeds precision or scale limits
        """

Usage Examples:

from voluptuous import Schema, Number, All, Coerce
from decimal import Decimal

# Financial precision validation
price_validator = Number(precision=10, scale=2)      # Max 10 digits, 2 decimal places
currency_validator = Number(precision=15, scale=4)   # High precision currency

# Scientific precision
measurement_validator = Number(precision=8, scale=6)  # Scientific measurements

# With Decimal conversion
financial_schema = Schema({
    'amount': All(
        Coerce(Decimal),                             # Convert to Decimal first
        Number(precision=12, scale=2, yield_decimal=True)  # Validate and return Decimal
    ),
    'rate': Number(precision=6, scale=4),            # Interest rate with 4 decimal places
})

# Usage examples:
price_validator(123.45)        # Valid: 5 digits total, 2 decimal places
price_validator(12345678.99)   # Valid: 10 digits total, 2 decimal places
# price_validator(123.456)     # Invalid: too many decimal places

currency_validator(1234567890.1234)  # Valid: 14 digits total, 4 decimal places

# Financial calculations
financial_schema({
    'amount': '1234.56',       # Converted to Decimal(1234.56)
    'rate': 0.0525,           # 5.25% interest rate
})

Membership Testing

Validate that values are present or absent in specified containers.

class In:
    def __init__(self, container, msg=None):
        """
        Validate value is in specified container.
        
        Parameters:
        - container: Container to check membership in (list, set, dict keys, etc.)
        - msg: Custom error message
        
        Returns:
        Original value if found in container
        
        Raises:
        InInvalid: If value not found in container
        """

class NotIn:
    def __init__(self, container, msg=None):
        """
        Validate value is not in specified container.
        
        Parameters:
        - container: Container to check membership against
        - msg: Custom error message
        
        Returns:
        Original value if not found in container
        
        Raises:
        NotInInvalid: If value found in container
        """

Usage Examples:

from voluptuous import Schema, In, NotIn, All

# Whitelist validation
status_validator = In(['active', 'inactive', 'pending', 'suspended'])
priority_validator = In([1, 2, 3, 4, 5])
country_validator = In(['US', 'CA', 'UK', 'DE', 'FR', 'JP'])

# Blacklist validation
forbidden_usernames = NotIn(['admin', 'root', 'system', 'administrator'])
forbidden_ports = NotIn([22, 23, 25, 53, 80, 110, 443])

# Combined validation
user_schema = Schema({
    'username': All(str, forbidden_usernames, Length(min=3)),
    'status': status_validator,
    'priority': priority_validator,
    'country': country_validator,
})

# Server configuration
server_schema = Schema({
    'port': All(int, Range(min=1024, max=65535), forbidden_ports),
    'protocol': In(['http', 'https', 'tcp', 'udp']),
})

# Dynamic containers
def get_valid_roles():
    return ['user', 'moderator', 'admin']  # Could be from database

role_validator = lambda value: In(get_valid_roles())(value)

Collection Content Validation

Validate that collections contain specific items or match expected patterns.

class Contains:
    def __init__(self, item, msg=None):
        """
        Validate sequence contains specific item.
        
        Parameters:
        - item: Item that must be present in sequence
        - msg: Custom error message
        
        Returns:
        Original sequence if item is found
        
        Raises:
        ContainsInvalid: If item not found in sequence
        """

Usage Examples:

from voluptuous import Schema, Contains, All, Length

# Required items validation
required_permissions = Contains('read')   # Must have 'read' permission
required_features = Contains('authentication')  # Must include auth feature

# Multiple required items
permissions_schema = All(
    [str],                        # List of strings
    Contains('read'),             # Must contain 'read'
    Contains('write'),            # Must contain 'write'
    Length(min=2),                # At least 2 permissions
)

# Configuration validation
app_config_schema = Schema({
    'features': All([str], Contains('core')),  # Core feature is required
    'plugins': All([str], Length(min=0)),      # Optional plugins
})

# Email list validation
email_list_schema = All(
    [str],
    Contains(lambda emails: any('@company.com' in email for email in emails)),  # At least one company email
)

Sequence Structure Validation

Validate sequences against specific structural patterns.

class ExactSequence:
    def __init__(self, validators, msg=None):
        """
        Validate sequence elements against validators in exact order.
        
        Parameters:
        - validators: List of validators, one per sequence element
        - msg: Custom error message
        
        Returns:
        Validated sequence with each element validated by corresponding validator
        
        Raises:
        ExactSequenceInvalid: If sequence length doesn't match validators or validation fails
        """

class Unordered:
    def __init__(self, validators, msg=None):
        """
        Validate sequence contains elements matching validators in any order.
        
        Parameters:
        - validators: List of validators that must all match some element
        - msg: Custom error message
        
        Returns:
        Original sequence if all validators match some element
        
        Raises:
        Invalid: If any validator doesn't match any element
        """

class Unique:
    def __init__(self, msg=None):
        """
        Ensure sequence contains no duplicate elements.
        
        Parameters:
        - msg: Custom error message
        
        Returns:
        Original sequence if all elements are unique
        
        Raises:
        Invalid: If duplicate elements are found
        """

Usage Examples:

from voluptuous import Schema, ExactSequence, Unordered, Unique, All, Range

# Exact sequence validation (fixed structure)
coordinates_validator = ExactSequence([
    All(float, Range(min=-90, max=90)),   # Latitude
    All(float, Range(min=-180, max=180)), # Longitude
    All(float, Range(min=0)),             # Altitude (optional, positive)
])

rgb_color_validator = ExactSequence([
    All(int, Range(min=0, max=255)),      # Red
    All(int, Range(min=0, max=255)),      # Green  
    All(int, Range(min=0, max=255)),      # Blue
])

# Unordered validation (flexible structure)
required_fields_validator = Unordered([
    'name',                       # Must contain 'name'
    'email',                      # Must contain 'email'
    'age',                        # Must contain 'age'
])

# Unique elements validation
unique_tags = All([str], Unique())
unique_ids = All([int], Unique())

# Combined sequence validation
data_schema = Schema({
    'coordinates': coordinates_validator,  # [lat, lon, alt]
    'color': rgb_color_validator,         # [r, g, b]
    'required_fields': required_fields_validator,
    'tags': unique_tags,                  # Unique string tags
})

# Usage examples:
coordinates_validator([40.7128, -74.0060, 10.0])  # Valid coordinates
rgb_color_validator([255, 128, 0])                 # Valid orange color
unique_tags(['python', 'web', 'api'])             # Valid unique tags

Exact Value Matching

Ensure value exactly matches a target value (no coercion or transformation).

class Equal:
    def __init__(self, target, msg=None):
        """
        Ensure value exactly matches target value.
        
        Parameters:
        - target: Exact value that input must match
        - msg: Custom error message
        
        Returns:
        Original value if it exactly matches target
        
        Raises:
        Invalid: If value doesn't exactly match target
        """

Usage Examples:

from voluptuous import Schema, Equal, Any, Required

# API status validation  
status_schema = Schema({
    'status': Equal('OK'),                    # Must be exactly 'OK'
    'version': Equal(1),                      # Must be exactly 1 (integer)
    'enabled': Equal(True),                   # Must be exactly True (boolean)
})

# Configuration validation
config_schema = Schema({
    'debug': Equal(False),                    # Must be exactly False
    'max_retries': Equal(3),                  # Must be exactly 3
    'api_version': Any(Equal('v1'), Equal('v2')),  # Must be 'v1' or 'v2'
})

# Validate exact matches
status_schema({'status': 'OK', 'version': 1, 'enabled': True})  # Valid
config_schema({'debug': False, 'max_retries': 3, 'api_version': 'v1'})  # Valid

# These would fail:
# status_schema({'status': 'ok'})      # Fails: 'ok' != 'OK' (case sensitive)
# config_schema({'debug': 0})          # Fails: 0 != False (no coercion)

Advanced Collection Patterns

Complex validation patterns for sophisticated collection requirements.

Conditional Collection Validation:

from voluptuous import Schema, All, Any, Length, Contains

def conditional_length(data):
    """Different length requirements based on data type."""
    if data.get('type') == 'premium':
        return All([str], Length(min=5, max=20))  # Premium users get more tags
    else:
        return All([str], Length(min=1, max=10))  # Regular users get fewer tags

user_schema = Schema({
    'type': In(['basic', 'premium']),
    'tags': conditional_length,
})

Nested Collection Validation:

from voluptuous import Schema, All, Length, Range

# Validate list of lists (matrix)
matrix_validator = All(
    [[int]],                      # List of lists of integers
    Length(min=1),                # At least one row
    lambda matrix: all(len(row) == len(matrix[0]) for row in matrix),  # Rectangular
)

# Validate hierarchical data
tree_node = Schema({
    'value': int,
    'children': All([lambda x: tree_node(x)], Length(max=10)),  # Recursive validation
})

Collection Aggregation Validation:

from voluptuous import Schema, All

def sum_constraint(target_sum):
    """Validate that numeric list sums to target value."""
    def validator(values):
        if sum(values) != target_sum:
            raise ValueError(f"Sum must equal {target_sum}, got {sum(values)}")
        return values
    return validator

def average_constraint(min_avg, max_avg):
    """Validate that numeric list average is within range."""
    def validator(values):
        if not values:
            raise ValueError("Cannot calculate average of empty list")
        avg = sum(values) / len(values)
        if not (min_avg <= avg <= max_avg):
            raise ValueError(f"Average {avg} not in range [{min_avg}, {max_avg}]")
        return values
    return validator

# Budget allocation (percentages must sum to 100)
budget_schema = Schema(All(
    [All(float, Range(min=0, max=100))],  # Each percentage 0-100
    sum_constraint(100.0),                # Must sum to 100%
    Length(min=1),                        # At least one category
))

# Performance scores (average must be acceptable)
scores_schema = Schema(All(
    [All(int, Range(min=0, max=100))],    # Each score 0-100
    average_constraint(70, 100),          # Average must be 70-100
    Length(min=3),                        # At least 3 scores
))

Install with Tessl CLI

npx tessl i tessl/pypi-voluptuous

docs

core-schema.md

error-handling.md

index.md

range-collection-validators.md

string-pattern-validators.md

type-validators.md

utility-transformers.md

validation-composers.md

tile.json