The last blog discussed a method of data validation, exemplified through a POST request, that utilized a class whose __init__
method attempted to assign parameters and threw an error if a parameter did not exist. Unfortunately, that class structure was a bit simplistic and also lacked features such as too many parameters being passed through.
However, Pydantic provides a better method to ensure your data looks exactly as it should. Here is a simple example to show.
Pydantic models
are easy to set up. Just import and pass the BaseModel
to your class.
from pydantic import BaseModel
class Person(BaseModel):
first_name: str
last_name: str
This is very similar to a class with the dataclass decorator and now you can initialize your model:
>>> person = Person(first_name="nav", last_name="610")
>>> person.first_name
'nav'
I can also add validators to my model, such that on initialization, the input parameters are checked against my custom validators:
class Person(BaseModel):
first_name: str
last_name: str
age: Optional[int]
email: Optional[str]
@validator('email')
def validate_email(cls, email):
if email and not any(email.endswith(provider) for provider in ['@gmail.com', '@yahoo.com', '@outlook.com']):
raise ValidationError
return email
I've added two extra parameters, age
and email
, and can validate the email upon initialization. If the email doesn't end properly, a ValidationError is raised
Also, I can define a configuration such that extra data cannot be passed through.
class Person(BaseModel):
first_name: str
last_name: str
age: Optional[int]
email: Optional[str]
@validator('email')
def validate_email(cls, email):
if email and not any(email.endswith(provider) for provider in ['@gmail.com', '@yahoo.com', '@outlook.com']):
raise ValidationError
return email
class Config:
extra = Extra.forbid
This configuration forbids the passing of extra parameters and will throw the following Validation error if extra parameters are passed through:
1 validation error for Person
blah
extra fields not permitted (type=value_error.extra)
Now I can use the same POST request example from the previous blog and get the following:
from flask import Flask
from flask import request
from flask import jsonify
from pydantic import BaseModel, ValidationError, validator, Extra
from typing import Optional
app = Flask(__name__)
class Person(BaseModel):
first_name: str
last_name: str
age: Optional[int]
email: Optional[str]
@validator('email')
def validate_email(cls, email):
if email and not any(email.endswith(provider) for provider in ['@gmail.com', '@yahoo.com', '@outlook.com']):
raise ValidationError
return email
class Config:
extra = Extra.forbid
@app.route("/create", methods=["POST"])
def create():
payload = request.get_json()
person: Person = Person(**payload)
return jsonify({"status": "ok"})
if __name__ == "__main__":
app.run(host="0.0.0.0", debug=True, port=8888)
A POST request with very easy data validation!