A lightweight library for converting complex datatypes to and from native Python datatypes
—
Marshmallow provides a comprehensive validation framework with built-in validators for common patterns and support for custom validation logic. Validators can be applied to individual fields or entire schemas.
All validators inherit from the base Validator class, which defines the validation interface.
class Validator:
"""
Abstract base class for all validators.
Attributes:
- error: str, default error message for validation failures
"""
def __call__(self, value):
"""
Perform validation on a value.
Parameters:
- value: the value to validate
Raises:
ValidationError: if validation fails
"""Validators that combine multiple validation rules.
class And(Validator):
"""
Compose multiple validators where all must pass.
Parameters:
- validators: sequence of validators to combine
- error: str, custom error message
"""
def __init__(self, *validators, error=None):
passValidators for text data with pattern matching and format validation.
class Email(Validator):
"""
Validate email addresses using regex pattern matching.
Parameters:
- error: str, custom error message
"""
def __init__(self, *, error=None):
pass
class URL(Validator):
"""
Validate URLs with configurable options.
Parameters:
- relative: bool, allow relative URLs (default: False)
- absolute: bool, allow absolute URLs (default: True)
- schemes: set, valid URL schemes (default: http, https, ftp, ftps)
- require_tld: bool, require top-level domain (default: True)
- error: str, custom error message
"""
def __init__(self, *, relative=False, absolute=True, schemes=None,
require_tld=True, error=None):
pass
class Regexp(Validator):
"""
Validate against a regular expression pattern.
Parameters:
- regex: str or compiled regex, regular expression pattern
- flags: int, regex flags (re.IGNORECASE, etc.)
- error: str, custom error message
"""
def __init__(self, regex, *, flags=0, error=None):
passValidators for numeric ranges and constraints.
class Range(Validator):
"""
Validate that a number is within a specified range.
Parameters:
- min: number, minimum value (inclusive by default)
- max: number, maximum value (inclusive by default)
- min_inclusive: bool, whether minimum is inclusive (default: True)
- max_inclusive: bool, whether maximum is inclusive (default: True)
- error: str, custom error message
"""
def __init__(self, min=None, max=None, *, min_inclusive=True,
max_inclusive=True, error=None):
passValidators for sequences, sets, and collection properties.
class Length(Validator):
"""
Validate the length of strings, lists, and other collections.
Parameters:
- min: int, minimum length
- max: int, maximum length
- equal: int, exact length required
- error: str, custom error message
"""
def __init__(self, min=None, max=None, *, equal=None, error=None):
pass
class OneOf(Validator):
"""
Validate that a value is one of a given set of choices.
Parameters:
- choices: iterable, valid choice values
- labels: iterable, human-readable labels for choices
- error: str, custom error message
"""
def __init__(self, choices, *, labels=None, error=None):
pass
class NoneOf(Validator):
"""
Validate that a value is not one of a given set of choices.
Parameters:
- choices: iterable, invalid choice values
- labels: iterable, human-readable labels for choices
- error: str, custom error message
"""
def __init__(self, choices, *, labels=None, error=None):
pass
class ContainsOnly(Validator):
"""
Validate that an iterable contains only the given choices.
Parameters:
- choices: iterable, valid choice values
- labels: iterable, human-readable labels for choices
- error: str, custom error message
"""
def __init__(self, choices, *, labels=None, error=None):
pass
class ContainsNoneOf(Validator):
"""
Validate that an iterable contains none of the given choices.
Parameters:
- choices: iterable, invalid choice values
- labels: iterable, human-readable labels for choices
- error: str, custom error message
"""
def __init__(self, choices, *, labels=None, error=None):
passValidators for equality comparison and custom predicate functions.
class Equal(Validator):
"""
Validate that a value equals a specific comparable value.
Parameters:
- comparable: the value to compare against
- error: str, custom error message
"""
def __init__(self, comparable, *, error=None):
pass
class Predicate(Validator):
"""
Validate using a custom predicate method on the value.
Parameters:
- method: str, method name to call on the value
- error: str, custom error message
"""
def __init__(self, method, *, error=None):
passfrom marshmallow import Schema, fields, validate
class UserSchema(Schema):
# Single validator
username = fields.Str(validate=validate.Length(min=3, max=20))
# Multiple validators using And
password = fields.Str(validate=validate.And(
validate.Length(min=8),
validate.Regexp(r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)')
))
# Choice validation
status = fields.Str(validate=validate.OneOf(['active', 'inactive', 'pending']))
# Numeric range
age = fields.Int(validate=validate.Range(min=18, max=120))
# Email validation
email = fields.Str(validate=validate.Email())
# URL validation
website = fields.Str(validate=validate.URL(schemes=['http', 'https']))
# Custom lambda validator
score = fields.Float(validate=lambda x: 0 <= x <= 100)class ArticleSchema(Schema):
# List length validation
tags = fields.List(fields.Str(), validate=validate.Length(min=1, max=10))
# List item validation
categories = fields.List(
fields.Str(validate=validate.OneOf(['tech', 'science', 'business']))
)
# Nested validation with ContainsOnly
valid_tags = fields.List(
fields.Str(),
validate=validate.ContainsOnly(['python', 'javascript', 'rust', 'go'])
)def validate_even(value):
"""Custom validator function."""
if value % 2 != 0:
raise ValidationError('Value must be even.')
class CustomValidator(validate.Validator):
"""Custom validator class."""
def __call__(self, value):
if not self.is_valid(value):
raise ValidationError(self.error or 'Validation failed')
def is_valid(self, value):
# Custom validation logic
return True
class NumberSchema(Schema):
# Using custom function validator
even_number = fields.Int(validate=validate_even)
# Using custom class validator
special_value = fields.Str(validate=CustomValidator())Schema-level validators are applied after field-level validation using the @validates_schema decorator.
from marshmallow import Schema, fields, validates_schema, ValidationError
class EventSchema(Schema):
start_date = fields.Date()
end_date = fields.Date()
@validates_schema
def validate_dates(self, data, **kwargs):
"""Validate that end_date is after start_date."""
if data.get('end_date') and data.get('start_date'):
if data['end_date'] < data['start_date']:
raise ValidationError('End date must be after start date.')class OrderSchema(Schema):
order_type = fields.Str(validate=validate.OneOf(['online', 'store']))
shipping_address = fields.Str()
store_location = fields.Str()
@validates_schema
def validate_order_requirements(self, data, **kwargs):
"""Validate requirements based on order type."""
if data.get('order_type') == 'online' and not data.get('shipping_address'):
raise ValidationError('Shipping address required for online orders.')
if data.get('order_type') == 'store' and not data.get('store_location'):
raise ValidationError('Store location required for store orders.')class ProductSchema(Schema):
name = fields.Str(
required=True,
validate=validate.Length(min=2, max=100),
error_messages={
'required': 'Product name is required.',
'validator_failed': 'Product name must be between 2 and 100 characters.'
}
)
price = fields.Decimal(
validate=validate.Range(min=0),
error_messages={
'validator_failed': 'Price must be a positive number.'
}
)
category = fields.Str(
validate=validate.OneOf(['books', 'electronics', 'clothing']),
error_messages={
'validator_failed': 'Category must be one of: books, electronics, clothing.'
}
)Install with Tessl CLI
npx tessl i tessl/pypi-marshmallow