Declarative API
Overview
The Declarative API is the modern, recommended way to define InputFilters in flask-inputfilter. It uses Python decorators and class-level declarations to create clean, readable, and maintainable input validation definitions.
Key Features
Clean Syntax: Define fields, conditions, and global components directly in class definition
Type Safety: Integrates well with type hints and IDEs
Inheritance Support: Full support for class inheritance and MRO
Model Integration: Automatic serialization to dataclasses, Pydantic models, and more
Multiple Element Support: Register multiple components at once for concise definitions
Core Components
The Declarative API consists of four main decorators:
Quick Example
from flask_inputfilter import InputFilter
from flask_inputfilter.declarative import field, condition, global_filter, global_validator, model
from flask_inputfilter.filters import StringTrimFilter, ToLowerFilter
from flask_inputfilter.validators import IsStringValidator, LengthValidator, EmailValidator
from flask_inputfilter.conditions import EqualCondition
from dataclasses import dataclass
@dataclass
class User:
username: str
email: str
password: str
class UserRegistrationFilter(InputFilter):
# Field definitions with individual configuration
username = field(
required=True,
validators=[LengthValidator(min_length=3, max_length=20)]
)
email = field(
required=True,
validators=[EmailValidator()]
)
password = field(required=True, validators=[LengthValidator(min_length=8)])
password_confirmation = field(required=True)
# Global components - applied to all fields
global_filter(StringTrimFilter(), ToLowerFilter())
global_validator(IsStringValidator())
# Cross-field validation
condition(EqualCondition('password', 'password_confirmation'))
# Model association
model(User)
Declarative API
class MyFilter(InputFilter):
name = field(required=True, validators=[IsStringValidator()])
email = field(required=True, validators=[EmailValidator()])
global_filter(StringTrimFilter())
condition(RequiredCondition('name'))
Inheritance and MRO
The Declarative API fully supports Python’s inheritance and Method Resolution Order (MRO):
class BaseUserFilter(InputFilter):
# Base fields
name = field(required=True, validators=[IsStringValidator()])
# Base global components
global_filter(StringTrimFilter())
class ExtendedUserFilter(BaseUserFilter):
# Additional fields
email = field(required=True, validators=[EmailValidator()])
age = field(required=False, validators=[IsIntegerValidator()])
# Additional global components (inherited ones are preserved)
global_validator(LengthValidator(min_length=1))
# Conditions
condition(RequiredCondition('email'))
Field Override
You can override fields from parent classes:
class BaseFilter(InputFilter):
name = field(required=False) # Optional in base
class StrictFilter(BaseFilter):
name = field(required=True, validators=[LengthValidator(min_length=2)]) # Override
Multiple Element Registration
You can register multiple components at once for cleaner definitions:
class CompactFilter(InputFilter):
name = field(required=True)
email = field(required=True)
# Multiple global filters
global_filter(StringTrimFilter(), ToLowerFilter(), RemoveExtraSpacesFilter())
# Multiple global validators
global_validator(IsStringValidator(), NotEmptyValidator())
# Multiple conditions
condition(
RequiredCondition('name'),
RequiredCondition('email'),
EqualCondition('password', 'password_confirmation')
)
Model Integration
The Declarative API seamlessly integrates with various model types:
Dataclasses
from dataclasses import dataclass
@dataclass
class User:
name: str
email: str
class UserFilter(InputFilter):
name = field(required=True, validators=[IsStringValidator()])
email = field(required=True, validators=[EmailValidator()])
model(User)
# Usage
filter_instance = UserFilter()
user = filter_instance.validate_data({'name': 'John', 'email': 'john@example.com'})
# user is a User dataclass instance
Pydantic Models
from pydantic import BaseModel
class User(BaseModel):
name: str
email: str
class UserFilter(InputFilter):
name = field(required=True, validators=[IsStringValidator()])
email = field(required=True, validators=[EmailValidator()])
model(User)
TypedDict
from typing import TypedDict
class UserDict(TypedDict):
name: str
email: str
class UserFilter(InputFilter):
name = field(required=True, validators=[IsStringValidator()])
email = field(required=True, validators=[EmailValidator()])
model(UserDict)
Next Steps
For detailed information about each component, see:
Field Decorator - Complete field configuration options
Global Decorators - Global filters, validators, and conditions
Conditions - Cross-field validation conditions
Filters - Available filters and custom filter creation
Validators - Available validators and custom validator creation