A schema and validator for YAML with comprehensive data type validation and constraint support.
Schema creation, include management, and validation result handling for building complex validation structures. This module provides the core classes for managing YAML schemas and processing validation results.
Main schema representation that processes YAML schema definitions and validates data against defined rules.
class Schema:
"""
Schema object that represents a YAML validation schema.
"""
def __init__(self, schema_dict, name="", validators=None, includes=None):
"""
Create a Schema object from a schema dictionary.
Parameters:
- schema_dict (dict): Dictionary representing the schema structure
- name (str): Optional name for the schema
- validators (dict, optional): Validator dictionary, defaults to DefaultValidators
- includes (dict, optional): Existing includes dictionary for shared includes
Attributes:
- validators: Dictionary of available validators
- dict: Original schema dictionary
- name: Schema name
- includes: Dictionary of included sub-schemas
"""
def add_include(self, type_dict):
"""
Add include definitions to the schema.
Parameters:
- type_dict (dict): Dictionary of include names to schema definitions
"""
def validate(self, data, data_name, strict):
"""
Validate data against this schema.
Parameters:
- data: Data to validate
- data_name (str): Name/path for error reporting
- strict (bool): Enable strict validation mode
Returns:
ValidationResult: Result of validation with errors if any
"""
# Schema attributes
validators: dict # Available validators dictionary
dict: dict # Original schema dictionary
name: str # Schema name
includes: dict # Dictionary of included sub-schemas
class FatalValidationError(Exception):
"""
Exception raised for fatal validation errors during schema processing.
"""
def __init__(self, error):
"""
Initialize with error message.
Parameters:
- error (str): Error message
Attributes:
- error: Error message string
"""
error: str # Error messageUsage examples:
# Create schema from dictionary
schema_dict = {
'name': 'str()',
'age': 'int(min=0)',
'emails': 'list(str())'
}
schema = yamale.schema.Schema(schema_dict)
# Add external includes after creation
includes = {
'address': {
'street': 'str()',
'city': 'str()',
'zip': 'str()'
}
}
schema.add_include(includes)
# Validate data
data = {'name': 'John', 'age': 30, 'emails': ['john@example.com']}
result = schema.validate(data, 'test.yaml', strict=True)Classes that represent the outcome of validation operations with detailed error information.
class ValidationResult(Result):
"""
Contains the result of validating data against a schema.
Inherits from Result class.
"""
def __init__(self, data, schema, errors):
"""
Initialize validation result.
Parameters:
- data (str): Path or identifier of validated data
- schema (str): Path or identifier of schema used
- errors (list): List of validation error messages
Attributes:
- data: Data identifier that was validated
- schema: Schema identifier used for validation
- errors: List of error messages
"""
def isValid(self):
"""
Check if validation passed.
Returns:
bool: True if no errors, False otherwise
"""
def __str__(self):
"""
Get human-readable representation of validation result.
Returns:
str: Formatted validation result message
"""
class Result:
"""
Base result class for validation operations.
"""
def __init__(self, errors):
"""
Initialize result with error list.
Parameters:
- errors (list): List of error messages
Attributes:
- errors: List of error messages
"""
def isValid(self):
"""
Check if result represents success.
Returns:
bool: True if no errors, False otherwise
"""
def __str__(self):
"""
Get string representation of errors.
Returns:
str: Newline-separated error messages
"""Usage examples:
# Check validation results
results = yamale.validate(schema, data, _raise_error=False)
for result in results:
if result.isValid():
print(f"✓ {result.data} is valid")
else:
print(f"✗ {result.data} failed validation:")
for error in result.errors:
print(f" - {error}")
# Access result attributes
result = results[0]
print(f"Data: {result.data}")
print(f"Schema: {result.schema}")
print(f"Error count: {len(result.errors)}")
print(f"Valid: {result.isValid()}")Yamale supports a powerful includes system for schema composition and reuse.
Define reusable schema components in separate YAML documents:
# Main schema document
user: include('person')
admin: include('person')
---
# Include definitions
person:
name: str()
age: int(min=0)
email: str()Create self-referencing schemas for tree structures:
directory: include('folder')
---
folder:
name: str()
files: list(str(), required=False)
subdirs: list(include('folder'), required=False)# Create base schema
schema = yamale.make_schema('./base-schema.yaml')
# Add external includes dynamically
external_includes = {
'address': {
'street': 'str()',
'city': 'str()',
'country': 'str(equals="US")'
},
'contact': {
'phone': 'str()',
'email': 'str()',
'address': 'include("address")'
}
}
schema.add_include(external_includes)
# Now schema can use include('address') and include('contact')Control strict validation per include:
user_data: include('user', strict=False) # Allow extra fields in user data
system_config: include('config') # Use default strict mode
---
user:
name: str()
preferences: map() # Flexible user preferences
config:
debug: bool()
timeout: int()# Schema with multiple include documents
schema_content = """
api_request: include('request')
api_response: include('response')
---
request:
method: str()
url: str()
headers: map(str(), required=False)
---
response:
status: int()
body: any()
headers: map(str(), required=False)
"""
schema = yamale.make_schema(content=schema_content)# Create custom validator
class EmailValidator(yamale.validators.Validator):
tag = 'email'
def _is_valid(self, value):
return '@' in str(value) and '.' in str(value)
# Create custom validator set
custom_validators = yamale.validators.DefaultValidators.copy()
custom_validators['email'] = EmailValidator
# Use in schema
schema = yamale.make_schema(
content="contact_email: email()",
validators=custom_validators
)Schema operations may raise several types of exceptions:
Always handle these exceptions when working with dynamic schema creation:
try:
schema = yamale.make_schema('./schema.yaml')
results = yamale.validate(schema, data)
except (SyntaxError, ValueError) as e:
print(f"Schema error: {e}")
except yamale.YamaleError as e:
print(f"Validation error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-yamale