CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-schematics

Python Data Structures for Humans - a library for data validation and transformation using structured models

Pending
Overview
Eval results
Files

compound-types.mddocs/

Compound Field Types

Advanced field types for complex data structures in Schematics. These types handle collections, nested models, and polymorphic data with recursive validation and conversion.

Capabilities

List Fields

Handle arrays and sequences with typed elements and size constraints.

class ListType(BaseType):
    """
    Field for storing lists/arrays of typed items.
    
    Validates list size and applies field validation to each element.
    Supports nested validation with any field type.
    """
    
    def __init__(self, field, min_size=None, max_size=None, **kwargs):
        """
        Initialize list field.
        
        Args:
            field (BaseType): Field type for list elements
            min_size (int, optional): Minimum list length
            max_size (int, optional): Maximum list length
            **kwargs: Base field options
        """

Dictionary Fields

Handle key-value mappings with optional typed values.

class DictType(BaseType):
    """
    Field for storing mappings/dictionaries.
    
    Supports typed values and validates dictionary structure.
    Keys are typically strings, values can be typed using field parameter.
    """
    
    def __init__(self, field=None, **kwargs):
        """
        Initialize dictionary field.
        
        Args:
            field (BaseType, optional): Field type for dictionary values
            **kwargs: Base field options
        """

Nested Model Fields

Handle embedded model instances with recursive validation.

class ModelType(BaseType):
    """
    Field that holds a model instance with nested validation.
    
    Enables composition of models and recursive data structures.
    Validates nested model according to its field definitions.
    """
    
    def __init__(self, model_class, **kwargs):
        """
        Initialize model field.
        
        Args:
            model_class (Model): Model class for nested instances
            **kwargs: Base field options
        """

Polymorphic Model Fields

Handle multiple model types with dynamic type resolution.

class PolyModelType(BaseType):
    """
    Field accepting instances of multiple model types.
    
    Supports polymorphic data structures where the exact model type
    is determined at runtime based on data content or explicit type hints.
    """
    
    def __init__(self, model_spec, **kwargs):
        """
        Initialize polymorphic model field.
        
        Args:
            model_spec (dict): Mapping of type identifiers to model classes
            **kwargs: Base field options
        """

Union Fields

Handle values that can be one of multiple types.

class UnionType(BaseType):
    """
    Field that accepts multiple type alternatives with fallback logic.
    
    Attempts conversion with each type until one succeeds,
    providing flexible input handling for ambiguous data.
    """
    
    def __init__(self, types, **kwargs):
        """
        Initialize union field.
        
        Args:
            types (list): List of field types to attempt
            **kwargs: Base field options
        """

Base Compound Type

Base class providing common functionality for compound types.

class CompoundType(BaseType):
    """
    Base class for compound field types containing other fields.
    
    Provides infrastructure for recursive validation and conversion
    of nested data structures.
    """
    
    def __init__(self, **kwargs):
        """
        Initialize compound field.
        
        Args:
            **kwargs: Base field options
        """

Usage Examples

List Validation

from schematics.models import Model
from schematics.types import StringType, ListType, IntType

class BlogPost(Model):
    title = StringType(required=True)
    tags = ListType(StringType(), min_size=1, max_size=10)
    ratings = ListType(IntType(min_value=1, max_value=5))

# Valid data
post = BlogPost({
    'title': 'My Blog Post',
    'tags': ['python', 'programming', 'web'],
    'ratings': [4, 5, 3, 4]
})
post.validate()  # Success

# Each list element is validated according to field type
invalid_post = BlogPost({
    'title': 'Test',
    'tags': ['valid_tag', ''],  # Empty string fails StringType validation
    'ratings': [1, 6]           # 6 exceeds max_value=5
})
# post.validate() would raise ValidationError

Dictionary Fields

from schematics.types import DictType, StringType

class Configuration(Model):
    metadata = DictType()  # Any dict values allowed
    settings = DictType(StringType())  # String values only

config = Configuration({
    'metadata': {'version': '1.0', 'author': 'John', 'count': 42},
    'settings': {'theme': 'dark', 'language': 'en'}
})
config.validate()

Nested Models

class Address(Model):
    street = StringType(required=True)
    city = StringType(required=True)
    country = StringType(required=True)

class Person(Model):
    name = StringType(required=True)
    address = ModelType(Address, required=True)

# Nested validation
person_data = {
    'name': 'John Doe',
    'address': {
        'street': '123 Main St',
        'city': 'Anytown', 
        'country': 'USA'
    }
}

person = Person(person_data)
person.validate()  # Validates both Person and nested Address

# Access nested data
print(person.address.city)  # 'Anytown'
print(person.to_primitive())  # Includes nested address data

Complex Nested Structures

class Comment(Model):
    author = StringType(required=True)
    text = StringType(required=True)
    timestamp = DateTimeType()

class Article(Model):
    title = StringType(required=True)
    content = StringType(required=True)
    comments = ListType(ModelType(Comment))
    tags = ListType(StringType())
    metadata = DictType(StringType())

# Complex nested data
article_data = {
    'title': 'Advanced Python',
    'content': 'Python is a powerful language...',
    'comments': [
        {'author': 'Alice', 'text': 'Great article!'},
        {'author': 'Bob', 'text': 'Very helpful, thanks.'}
    ],
    'tags': ['python', 'programming', 'tutorial'],
    'metadata': {'category': 'programming', 'difficulty': 'intermediate'}
}

article = Article(article_data)
article.validate()  # Validates entire nested structure

Polymorphic Models

class Vehicle(Model):
    make = StringType(required=True)
    model = StringType(required=True)

class Car(Vehicle):
    doors = IntType(min_value=2, max_value=5)

class Motorcycle(Vehicle):
    engine_size = IntType(min_value=50)

class Fleet(Model):
    name = StringType(required=True)
    vehicles = ListType(PolyModelType({
        'car': Car,
        'motorcycle': Motorcycle
    }))

# Mixed vehicle types
fleet_data = {
    'name': 'City Fleet',
    'vehicles': [
        {'_type': 'car', 'make': 'Toyota', 'model': 'Camry', 'doors': 4},
        {'_type': 'motorcycle', 'make': 'Honda', 'model': 'CBR', 'engine_size': 600}
    ]
}

fleet = Fleet(fleet_data)
fleet.validate()  # Each vehicle validated according to its specific type

Union Types for Flexible Input

from schematics.types import UnionType

class FlexibleRecord(Model):
    # Field can accept either string or integer
    identifier = UnionType([StringType(), IntType()])
    # Field can be either a single string or list of strings  
    tags = UnionType([StringType(), ListType(StringType())])

# Various input formats accepted
record1 = FlexibleRecord({
    'identifier': 'ABC123',      # String
    'tags': 'single-tag'         # Single string
})

record2 = FlexibleRecord({
    'identifier': 12345,         # Integer
    'tags': ['tag1', 'tag2']     # List of strings
})

record1.validate()  # Success
record2.validate()  # Success

Install with Tessl CLI

npx tessl i tessl/pypi-schematics

docs

basic-types.md

compound-types.md

contrib-modules.md

dynamic-fields.md

exceptions.md

index.md

models.md

network-types.md

utilities.md

tile.json