概要
前回 FastAPIに入門しました
今回はリクエストのバリデーションを実装する方法を紹介します
環境
- macOS 11.6.8
- Python 3.10.2
- FastAPI 0.83.0
pydandic の @validator を使う
おそらく一番メジャーでかつ簡単なのが pydantic の validator デコレータを使う方法だと思います
FastAPI は pydantic と密接に関係しており主にリクエストのモデルを扱う場合に使用する場合が多いです
なのでバリデーションも pydantic の機能を使うのが良いと思います
from pydantic import BaseModel, BaseSettings, validator
from fastapi import FastAPI
app = FastAPI()
class Settings(BaseSettings):
message: str = ""
settings = Settings()
class Item(BaseModel):
message: str
@validator('message')
def check_max_length(cls, v, values, **kwargs):
if len(v) > 10:
raise ValueError('Must be 10 characters or less.')
return v
@validator('message')
def contain_exclamation(cls, v, values, **kwargs):
if '!' not in v:
raise ValueError('Must contain a exclamation mark')
return v
@app.get("/")
async def get_msg():
return {"message": settings.message}
@app.post("/")
def set_msg(item: Item):
settings.message = item.message
return {"message": item.message}
解説
@validator('message')
がポイントです
BaseModel を継承したリクエストモデル用のクラスに実装します
引数の値はバリデーションを行うフィールドの値を指定します
同じフィールドい対してバリデーションのメソッドはいくつも登録することができるのでバリデーションの種類に応じてわけると良いかなと思います
ただバリデーションルールはOpenAPIに反映されない
これで /openapi.json を見るとわかるのですがバリデーション情報は openapi.json には反映されていません
Body を使う
pydantic を使わずにリクエストボディを定義することもできます (pydantic と組み合わせることもできます)
Body を使って定義することで openapi にもバリデーション情報が反映されます
from pydantic import BaseSettings
from fastapi import FastAPI, Body
app = FastAPI()
class Settings(BaseSettings):
message: str = ""
settings = Settings()
@app.get("/")
async def get_msg():
return settings.message
@app.post("/")
def set_msg(message: dict[str, str] = Body(max_length=10, regex=".*!.*", example={"message": "Hello!"})):
settings.message = message
return message
Body の他に指定可能なパラメータは参考サイトのURLを参照してください
動作確認
-
pipenv run uvicorn app:app --reload
で起動します
-
curl -XPOST localhost:8000 -H 'content-type: application/json' -d '{"message":"hoge!"}'
は成功します
-
curl -XPOST localhost:8000 -H 'content-type: application/json' -d '{"message":"hoge"}'
-
curl -XPOST localhost:8000 -H 'content-type: application/json' -d '{"message":"hogehogehoge!"}'
はエラーになることが確認できると思います
0 件のコメント:
コメントを投稿