Lightweight, extensible schema and data validation tool for Python dictionaries.
Cerberus provides a comprehensive schema management system including schema validation, registries for reusable schemas and rule sets, and extensible schema definitions. This enables structured schema reuse and validation across applications.
A specialized dictionary-like class for validated schema storage and manipulation.
class DefinitionSchema:
def __init__(self, validator, schema):
"""
Initialize a definition schema.
Parameters:
- validator: Validator instance that uses this schema
- schema: Schema definition as dict or string reference to registered schema
"""
def validate(self, schema=None):
"""
Validate a schema against supported validation rules.
Parameters:
- schema: Schema to validate (dict, optional - defaults to current schema)
Raises:
SchemaError: If schema is invalid
"""
def copy(self):
"""
Return a copy of the schema.
Returns:
DefinitionSchema: Copy of current schema
"""
def update(self, schema):
"""
Update schema with new definitions.
Parameters:
- schema: Schema updates to apply (dict)
"""
@classmethod
def expand(cls, schema):
"""
Expand schema shortcuts and references.
Parameters:
- schema: Schema to expand (dict)
Returns:
dict: Expanded schema
"""
# Dictionary-like interface
def __getitem__(self, key): ...
def __setitem__(self, key, value): ...
def __delitem__(self, key): ...
def __iter__(self): ...
def __len__(self): ...
def get(self, key, default=None): ...
def items(self): ...
def keys(self): ...
def values(self): ...Base registry class for storing and retrieving named definitions.
class Registry:
def add(self, name, definition):
"""
Register a definition by name.
Parameters:
- name: Name to register under (str)
- definition: Definition to store
"""
def get(self, name, default=None):
"""
Retrieve a registered definition.
Parameters:
- name: Name of definition to retrieve (str)
- default: Default value if not found
Returns:
Definition or default value
"""
def extend(self, definitions):
"""
Add multiple definitions from a dictionary.
Parameters:
- definitions: Dictionary of name -> definition mappings (dict)
"""
def remove(self, *names):
"""
Unregister definitions by name.
Parameters:
- names: Names of definitions to remove (str)
"""
def clear(self):
"""Remove all registered definitions."""
def all(self):
"""
Return dictionary of all registered definitions.
Returns:
dict: All registered definitions
"""Specialized registry for schema definitions.
class SchemaRegistry(Registry):
"""Registry for storing and retrieving schema definitions by name."""Specialized registry for rules set definitions.
class RulesSetRegistry(Registry):
"""Registry for storing and retrieving rule set definitions by name."""Pre-configured global registry instances for application-wide schema and rules storage.
schema_registry: SchemaRegistry
"""Global registry instance for storing schemas by name"""
rules_set_registry: RulesSetRegistry
"""Global registry instance for storing rule sets by name"""class SchemaError(Exception):
"""Raised when validation schema is missing, malformed, or contains errors"""from cerberus import Validator, DefinitionSchema
# Create schema directly
schema_dict = {
'name': {'type': 'string', 'minlength': 2},
'age': {'type': 'integer', 'min': 0}
}
validator = Validator(schema_dict)
# Access the schema object
definition_schema = validator.schema
print(type(definition_schema)) # <class 'cerberus.schema.DefinitionSchema'>from cerberus import Validator, SchemaError
# Valid schema
valid_schema = {
'name': {'type': 'string'},
'age': {'type': 'integer'}
}
# Invalid schema - will raise SchemaError
try:
invalid_schema = {
'name': {'type': 'invalid_type'}, # Invalid type
'age': {'type': 'integer', 'min': 'not_a_number'} # Invalid constraint
}
v = Validator(invalid_schema)
except SchemaError as e:
print(f"Schema error: {e}")from cerberus import Validator, schema_registry
# Register schemas globally
schema_registry.add('user', {
'name': {'type': 'string', 'minlength': 2},
'email': {'type': 'string', 'regex': r'^[^@]+@[^@]+\.[^@]+$'},
'age': {'type': 'integer', 'min': 18}
})
schema_registry.add('product', {
'name': {'type': 'string', 'required': True},
'price': {'type': 'float', 'min': 0},
'category': {'type': 'string', 'allowed': ['electronics', 'books', 'clothing']}
})
# Use registered schemas
user_validator = Validator('user') # References registered schema
product_validator = Validator('product')
# Validate documents
user_doc = {'name': 'John', 'email': 'john@example.com', 'age': 25}
print(user_validator.validate(user_doc)) # True
# Retrieve registered schemas
user_schema = schema_registry.get('user')
all_schemas = schema_registry.all()from cerberus import Validator, rules_set_registry
# Register common rule sets
rules_set_registry.add('string_rules', {
'type': 'string',
'minlength': 1,
'maxlength': 100
})
rules_set_registry.add('email_rules', {
'type': 'string',
'regex': r'^[^@]+@[^@]+\.[^@]+$'
})
# Use rule sets in schemas
schema = {
'name': 'string_rules', # References registered rule set
'email': 'email_rules',
'description': {'type': 'string', 'maxlength': 500}
}
v = Validator(schema)from cerberus import schema_registry, rules_set_registry
# Add multiple definitions at once
schemas = {
'person': {'name': {'type': 'string'}, 'age': {'type': 'integer'}},
'address': {'street': {'type': 'string'}, 'city': {'type': 'string'}}
}
schema_registry.extend(schemas)
# Remove definitions
schema_registry.remove('person', 'address')
# Clear all definitions
schema_registry.clear()from cerberus import Validator
schema = {
'name': {'type': 'string'},
'age': {'type': 'integer'}
}
v = Validator(schema)
# Update schema
v.schema.update({
'email': {'type': 'string', 'regex': r'^[^@]+@[^@]+\.[^@]+$'}
})
# Copy schema
schema_copy = v.schema.copy()
# Modify copy without affecting original
schema_copy['phone'] = {'type': 'string'}from cerberus import Validator, schema_registry
# Register base schemas
schema_registry.add('base_person', {
'name': {'type': 'string', 'required': True},
'age': {'type': 'integer', 'min': 0}
})
# Create validator using registered schema
v = Validator('base_person')
# Extend with additional fields
v.schema.update({
'email': {'type': 'string', 'required': True},
'phone': {'type': 'string'}
})from cerberus import DefinitionSchema
# Schema with shortcuts
schema_with_shortcuts = {
'name': 'string', # Shortcut for {'type': 'string'}
'tags': ['string'], # Shortcut for list of strings
'metadata': {'type': 'dict'}
}
# Expand shortcuts
expanded = DefinitionSchema.expand(schema_with_shortcuts)
print(expanded)
# Output: {
# 'name': {'type': 'string'},
# 'tags': {'type': 'list', 'schema': {'type': 'string'}},
# 'metadata': {'type': 'dict'}
# }Install with Tessl CLI
npx tessl i tessl/pypi-cerberus