# Validation

One of the most commonly implemented features of a web application is user-input validation. For obvious reasons, this is not only a security issue, but also just plain good practice. You want to make sure your data conforms to expectations, and throw a 400 response when it does not.

# Implementation

# Validation with Dataclasses

With the introduction of Data Classes (opens new window), Python made it super simple to create objects that meet a defined schema. However, the standard library only supports type checking validation, not runtime validation. Sanic Extensions adds the ability to do runtime validations on incoming requests using dataclasses.

First, define a model.

@dataclass
class SearchParams:
    q: str

Then, attach it to your route

from sanic_ext import validate
@app.route("/search")
@validate(query=SearchParams)
async def handler(request, query: SearchParams):
    return json(asdict(query))

You should now have validation on the incoming request.

$ curl localhost:8000/search                                       
⚠️ 400 — Bad Request
====================
Invalid request body: SearchParams. Error: missing a required argument: 'q'
$ curl localhost:8000/search\?q=python                             
{"q":"python"}

# Validation with Pydantic

WARNING

Currently, only JSON body validation supports Pydantic models.

You can use Pydantic models also.

First, define a model.

class Person(BaseModel):
    name: str
    age: int

Then, attach it to your route

from sanic_ext import validate
@app.post("/person")
@validate(json=Person)
async def handler(request, body: Person):
    return json(body.dict())

You should now have validation on the incoming request.

$ curl localhost:8000/person -d '{"name": "Alice", "age": 21}' -X POST  
{"name":"Alice","age":21}

# What can be validated?

The validate decorator can be used to validate incoming user date from three places: JSON body data (request.json), form body data (request.form), and query parameters (request.args).

As you might expect, you can attach your model using the keyword arguments of the decorator.

@validate(
    json=ModelA,
    query=ModelB,
    form=ModelC,
)
MIT Licensed
Copyright © 2018-present Sanic Community Organization

~ Made with ❤️ and ☕️ ~