コンテンツにスキップ

クエリパラメータと文字列検証

FastAPI では、パラメータに追加情報と検証を宣言できます。

このアプリケーションを例にとってみましょう

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/")
async def read_items(q: str | None = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI

app = FastAPI()


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

クエリパラメータ qUnion[str, None] 型(Python 3.10 では str | None)です。これは、str 型ですが None にもなり得ることを意味し、実際、デフォルト値は None なので、FastAPI はそれが必須ではないことを認識します。

注記

FastAPI は、デフォルト値 = None によって q の値が必須ではないことを認識します。

Union[str, None]Union によって、エディタはより良いサポートを提供し、エラーを検出できます。

追加検証

q はオプションですが、指定された場合は**長さが 50 文字を超えない**ようにします。

QueryAnnotated をインポートする

これを実現するには、まずインポートします

  • fastapi から Query
  • typing から Annotated(Python 3.9 未満では typing_extensions から)

Python 3.9 以降では、Annotated は標準ライブラリの一部であるため、typing からインポートできます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


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

Python 3.9 未満のバージョンでは、typing_extensions から Annotated をインポートします。

これは FastAPI と一緒にインストールされます。

from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


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

情報

FastAPI はバージョン 0.95.0 で Annotated のサポートを追加し(推奨を開始しました)。

古いバージョンを使用している場合、Annotated を使用しようとするとエラーが発生します。

Annotated を使用する前に、FastAPI のバージョンを少なくとも 0.95.1 にアップグレードしてください。

q パラメータの型に Annotated を使用します

以前、Python の型入門で、Annotated を使用してパラメータにメタデータを追加できることを説明したのを覚えていますか?

FastAPI でそれを使用するときが来ました。🚀

この型注釈がありました

q: str | None = None
q: Union[str, None] = None

これから行うことは、それを Annotated でラップすることです。つまり、次のようになります。

q: Annotated[str | None] = None
q: Annotated[Union[str, None]] = None

これらの両方のバージョンは同じ意味です。qstr または None にできるパラメータであり、デフォルトでは None です。

それでは、楽しいことに進みましょう。🎉

q パラメータの AnnotatedQuery を追加します

これで、より多くの情報(この場合は追加の検証)を追加できる Annotated ができました。Annotated 内に Query を追加し、パラメータ max_length50 に設定します。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(max_length=50)] = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


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

デフォルト値は依然として None であるため、パラメータは依然としてオプションです。

しかし、Annotated 内に Query(max_length=50) を指定することで、FastAPI に対して、この値に追加の検証、つまり最大 50 文字にすることを指示しています。😎

ヒント

ここでは、クエリパラメータであるため、Query() を使用しています。後で、Query() と同じ引数を受け入れる Path()Body()Header()Cookie() なども紹介します。

FastAPI はこれから次のことを行います

  • データが最大長 50 文字であることを確認して、データを**検証**します
  • データが無効な場合、クライアントに**明確なエラー**を表示します
  • OpenAPI スキーマの*パス操作*でパラメータを**文書化**します(そのため、**自動ドキュメント UI** に表示されます)

代替(古い):デフォルト値としての Query

以前のバージョンの FastAPI(0.95.0 より前)では、Annotated に入れる代わりに、パラメータのデフォルト値として Query を使用する必要がありました。この方法を使用しているコードを見かける可能性が高いため、説明します。

ヒント

新しいコードと可能な限り、上記のように Annotated を使用してください。複数の利点(以下で説明)があり、欠点はありません。🍰

これは、関数パラメータのデフォルト値として Query() を使用し、パラメータ max_length を 50 に設定する方法です。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: str | None = Query(default=None, max_length=50)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


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

この場合(Annotated を使用しない場合)、関数のデフォルト値 NoneQuery() に置き換える必要があるため、パラメータ Query(default=None) でデフォルト値を設定する必要があります。これは、デフォルト値を定義するのと同じ目的を果たします(少なくとも FastAPI では)。

つまり

q: Union[str, None] = Query(default=None)

... は、パラメータをオプションにし、デフォルト値を None にします。これは、次の場合と同じです。

q: Union[str, None] = None

そして、Python 3.10 以降では

q: str | None = Query(default=None)

... は、パラメータをオプションにし、デフォルト値を None にします。これは、次の場合と同じです。

q: str | None = None

ただし、Query バージョンでは、クエリパラメータであることが明示的に宣言されます。

情報

パラメータをオプションにするための最も重要な部分は、次の部分です。

= None

または

= Query(default=None)

これは、None をデフォルト値として使用するため、パラメータは**必須ではなくなり**ます。

Union[str, None] 部分を使用すると、エディターがより優れたサポートを提供できますが、FastAPI にこのパラメータが必須ではないことを伝えるものではありません。

