Validation

Flaxon provides declarative validation schemas that automatically validate request data.

Basic Schema

from flaxon.validation import Schema, fields

class CreateUser(Schema):
    name = fields.String(required=True, min_length=2, max_length=80)
    email = fields.Email(required=True)
    age = fields.Integer(required=False, minimum=13, maximum=120)

Using Schemas in Routes

@app.post("/users")
async def create_user(data: CreateUser):
    # data is automatically validated
    # Invalid data returns 422
    return {"success": True, "user": data.to_dict()}

Field Types

String

class UserSchema(Schema):
    name = fields.String(
        required=True,
        min_length=2,
        max_length=80,
        strip=True,
        pattern=r"^[a-zA-Z\s]+$",
    )

Integer

class ProductSchema(Schema):
    price = fields.Integer(
        required=True,
        minimum=0,
        maximum=999999,
    )

Float

class PriceSchema(Schema):
    amount = fields.Float(
        required=True,
        minimum=0.0,
        maximum=9999.99,
    )

Boolean

class SettingsSchema(Schema):
    active = fields.Boolean(required=True)
    notifications = fields.Boolean(default=True)

Choice

class StatusSchema(Schema):
    status = fields.Choice(
        ["pending", "active", "suspended", "deleted"],
        required=True,
    )

Email

class ContactSchema(Schema):
    email = fields.Email(required=True)

Date

class EventSchema(Schema):
    date = fields.Date(required=True, format="%Y-%m-%d")

DateTime

class ScheduleSchema(Schema):
    datetime = fields.DateTime(required=True, format="%Y-%m-%dT%H:%M:%S")

UUID

class TokenSchema(Schema):
    token = fields.UUID(required=True)

List

class BulkCreateSchema(Schema):
    users = fields.List(
        item_field=fields.String(min_length=2),
        min_items=1,
        max_items=100,
    )

Nested

class AddressSchema(Schema):
    street = fields.String(required=True)
    city = fields.String(required=True)
    zipcode = fields.String(required=True, pattern=r"^\d{5}$")

class UserSchema(Schema):
    name = fields.String(required=True)
    address = fields.Nested(AddressSchema)

Validation Errors

@app.post("/users")
async def create_user(data: CreateUser):
    # If validation fails, Flaxon automatically returns:
    # {
    #   "success": false,
    #   "error": {
    #     "code": "FX-VAL-001",
    #     "message": "Request validation failed.",
    #     "fields": {
    #       "email": ["Enter a valid email address."],
    #       "age": ["Must be at least 13."]
    #     }
    #   }
    # }
    return {"user": data.to_dict()}

Custom Validators

from flaxon.validation.validators import custom_validator

def validate_unique_email(value, field):
    if email_exists(value):
        raise ValueError("Email already registered")

class CreateUser(Schema):
    email = fields.Email(
        required=True,
        validators=[custom_validator(validate_unique_email)],
    )

Combining Validators

from flaxon.validation.validators import and_validators, or_validators, email_validator, pattern_validator, length_validator

class UserSchema(Schema):
    # Must meet all conditions
    username = fields.String(
        validators=[and_validators(
            length_validator(3, 20),
            pattern_validator(r"^[a-zA-Z0-9_]+$"),
        )],
    )

    # Must meet at least one condition
    contact = fields.String(
        validators=[or_validators(
            email_validator(),
            pattern_validator(r"^\+\d{10,15}$"),
        )],
    )
Tip

Schemas also have a .validate() method for manual validation and .to_json() for serialization.