Lightweight, extensible schema and data validation tool for Python dictionaries.
The Validator class is the heart of Cerberus, providing comprehensive document validation and normalization capabilities against schema definitions. It supports extensive validation rules, custom constraints, and flexible validation modes.
The main validation class that validates and normalizes mappings against validation schemas.
class Validator:
def __init__(self, schema=None, ignore_none_values=False, allow_unknown=False,
require_all=False, purge_unknown=False, purge_readonly=False,
error_handler=None):
"""
Initialize a Validator instance.
Parameters:
- schema: Validation schema (dict or string reference)
- ignore_none_values: Skip validation of None values (bool)
- allow_unknown: Allow unknown fields (bool or dict)
- require_all: Require all schema fields (bool)
- purge_unknown: Remove unknown fields during validation (bool)
- purge_readonly: Remove readonly fields during normalization (bool)
- error_handler: Custom error handler instance or class
"""Core validation functionality for validating documents against schemas.
def validate(self, document, schema=None, update=False, normalize=True) -> bool:
"""
Validate a document against the schema.
Parameters:
- document: The document to validate (dict)
- schema: Override schema for this validation (dict, optional)
- update: Treat document as an update, allowing partial validation (bool)
- normalize: Apply normalization during validation (bool)
Returns:
bool: True if valid, False otherwise
"""
def validated(self, *args, **kwargs):
"""
Return validated document or None if validation failed.
Parameters: Same as validate(), plus:
- always_return_document: Return document even if validation fails (bool, default: False)
Returns:
dict or None: Validated document if successful, None if validation failed
(unless always_return_document=True)
"""
def __call__(self, document, schema=None, update=False, normalize=True) -> bool:
"""
Callable interface - alias for validate().
Parameters: Same as validate()
Returns:
bool: True if valid, False otherwise
"""Document transformation and coercion capabilities.
def normalized(self, document, schema=None, always_return_document=False):
"""
Return normalized version of document.
Parameters:
- document: Document to normalize (dict)
- schema: Override schema for normalization (dict, optional)
- always_return_document: Return document even if validation fails (bool)
Returns:
dict or None: Normalized document, or None if normalization failed
"""Access to validator state and configuration.
# Schema and Configuration
@property
def schema(self) -> dict:
"""Current validation schema"""
@schema.setter
def schema(self, schema):
"""Set validation schema"""
@property
def allow_unknown(self) -> bool:
"""Whether unknown fields are allowed"""
@allow_unknown.setter
def allow_unknown(self, value):
"""Set allow_unknown behavior"""
@property
def require_all(self) -> bool:
"""Whether all schema fields are required"""
@require_all.setter
def require_all(self, value):
"""Set require_all behavior"""
@property
def ignore_none_values(self) -> bool:
"""Whether None values are ignored during validation"""
@ignore_none_values.setter
def ignore_none_values(self, value):
"""Set ignore_none_values behavior"""
@property
def purge_unknown(self) -> bool:
"""Whether unknown fields are removed"""
@purge_unknown.setter
def purge_unknown(self, value):
"""Set purge_unknown behavior"""
@property
def purge_readonly(self) -> bool:
"""Whether readonly fields are removed during normalization"""
@purge_readonly.setter
def purge_readonly(self, value):
"""Set purge_readonly behavior"""
# Validation State
@property
def document(self) -> dict:
"""The document being/recently processed"""
@property
def errors(self):
"""Formatted validation errors from last operation"""
@property
def document_error_tree(self):
"""Errors organized by document structure"""
@property
def schema_error_tree(self):
"""Errors organized by schema structure"""
@property
def recent_error(self):
"""Most recent individual validation error"""
# Context Properties
@property
def is_child(self) -> bool:
"""True if this is a child validator"""
@property
def document_path(self) -> tuple:
"""Current path within document during validation"""
@property
def schema_path(self) -> tuple:
"""Current path within schema during validation"""
@property
def root_document(self):
"""Root validator's document"""
@property
def root_schema(self):
"""Root validator's schema"""
@property
def root_allow_unknown(self):
"""Root validator's allow_unknown setting"""
@property
def root_require_all(self):
"""Root validator's require_all setting"""Integration with schema and rules registries.
@property
def schema_registry(self):
"""Schema registry instance"""
@schema_registry.setter
def schema_registry(self, registry):
"""Set schema registry"""
@property
def rules_set_registry(self):
"""Rules set registry instance"""
@rules_set_registry.setter
def rules_set_registry(self, registry):
"""Set rules set registry"""Error handling customization.
@property
def error_handler(self):
"""Current error handler instance"""Schema validation cache management.
@classmethod
def clear_caches(cls):
"""Clear schema validation cache"""Access to available validation rules and capabilities.
@property
def types(self):
"""Available type constraints mapping"""
@property
def validators(self):
"""Available validator methods"""
@property
def coercers(self):
"""Available coercion methods"""
@property
def default_setters(self):
"""Available default setter methods"""
@property
def rules(self):
"""Available validation rules"""
@property
def normalization_rules(self):
"""Rules applied during normalization"""
@property
def validation_rules(self):
"""Rules applied during validation"""
types_mapping: dict
"""Type names to TypeDefinition mapping (class attribute)"""
checkers: tuple
"""Available check_with methods (class attribute)"""Configuration of validation behavior.
mandatory_validations: tuple
"""Rules evaluated on every field"""
priority_validations: tuple
"""Rules processed first during validation"""from cerberus import Validator
# Create validator with schema
schema = {
'name': {'type': 'string', 'minlength': 2, 'maxlength': 50},
'age': {'type': 'integer', 'min': 0, 'max': 150},
'email': {'type': 'string', 'regex': r'^[^@]+@[^@]+\.[^@]+$'}
}
v = Validator(schema)
# Valid document
document = {
'name': 'John Doe',
'age': 30,
'email': 'john@example.com'
}
if v.validate(document):
print("Document is valid!")
else:
print("Validation errors:", v.errors)from cerberus import Validator
schema = {'name': {'type': 'string'}}
# Allow unknown fields
v = Validator(schema, allow_unknown=True)
v.validate({'name': 'John', 'extra': 'value'}) # True
# Require all schema fields
v = Validator(schema, require_all=True)
v.validate({'name': 'John'}) # True
v.validate({}) # False - missing required field
# Purge unknown fields
v = Validator(schema, purge_unknown=True)
doc = {'name': 'John', 'extra': 'value'}
normalized = v.normalized(doc) # {'name': 'John'}from cerberus import Validator
schema = {
'name': {'type': 'string', 'required': True},
'age': {'type': 'integer', 'required': True}
}
v = Validator(schema)
# Partial update - only validate provided fields
update = {'age': 25}
v.validate(update, update=True) # True - name not required for updatesfrom cerberus import Validator
v = Validator({'name': {'type': 'string'}})
# Use validator as callable
result = v({'name': 'John'}) # True
result = v({'name': 123}) # Falseclass DocumentError(Exception):
"""Raised when target document is missing or has wrong format"""This exception is raised when the document being validated is not in the expected format (typically when it's not a dictionary) or is missing entirely.
Install with Tessl CLI
npx tessl i tessl/pypi-cerberus