Flaxon 0.3.0 and Teloce-Py 0.3.0 are available on PyPI. Release instructions are maintained on this site; source links identify the framework snapshot. Check version and upgrade guidance.
Validation
Overview
Flaxon provides declarative validation schemas that automatically validate request data and inject validated objects into route handlers.
Validation supports:
- Type checking
- Required fields
- Length validation
- Range validation
- Custom validators
- Nested schemas
- Serialization
- Automatic error responses
Basic Schema
from flaxon.validation import Schema, fields
class CreateUser(Schema):
name = fields.StrField(
required=True,
min_length=2,
max_length=80
)
email = fields.EmailField(
required=True
)
age = fields.IntField(
required=False,
minimum=13,
maximum=120
)
````
---
# Using Schemas in Routes
```python
@app.post("/users")
async def create_user(data: CreateUser):
# Data is automatically validated
return {
"success": True,
"user": data.to_dict()
}
Invalid data automatically returns:
{
"error": {
"code": "FX-VAL-001",
"message": "Validation failed"
}
}
Field Types
String
class UserSchema(Schema):
name = fields.StrField(
required=True,
min_length=2,
max_length=80,
strip=True,
pattern=r"^[a-zA-Z\s]+$"
)
Integer
class ProductSchema(Schema):
price = fields.IntField(
required=True,
minimum=0,
maximum=999999
)
Float
class PriceSchema(Schema):
amount = fields.FloatField(
required=True,
minimum=0.0,
maximum=9999.99
)
Boolean
class SettingsSchema(Schema):
active = fields.BoolField(
required=True
)
notifications = fields.BoolField(
default=True
)
Choice
class StatusSchema(Schema):
status = fields.ChoiceField(
[
"pending",
"active",
"suspended",
"deleted"
],
required=True
)
class ContactSchema(Schema):
email = fields.EmailField(
required=True
)
Date
class EventSchema(Schema):
date = fields.DateField(
required=True,
format="%Y-%m-%d"
)
DateTime
class ScheduleSchema(Schema):
datetime = fields.DateTimeField(
required=True,
format="%Y-%m-%dT%H:%M:%S"
)
UUID
class TokenSchema(Schema):
token = fields.UUIDField(
required=True
)
List Field
class BulkCreateSchema(Schema):
users = fields.ListField(
item_field=fields.StrField(
min_length=2
),
min_items=1,
max_items=100
)
Nested Schemas
class AddressSchema(Schema):
street = fields.StrField(
required=True
)
city = fields.StrField(
required=True
)
zipcode = fields.StrField(
required=True,
pattern=r"^\d{5}$"
)
class UserSchema(Schema):
name = fields.StrField(
required=True
)
address = fields.NestedField(
AddressSchema
)
Validation Errors
@app.post("/users")
async def create_user(data: CreateUser):
return {
"user": data.to_dict()
}
If validation fails:
{
"success": false,
"error": {
"code": "FX-VAL-001",
"message": "Request validation failed.",
"fields": {
"email": [
"Enter a valid email address."
],
"age": [
"Must be at least 13."
]
}
}
}
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.EmailField(
required=True,
validators=[
custom_validator(
validate_unique_email
)
]
)
Combining Validators
from flaxon.validation.validators import (
and_validators,
or_validators,
)
class UserSchema(Schema):
username = fields.StrField(
validators=[
and_validators(
length_validator(3, 20),
pattern_validator(
r"^[a-zA-Z0-9_]+$"
)
)
]
)
contact = fields.StrField(
validators=[
or_validators(
email_validator(),
pattern_validator(
r"^\+\d{10,15}$"
)
)
]
)
Serialization
Objects returned from routes are automatically serialized.
@app.get("/users/<int:user_id>")
async def get_user(user_id: int):
user = await db.fetch_one(
"SELECT * FROM users WHERE id = $1",
user_id
)
return user
Custom Serialization
class UserSchema(Schema):
name = fields.StrField()
email = fields.EmailField()
def to_dict(self):
return {
"name": self.name,
"email": self.email,
"display_name": self.name.upper()
}
Full Example
from flaxon import Flaxon
from flaxon.validation import (
Schema,
fields
)
from flaxon.validation.validators import (
custom_validator
)
app = Flaxon(
"validation-demo"
)
def validate_unique_username(value, field):
if value == "admin":
raise ValueError(
"Username already exists"
)
class CreateUser(Schema):
username = fields.StrField(
required=True,
min_length=3,
max_length=30,
pattern=r"^[a-zA-Z0-9_]+$",
validators=[
custom_validator(
validate_unique_username
)
]
)
email = fields.EmailField(
required=True
)
password = fields.StrField(
required=True,
min_length=8,
max_length=128
)
age = fields.IntField(
required=False,
minimum=13,
maximum=120
)
role = fields.ChoiceField(
[
"user",
"moderator",
"admin"
],
default="user"
)
class UpdateUser(Schema):
username = fields.StrField(
min_length=3,
max_length=30
)
email = fields.EmailField()
age = fields.IntField(
minimum=13,
maximum=120
)
@app.post("/users")
async def create_user(data: CreateUser):
# Hash password before saving
return {
"success": True,
"user": data.to_dict()
}
@app.patch("/users/<int:user_id>")
async def update_user(
user_id: int,
data: UpdateUser
):
return {
"updated": True,
"id": user_id,
"data": data.to_dict()
}
Validation Best Practices
- Validate all incoming data.
- Never trust client input.
- Use schemas for API requests.
- Keep validation separate from business logic.
- Create reusable validators.
- Return meaningful validation errors.
- Validate file uploads.
- Validate authentication payloads.
- Use nested schemas for complex objects.
Next Steps
Continue with:
- Authentication
- Authorization
- Serialization
- Error Handling
- Database Integration
- API Development
Use this capability in a full-stack app
Flaxon serves Python APIs and Teloce interfaces in one project. Keep validation, authorization and privileged operations on the server; components call those endpoints and present their results. Follow the full-stack lessons and Teloce integration reference to connect this capability to pages, components and application modules.