次に、Query にさらにパラメータを渡すことができます。この場合は、文字列に適用される max_length パラメータです。

q: Union[str, None] = Query(default=None, max_length=50)

これにより、データが検証され、データが無効な場合は明確なエラーが表示され、OpenAPI スキーマの*パス操作*でパラメータが文書化されます。

デフォルト値としての Query または Annotated 内の Query

Annotated 内で Query を使用する場合、Querydefault パラメータは使用できないことに注意してください。

代わりに、関数パラメータの実際のデフォルト値を使用してください。そうしないと、一貫性がなくなります。

たとえば、これは許可されていません

q: Annotated[str, Query(default="rick")] = "morty"

... デフォルト値が "rick" なのか "morty" なのかが明確でないためです。

そのため、(できれば)次のように使用します。

q: Annotated[str, Query()] = "rick"

... または、古いコードベースでは次のようになります。

q: str = Query(default="rick")

Annotated の利点

関数パラメータのデフォルト値の代わりに **Annotated を使用することをお勧めします**。複数の理由から、**優れてい**ます。🤓

**関数パラメータ**の**デフォルト**値は**実際のデフォルト**値です。これは、一般的に Python ではより直感的です。😌

FastAPI なしで**他の場所**で同じ関数を**呼び出す**ことができ、**期待どおりに動作**します。**必須**パラメータ(デフォルト値なし)がある場合、**エディター**はエラーでそれを知らせます。必須パラメータを渡さずに実行すると、**Python**もエラーを報告します。

Annotated を使用せず、代わりに **(古い)デフォルト値スタイル**を使用する場合、FastAPI なしで**他の場所**でその関数を呼び出すと、正しく動作するために関数に引数を渡すことを**覚えておく**必要があります。そうしないと、値が期待どおりになりません(たとえば、str ではなく QueryInfo など)。エディターはエラーを報告せず、Python はその関数を実行してもエラーを報告しません。操作が内部でエラーになった場合にのみエラーが報告されます。

Annotated には複数のメタデータ注釈を含めることができるため、Typer などの他のツールでも同じ関数を使用できるようになりました。🚀

検証を追加する

パラメータ min_length を追加することもできます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[str | None, Query(min_length=3, max_length=50)] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[Union[str, None], Query(min_length=3, max_length=50)] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


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

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


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

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


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

正規表現を追加する

パラメータが一致する必要がある正規表現 pattern を定義できます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        str | None, Query(min_length=3, max_length=50, pattern="^fixedquery$")
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: str | None = Query(
        default=None, min_length=3, max_length=50, pattern="^fixedquery$"
    ),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(
        default=None, min_length=3, max_length=50, pattern="^fixedquery$"
    ),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

この特定の正規表現パターンは、受信したパラメータ値が次の条件を満たしていることを確認します。

  • ^:次の文字で始まり、前に文字がありません。
  • fixedquery:正確な値 fixedquery です。
  • $:そこで終わり、fixedquery の後に文字がありません。

これらの**「正規表現」**の概念がわからない場合は、心配しないでください。多くの人にとって難しいトピックです。まだ正規表現を必要とせずに多くのことを行うことができます。

しかし、必要なときにそれらを学習すれば、**FastAPI** で直接使用できることがわかります。

Pydantic v1 の regexpattern の代わりに)

Pydantic バージョン 2 以前と FastAPI 0.100.0 以前では、パラメータは pattern ではなく regex と呼ばれていましたが、現在は非推奨です。

まだそれを使用しているコードを見かけるかもしれません。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        str | None, Query(min_length=3, max_length=50, regex="^fixedquery$")
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

しかし、これは非推奨であり、新しいパラメータ pattern を使用するように更新する必要があることを知っておいてください。🤓

デフォルト値

もちろん、None 以外のデフォルト値を使用できます。

q クエリパラメータの min_length3 にし、デフォルト値を "fixedquery" にするとします。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = "fixedquery"):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = "fixedquery"):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: str = Query(default="fixedquery", min_length=3)):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

注記

None を含む任意の型のデフォルト値を設定すると、パラメータはオプション(必須ではない)になります。

必須パラメータ

より多くの検証またはメタデータを宣言する必要がない場合は、次のようにデフォルト値を宣言しないことで、q クエリパラメータを必須にすることができます。

q: str

次の代わりに

q: Union[str, None] = None

しかし、今は次のように Query を使用して宣言しています。

q: Annotated[Union[str, None], Query(min_length=3)] = None
q: Union[str, None] = Query(default=None, min_length=3)

そのため、Query を使用しているときに値を必須として宣言する必要がある場合は、デフォルト値を宣言しないだけです。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)]):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


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

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


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

ヒント

