LoginSignup
0
2

More than 1 year has passed since last update.

FastAPIで作るWebアプリ - validation

Last updated at Posted at 2021-10-29

今回はRequest パラメータのバリデーションを取り上げます。パスパラメータとクエリパラメータです。Swagger UIとともに、FastAPIでの開発効率を上げてくれるものです。

【過去記事】
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.パスパラメータ

1-1.型チェック

前回と同じプログラムを使います。

path.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/items/{item_id}")
async def read_item(item_id : int):
    return {"item_id": item_id}

起動します

uvicorn path:app --reload

前回はもっぱらSwagger UIからRequestを投げましたが、今回はサーバ側のエラーチェックを確認するためcurlコマンドを使います。

curl http://localhost:8000/items/123 

サーバ側のステータス(200 OK)も確認して、クラシアン側に以下のコンテンツが返ってくることも確認します。

{"item_id":123}

今度はエラーデータをRequestします。

curl http://localhost:8000/items/f00 

サーバ側のステータス(422 Unprocessable Entity)はエラーとなり、クライアント側にも以下のエラーが返ってきます。型を正しくチェックしているのがわかります。

{"detail":[{"loc":["path","item_id"],"msg":"value is not a valid integer","type":"type_error.integer"}]}

1-2.Enumによる値の制限

Enumを使ってパスパラメータの値を制限することができます。

pathenum.py
from enum import Enum
from fastapi import FastAPI

app = FastAPI()

Class Color(str,Enum)
    RED = 'red'
    GREEN = 'green'
    BLUE = 'blue'

@app.get("/items/{color}/{item_id}")
async def read_item(color : Color, item_id : int):
    return {"color": color, "item_id": item_id}

ここでEnum classであるColorは親としてstrが必要です。
String-based enum in Python

正しいRequestを投げます

curl http://localhost:8000/items/red/123

サーバ側は200 okで、クライアント側は以下のコンテンツを受け取ります。

{"color":"red","item_id":123}

それでは正しくないRequestを投げます。'black'はEnumには含まれていません。

curl http://localhost:8000/items/black/123

サーバ側は422 Unprocessable Entityとなり、クライアント側は以下のエラーを受け取ります。

{"detail":[{"loc":["path","color"],"msg":"value is not a valid enumeration member; permitted: 'red', 'green', 'blue'","type":"type_error.enum","ctx":{"enum_values":["red","green","blue"]}}]}

ここまでで、如何にvalidationが、Pythonのtype hintの記述で、自然に行われるかがわかります。もっと多くのエラーチェックがありますが、次に進んでいきましょう。

2.クエリパラメータ

以下のようなプログラムを考えます。

query.py
from typing import Optional

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Optional[str] = Query(None, max_length=5)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

Query()関数でより進んだValidationを行うことができます。第一引数にdefault値をとり、第二引数以降にValidationを記述します。Query(None, min_length=3) はデフォルト値がNoneで3文字以上の文字列の値が必要です。デフォルト値を指定せず、値の指定が必須の場合はQuery(..., min_length=3)と書きます。

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

それでは正常なRequestを発行してみましょう

curl http://localhost:8000/items/?q=foo

サーバ側に200 okが表示され、クライアント側には以下の値が返ります。

{"items":[{"item_id":"Foo"},{"item_id":"Bar"}],"q":"foo"}

それでは文字列に長さが5を超えるものを指定してみましょう。

curl http://localhost:8000/items/?q=foofoo

サーバ側に422 Unprocessable Entityが表示され、クライアント側に以下のエラーが表示されます。

{"detail":[{"loc":["query","q"],"msg":"ensure this value has at most 5 characters","type":"value_error.any_str.max_length","ctx":{"limit_value":5}}]}

パスパラメータとクエリパラメータのValidationについて見てきましたが、とても簡単です。またここでは十分に取り上げられませんでしたが、とても豊富です。FastAPIの開発効率が良いのも十分理解できます。

Request Bodyについては次回取り上げるつもりです。

今回は以上です。

0
2
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
0
2