LoginSignup
2
5

More than 1 year has passed since last update.

FastAPIで作るWebアプリ - Body validation

Last updated at Posted at 2021-10-30

今回はFastAPIのRequest BodyのValidationについてです。

【過去記事】
Python Asyncio入門
Aiohttpで作るSimple Web Server - Qiita
Starletteで作る Simple Web Server - QIita
FastAPIで作るWebアプリ - 基本
FastAPIで作るWebアプリ - validation
FastAPIで作るWebアプリ - Body validation
FastAPIで作るWebアプリ - Form validation

FastAPI 公式サイト

1.基本的なBody関数

body1.py
from fastapi import Body, FastAPI

app = FastAPI()

@app.post("/items/")
async def create_item(name: str=Body(...), price: float=Body(...)):
    return {"name": name, "price": price}

FastAPIで作るWebアプリ - validation」で述べたようにクエリパラメータの場合は**Query()関数が使われますが、リクエストボディの場合はBody()**が用いられます。

(補足2022/07/22)
(...)はPythonの値でEllipsisと呼ばれています。
PydanticとFastAPI において、Ellipsisは値の指定が必須であることを表現するために使われています。
Query Parameters and String Validations

プログラムを起動します。

uvicorn body1:app --reload

以下の正常なデータをRequestします。

curl -X 'POST' 'http://localhost:8000/items/' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"name": "Hanako", "price": 12.5}'

サーバ側は200 okで、クライアント側は以下のメッセージを受け取ります。

{"name":"Hanako","price":12.5}

2.Pydantic modelsでスマートな検証

Pydantic はデータ検証のためのPythonライブラリです。Pythonのtype hintが使われます。
前に取り上げたプログラムを再掲載して、より詳細な説明を加えます。

body2.py
from fastapi import FastAPI
from typing import Optional
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.post("/items/")
async def create_item(item: Item):
    return item
  • まずすべての基本となるBaseClassをimportします。
  • 次に、それを継承する、われわれのClassであるItemを定義します。Itemの任意のプロパティはtype hintをもちます。これを基にPydanticは送られてきたBodyの検証を行います。
  • 最後に引数item のtype hintにItemを指定します。FastAPIはRequestのBodyが型Itemを持っていると知っていて、検証を行います。

以下の正常なデータをRequestします。

curl -X 'POST' 'http://localhost:8000/items/' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"name": "Hanako", "price": 12.5}'

サーバ側は200 okで、クライアント側は以下のメッセージを受け取ります。

{"name":"Hanako","description":null,"price":12.5,"tax":null}

以下のエラーデータをRequestしてみます

curl -X 'POST' 'http://localhost:8000/items/' -H 'accept: application/json' -H 'Content-Type: application/json' -d '{"name": "Hanako", "price": "abc"}'

サーバ側は422 Unprocessable Entityを出力し、クライアント側には以下のエラーメッセージを送ります。

{"detail":[{"loc":["body","price"],"msg":"value is not a valid float","type":"type_error.float"}]}

これは個人的には結構スマートな機能だと思います。

今回は以上です。

2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5