この場合、Query() は関数パラメータのデフォルト値として使用されますが、Query()default=None を渡さないことに注意してください。

それでも、おそらく Annotated バージョンを使用する方が良いでしょう。😉

省略記号(...)を使用した必須

値が必須であることを明示的に宣言する別の方法があります。デフォルトをリテラル値 ... に設定できます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str, Query(min_length=3)] = ...):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


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

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


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

情報

以前に ... を見たことがない場合:これは特別な単一の値であり、Python の一部であり、「省略記号」と呼ばれます

Pydantic と FastAPI では、値が必須であることを明示的に宣言するために使用されます。

これにより、**FastAPI** はこのパラメータが必須であることを認識します。

必須、None にすることができます

パラメータが None を受け入れることができるが、それでも必須であることを宣言できます。これにより、値が None であっても、クライアントは値を送信する必要があります。

そのためには、None が有効な型であることを宣言しますが、それでもデフォルトとして ... を使用します。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(min_length=3)] = ...):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(min_length=3)] = ...):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


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

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


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

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


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

ヒント

FastAPI のすべてのデータ検証とシリアル化を強化する Pydantic は、デフォルト値なしで Optional または Union[Something, None] を使用すると特別な動作をします。必須フィールドに関する Pydantic のドキュメントで詳細を読むことができます。

ヒント

ほとんどの場合、何かが必須の場合は、単にデフォルトを省略できるため、通常は ... を使用する必要がないことに注意してください。

クエリパラメータリスト/複数値

Query でクエリパラメータを明示的に定義すると、値のリストを受け取るか、言い換えれば、複数の値を受け取ると宣言することもできます。

たとえば、URL に複数回出現できるクエリパラメータ q を宣言するには、次のように記述します。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[list[str] | None, Query()] = None):
    query_items = {"q": q}
    return query_items
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[Union[list[str], None], Query()] = None):
    query_items = {"q": q}
    return query_items
from typing import List, Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[Union[List[str], None], Query()] = None):
    query_items = {"q": q}
    return query_items

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: list[str] | None = Query(default=None)):
    query_items = {"q": q}
    return query_items

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Union[list[str], None] = Query(default=None)):
    query_items = {"q": q}
    return query_items

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import List, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Union[List[str], None] = Query(default=None)):
    query_items = {"q": q}
    return query_items

次に、次のような URL を使用すると、

http://localhost:8000/items/?q=foo&q=bar

*パス操作関数*内の Python list で、*関数パラメータ* q に、複数の q *クエリパラメータ*の値(foobar)を受け取ります。

そのため、その URL への応答は次のようになります。

{
  "q": [
    "foo",
    "bar"
  ]
}

ヒント

上記の例のように、list 型のクエリパラメータを宣言するには、明示的に Query を使用する必要があります。そうしないと、リクエスト本文として解釈されます。

インタラクティブ API ドキュメントはそれに応じて更新され、複数の値を許可します。

デフォルト値を持つクエリパラメータリスト/複数値

また、値が提供されない場合に備えて、デフォルトのlistを定義することもできます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[list[str], Query()] = ["foo", "bar"]):
    query_items = {"q": q}
    return query_items
from typing import List

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[List[str], Query()] = ["foo", "bar"]):
    query_items = {"q": q}
    return query_items

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: list[str] = Query(default=["foo", "bar"])):
    query_items = {"q": q}
    return query_items

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import List

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: List[str] = Query(default=["foo", "bar"])):
    query_items = {"q": q}
    return query_items

もしあなたが

http://localhost:8000/items/

にアクセスした場合、qのデフォルトは["foo", "bar"]となり、レスポンスは

{
  "q": [
    "foo",
    "bar"
  ]
}

listのみを使用する

List[str](またはPython 3.9+ではlist[str])の代わりに、直接listを使用することもできます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[list, Query()] = []):
    query_items = {"q": q}
    return query_items
from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[list, Query()] = []):
    query_items = {"q": q}
    return query_items

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: list = Query(default=[])):
    query_items = {"q": q}
    return query_items

注記

この場合、FastAPIはリストの内容をチェックしないことに注意してください。

例えば、List[int]はリストの内容が整数であることをチェック(そしてドキュメント化)しますが、listだけではチェックしません。

より多くのメタデータを宣言する

パラメータに関するより多くの情報を追加できます。

その情報は、生成されたOpenAPIに含まれ、ドキュメントユーザーインターフェースおよび外部ツールによって使用されます。

注記

ツールによってOpenAPIのサポートレベルが異なる場合があることに注意してください。

一部のツールでは、宣言されたすべての追加情報がまだ表示されない場合がありますが、ほとんどの場合、欠落している機能はすでに開発が計画されています。

