輸入與輸出驗證--fastapi教程系列

概述

本文主要講解如何使用mypy(typing)和pydantic標註類,實現輸入和輸出參數序列化(用drf的話叫序列化)。
主要功能就是驗證輸入參數和輸出參數並轉換爲標準格式
以BaseModel實例爲例,實際上數據在basemodel和body等參數使用規則是一致的。
(有價值的參考:https://blog.csdn.net/swinfans/article/details/89629641)

數據類型

數據類型的核心就在於,一切都基於類,而我們要做的就是把輸入輸出的數據用類標註出來。

基礎數據類型

基礎類型主要是分爲如下幾種:int、float、string、bytes,其他的數據類型都是以基礎數據類型進行擴展而得到的。

from pydantic import BaseModel
class Test(BaseModel):
	int_a:int=None
	float_b:float=1.1
	str_c:string
	bytes_d:bytes # 一般這個是用來返回文件的,主要是獲取二進制數據

注意:如果爲非必須數據,可以使用=None或等於規定類型數據的方式來提供初始值,當然fastapi也可以設置:如果輸入的參數爲默認值則不將該結果錄入到輸入

擴展數據類型

擴展數據類型主要是指對基礎數據類型更多的要求,比如:url類型(string擴展,對數據結構有要求),image類型(對bytes的擴展),datetime類型(屬於類類型,實際也是string的擴展)、date類型等等。(甚至你可以自己定義類型)
這裏舉個簡單的例子:

from pydantic import HttpUrl, BaseModel
from datetime import datetime # 這裏還包括date、datetleta

class Test(BaseModel):
    url:HttpUrl
    t:datetime

常用類型:我能看懂的如下:

    # network
    'AnyUrl', 'AnyHttpUrl', 'HttpUrl', 'stricturl', 'EmailStr', 'NameEmail', 'IPvAnyAddress', 'IPvAnyInterface',
    'IPvAnyNetwork', 'PostgresDsn', 'UUID1', 'UUID3', 'UUID4', 'UUID5', 'FilePath', 'DirectoryPath', 'Json',
    # 非pydantic包裏面的類型
    # from datetime
    'datetime', 'date',
    # from typing
    'List', 'Dict', 'Set', 'Enum', 'Union'

更多的基礎數據類型請自行參考pydantic的文檔。也可以自己寫驗證數據的方法然後

複合數據類型:list、dict、set、enum、union

複合數據類型主要是列表list,字典dict,集合set等。定義方式與基礎數據類型最大的區別就是,這些類型主要是存儲多個基礎數據類型的。
要定義這些數據,需要有一點c語言的思維,單純用list進行標註,有時候並不能得到更好的數據驗證。
比如我只想list存儲數字,那麼就不能存儲字符串,這種情況可以這麼寫list_e:List[int],如果單純想存數字和bytes,可以這麼寫:list_f:List[int,bytes]。方括號裏面是可選的類型。如果想讓該值也可以爲空,則需要使用Optional進行包裝:Optional[List[int,bytes]]
這裏我舉一些常見結構:

from typing import Optional, Dict, Union,List
class TestTuping(BaseModel):
	dict_a: Dict[str,Union[str,int]] = {"chise": "asd","abc":4}#字典的鍵必須是str,值必須爲int或str。注意dict_a不能爲None
	list_b:Optional[List[int]]#dict_b可以爲None,或者元素全部是int的list類型,Set,tuple參考這一條,
	dict_c:dict_c:Dict[str,HttpUrl]#當然也可以使用上述的擴展數據類型。(自定義的也可以使用)

自定義數據類型與驗證

由於pydantic可以做嵌套,所以我們可以自己定義數據驗證,下面是一個簡單的自定義數據驗證例子:

from pydantic import  ValidationError
class Url(BaseModel):
    url: str
    @validator('url')
    def url_must_contain_space(cls, v):
        if ' ' not in v:
            raise ValidationError('must contain a space')#如果錯誤就觸發這個錯誤
        return v#如果正確就返回結果
#使用方式如下:
class NANME(BaseModel):
	url:Url

一些額外的自動處理方式

可以在BaseModel的繼承類裏面使用class config進行一些配置:

class Test(BaseModel):
	i:int 
	class config:
		min_anystr_length=True
		...

config的常用部分配置如下:
Config 類包含如下一些類屬性:

anystr_strip_whitespace:是否消除字符串或者字節的前導和後置空白空格。默認爲 False。
min_anystr_length:字符串或字節的最小長度。默認爲0。
max_anystr_length:字符串或字節的最大長度。默認爲 2 ** 16
validate_all:是否驗證字段的默認值。默認爲 False。
extra:是否忽略、允許或禁止模型中的額外屬性。可以使用字符串值 ignor,allow或 forbid,也可以使用 Extra 的枚舉值。默認值是 Extra.ignore。
use_enum_values:是否使用枚舉的 value 特性填充模型,而不是使用原始枚舉。這在您希望序列化 model.dict() 時非常有用。默認值爲 False。
validate_assignment:是否在爲屬性賦值時執行驗證。默認爲 False
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章