3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FastAPI Tutorialメモ その3 Query Parameters

Posted at

はじめに

FastAPI Souce: https://github.com/tiangolo/fastapi
FastAPI Document: https://fastapi.tiangolo.com

対象:Query Parameters

FastAPIチュートリアルのメモ。
基本的にはFastAPIの公式チュートリアルを参考にしていますが、自身の学習のため一部分を省略したり順番を前後させています。
正しい詳細な情報は公式ドキュメントを参考いただければと思います。

Web & Python 初心者かつ翻訳はGoogleとDeepL頼りのため、間違い等ありましたらご指摘いただけますと幸いです。

以前までのメモはこちら

開発環境

Ubuntu 20.04 LTS
Python 3.8.2
pipenv 2018.11.26

目標

  • FastAPIにおけるQuery Parameterの使い方を把握する

手順

Intro

前回( FastAPI Tutorialメモ その2 Path Parameters )、関数のパラメータとしてPathパラメータを渡す方法について学習しました。
今回はQueryパラメータを渡す方法について学習したいと思います。

FastAPIでは、Pathパラメータではないパラメータを関数の引数として宣言した場合、自動的にQueryパラメータとして解釈されます。
下記のコードを確認してください。

main.py
from fastapi import FastAPI

app = FastAPI()

fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]


@app.get("/items/")
async def read_item(skip: int = 0, limit: int = 10):    # <- Queryパラメータを指定している。
    return fake_items_db[skip : skip + limit]

HTTPのURIにおいてクエリは基本的に?の後に続くキーのペアを=でつなげて表現されます。
複数指定する場合は&でURIを区切ります。
上記のコードに合わせるのであれば、たとえば下記のようなURLが想定されます:

http://127.0.0.1:8000/items/?skip=0&limit=10

この場合のQueryパラメータは、

  • 値が0skip
  • 値が10limit

の2つが関数に渡されます。

これらはURLの一部であるため、通常は文字列(str)として解釈されるはずです。
しかし、上記のコードでは引数にパラメータを指定する際、Pythonの型であるint型で宣言したため、パラメータはint型への変換と検証が行われます。

これは、Pathパラメータで適用された以下の利点がQueryパラメータにも適用されることを意味しています。

  • エディタによるサポート
  • データの "parsing" (解析)
  • データの検証
  • 自動ドキュメンテーション

なお、これらの利点はPath、Queryに限らずFastAPIが扱う様々なパラメータでサポートされています。

Defaults (デフォルト値)

QueryパラメータはURIのパスで固定されているわけではなく、オプション設定であるため、デフォルト値を指定することが可能です。

先述のコードでは、デフォルト値としてskip=0limit=10が指定されていることが確認できます。
よって、このようなURL:

http://127.0.0.1:8000/items/

にブラウザからアクセスした場合、

http://127.0.0.1:8000/items/?skip=0&limit=10

上記2つのURLは同じ出力になります。

また、例えば下記のようなURL:

http://127.0.0.1:8000/items/?skip=20

にアクセスした場合、関数のパラメータは次のようになります:

  • URLで設定されたskip=20
  • デフォルト値limit=10

Optional parameters

デフォルト値をNoneとすることにより、オプションとして使用することができるQueryパラメータを宣言することも可能です。
例として、下記のコードを確認してください。

main.py
from typing import Optional     # typingパッケージからOptionalをインポート

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: str, q: Optional[str] = None):     # Queryパラメータ"q"をオプションパラメータとして宣言
    if q:
        return {"item_id": item_id, "q": q}
    return {"item_id": item_id}

この場合、関数のパラメータqはオプション扱いとなり、デフォルトではNoneとして扱われます。

この際にFastAPIがitem_idPathパラメータであり、qPathパラメータではなくQueryパラメータであることを理解している点に注目してください。

また、FastAPIでは=Noneが宣言されるだけでqがオプションのパラメータであることを認識しています。
OptionalはFastAPI自体が使用しているわけではありません。
わざわざOptional[str]としてオプションであることを明示しているのは、エディターのサポートによってエラーを事前に発見することができるためです。

Query parameter type conversion (Queryパラメータの型の変換)

Queryパラメータとしてbool型を宣言することができ、その場合、パラメータはFastAPIによって適した形に変換されれます。
例として、下記のコードを確認してください。