titleを追加できます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[str | None, Query(title="Query string", min_length=3)] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[Union[str, None], Query(title="Query string", min_length=3)] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[Union[str, None], Query(title="Query string", min_length=3)] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: str | None = Query(default=None, title="Query string", min_length=3),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(default=None, title="Query string", min_length=3),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

そしてdescriptionを追加できます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        str | None,
        Query(
            title="Query string",
            description="Query string for the items to search in the database that have a good match",
            min_length=3,
        ),
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        Union[str, None],
        Query(
            title="Query string",
            description="Query string for the items to search in the database that have a good match",
            min_length=3,
        ),
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        Union[str, None],
        Query(
            title="Query string",
            description="Query string for the items to search in the database that have a good match",
            min_length=3,
        ),
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: str | None = Query(
        default=None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
    ),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(
        default=None,
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
    ),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

エイリアスパラメータ

パラメータをitem-queryにしたいとします。

例えば

http://127.0.0.1:8000/items/?item-query=foobaritems

のように。しかし、item-queryは有効なPython変数名ではありません。

最も近いのはitem_queryです。

しかし、それでも正確にitem-queryである必要があります...

その場合、aliasを宣言できます。このエイリアスは、パラメータ値を見つけるために使用されます。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[str | None, Query(alias="item-query")] = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(alias="item-query")] = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(q: Annotated[Union[str, None], Query(alias="item-query")] = None):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: str | None = Query(default=None, alias="item-query")):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

パラメータを非推奨にする

このパラメータがもう気に入らないとしましょう。

クライアントが使用しているため、しばらくはそのままにしておく必要がありますが、ドキュメントには非推奨として明確に表示したいと考えています。

その場合、Queryにパラメータdeprecated=Trueを渡します。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        str | None,
        Query(
            alias="item-query",
            title="Query string",
            description="Query string for the items to search in the database that have a good match",
            min_length=3,
            max_length=50,
            pattern="^fixedquery$",
            deprecated=True,
        ),
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        Union[str, None],
        Query(
            alias="item-query",
            title="Query string",
            description="Query string for the items to search in the database that have a good match",
            min_length=3,
            max_length=50,
            pattern="^fixedquery$",
            deprecated=True,
        ),
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Annotated[
        Union[str, None],
        Query(
            alias="item-query",
            title="Query string",
            description="Query string for the items to search in the database that have a good match",
            min_length=3,
            max_length=50,
            pattern="^fixedquery$",
            deprecated=True,
        ),
    ] = None,
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: str | None = Query(
        default=None,
        alias="item-query",
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
        max_length=50,
        pattern="^fixedquery$",
        deprecated=True,
    ),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    q: Union[str, None] = Query(
        default=None,
        alias="item-query",
        title="Query string",
        description="Query string for the items to search in the database that have a good match",
        min_length=3,
        max_length=50,
        pattern="^fixedquery$",
        deprecated=True,
    ),
):
    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
    if q:
        results.update({"q": q})
    return results

ドキュメントにはこのように表示されます。

OpenAPIからパラメータを除外する

生成されたOpenAPIスキーマ(および自動ドキュメントシステム)からクエリパラメータを除外するには、Queryinclude_in_schemaパラメータをFalseに設定します。

from typing import Annotated

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    hidden_query: Annotated[str | None, Query(include_in_schema=False)] = None,
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    else:
        return {"hidden_query": "Not found"}
from typing import Annotated, Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    hidden_query: Annotated[Union[str, None], Query(include_in_schema=False)] = None,
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    else:
        return {"hidden_query": "Not found"}
from typing import Union

from fastapi import FastAPI, Query
from typing_extensions import Annotated

app = FastAPI()


@app.get("/items/")
async def read_items(
    hidden_query: Annotated[Union[str, None], Query(include_in_schema=False)] = None,
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    else:
        return {"hidden_query": "Not found"}

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    hidden_query: str | None = Query(default=None, include_in_schema=False),
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    else:
        return {"hidden_query": "Not found"}

ヒント

可能な場合は、Annotated バージョンを使用することをお勧めします。

from typing import Union

from fastapi import FastAPI, Query

app = FastAPI()


@app.get("/items/")
async def read_items(
    hidden_query: Union[str, None] = Query(default=None, include_in_schema=False),
):
    if hidden_query:
        return {"hidden_query": hidden_query}
    else:
        return {"hidden_query": "Not found"}

まとめ

パラメータに追加の検証とメタデータを宣言できます。

一般的な検証とメタデータ

  • alias
  • title
  • description
  • deprecated

文字列に固有の検証

  • min_length
  • max_length
  • pattern

これらの例では、str値の検証を宣言する方法を説明しました。

数値などの他の型の検証を宣言する方法については、次の章を参照してください。