main.py
from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
# 引数のクエリパラメータにbool型を指定している
async def read_item(item_id: str, q: Optional[str] = None, short: bool = False):
    item = {"item_id": item_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

このようなコードの場合、以下のようにアクセスすることができます。

  • http://127.0.0.1:8000/items/foo?short=1
  • http://127.0.0.1:8000/items/foo?short=True
  • http://127.0.0.1:8000/items/foo?short=true
  • http://127.0.0.1:8000/items/foo?short=on
  • http://127.0.0.1:8000/items/foo?short=yes

これらのURLの場合、パラメータshortはすべてbool値Trueとして扱われます。(最初の文字を小文字から大文字にした場合でも同様です)
上記以外の値の場合はFalseとなります。
このように、Queryパラメータbool型を指定した場合はFastAPIによる変換が行われます。

Multiple path and query parameters (複数のPathパラメータとQueryパラメータ)

FastAPIでは関数の引数に複数のPathパラメータQueryパラメータを同時に宣言しても問題なく動作します。
また、それらを特定の順序に従って宣言する必要もありません。
FastAPIでは、パラメータを名前によって認識しているためです。

たとえば、このようなコードがあるとします:

main
from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/{user_id}/items/{item_id}")    # <- {user_id}と{item_id}をPathパラメータとして指定
async def read_user_item(
    user_id: int, item_id: str, q: Optional[str] = None, short: bool = False    # <- Pathパラメータではない"q"と"short"はQueryパラメータとして扱う
):
    item = {"item_id": item_id, "owner_id": user_id}
    if q:
        item.update({"q": q})
    if not short:
        item.update(
            {"description": "This is an amazing item that has a long description"}
        )
    return item

この場合、関数の引数の順序を入れ替えたとしても問題ありません。
FastAPIはあくまでもパラメータの名前を基準にして各パラメータを認識します。

Required query parameters (必須のクエリパラメータの指定)

Path以外のパラメータ(現時点ではQueryパラメータしか学習していませんが)でデフォルト値を宣言した場合、そのパラメータは省略不可の必須のパラメータではなくなります。
パラメータを省略した場合はデフォルト値が指定されるためです。

また、デフォルト値をNoneとすることで、特定の値を追加せずにパラメータを任意のオプションパラメータとして宣言することもできます。

では、Queryパラメータを省略不可能な必須のパラメータとして設定したい時はどうするかというと、デフォルト値を宣言しないことで実現できます。

main
from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(item_id: str, needy: str):     # <- デフォルト値を指定せずにパラメータneedyを宣言している
    item = {"item_id": item_id, "needy": needy}
    return item

上記のneedyパラメータは必須のstrQueryパラメータとして宣言されています。
もしあなたがこのようなURL:

http://127.0.0.1:8000/items/foo-item

をブラウザで開いた場合、必須パラメータであるneedyが追加されていないため、次のようなエラーが表示されるdでしょう。

{
    "detail": [
        {
            "loc": [
                "query",
                "needy"
            ],
            "msg": "field required",
            "type": "value_error.missing"
        }
    ]
}

needyは必須のパラメータなので、下記のようにURLで指定する必要があります:

http://127.0.0.1:8000/items/foo-item?needy=sooooneedy

このURLは次のように表示されます:

{
    "item_id": "foo-item",
    "needy": "sooooneedy"
}

もちろん、必須のパラメータとデフォルト値を持つパラメータとオプションのパラメータを同時に定義することも可能です。

main
from typing import Optional

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_user_item(
    item_id: str, needy: str, skip: int = 0, limit: Optional[int] = None    # <-
):
    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
    return item

上記のコードでは、3つのクエリパラメータが宣言されています。

  • needy: str型で(デフォルト値を持たない)必須のパラメータ
  • skip: int型でデフォルト値0のパラメータ
  • limit: int型でオプションのパラメータ

なお、Pathパラメータと同様にQueryパラメータでもEnumを使用することができます。
詳細はPath Parametersを確認ください。

終わりに

今回はQueryパラメータの使用方法を学習しました。
この記事で使用したコードはすべて公式ドキュメント からの引用になりますが、
私のローカル環境で動作することは確認できています。

次回はRequest Body を学習します。

3
3
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
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?