パスパラメーターと数値の検証¶
クエリパラメーターで Query
を使用して追加の検証とメタデータを宣言できるのと同様に、パスパラメーターで Path
を使用して同じ種類の検証とメタデータを宣言できます。
パスのインポート¶
まず、fastapi
から Path
をインポートし、Annotated
をインポートします。
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")],
q: Annotated[str | None, Query(alias="item-query")] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from typing import Annotated, Union
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")],
q: Annotated[Union[str, None], Query(alias="item-query")] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Path, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")],
q: Annotated[Union[str, None], Query(alias="item-query")] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: str | None = Query(default=None, alias="item-query"),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from typing import Union
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: Union[str, None] = Query(default=None, alias="item-query"),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
情報
FastAPI はバージョン 0.95.0 で Annotated
のサポートを追加し(そして推奨し始めました)。
古いバージョンを使用している場合、Annotated
を使用しようとするとエラーが発生します。
Annotated
を使用する前に、FastAPI のバージョンを 0.95.1 以上にアップグレードしてください。
メタデータの宣言¶
Query
と同じパラメーターをすべて宣言できます。
たとえば、パスパラメーター item_id
の title
メタデータ値を宣言するには、次のように入力します。
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")],
q: Annotated[str | None, Query(alias="item-query")] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from typing import Annotated, Union
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")],
q: Annotated[Union[str, None], Query(alias="item-query")] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
from typing import Union
from fastapi import FastAPI, Path, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")],
q: Annotated[Union[str, None], Query(alias="item-query")] = None,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: str | None = Query(default=None, alias="item-query"),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from typing import Union
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: int = Path(title="The ID of the item to get"),
q: Union[str, None] = Query(default=None, alias="item-query"),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
注
パスパラメーターはパスの一部である必要があるため、常に必須です。None
で宣言したり、デフォルト値を設定しても、何も影響はなく、常に必須となります。
必要に応じてパラメーターを並べ替える¶
ヒント
Annotated
を使用する場合は、これはそれほど重要ではないか、必要ありません。
クエリパラメーター q
を必須の str
として宣言したいとします。
そして、そのパラメーターに他に何も宣言する必要がないため、Query
を使用する必要は実際にはありません。
しかし、item_id
パスパラメーターには Path
を使用する必要があります。そして、何らかの理由で Annotated
を使用したくないとします。
デフォルト値を持たない値の前に「デフォルト」を持つ値を置くと、Python は文句を言います。
しかし、それらを並べ替えて、デフォルト値を持たない値(クエリパラメーター q
)を最初に置くことができます。
FastAPI にとっては問題ありません。名前、型、デフォルトの宣言(Query
、Path
など)によってパラメーターを検出するため、順序は気にしません。
したがって、関数を次のように宣言できます。
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(q: str, item_id: int = Path(title="The ID of the item to get")):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from typing import Annotated
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
q: str, item_id: Annotated[int, Path(title="The ID of the item to get")]
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
from fastapi import FastAPI, Path
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
q: str, item_id: Annotated[int, Path(title="The ID of the item to get")]
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ただし、Annotated
を使用する場合、Query()
や Path()
の関数パラメーターのデフォルト値を使用しないため、この問題は発生せず、*
を使用する必要もありません。
from typing import Annotated
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
q: str, item_id: Annotated[int, Path(title="The ID of the item to get")]
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from fastapi import FastAPI, Path
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
q: str, item_id: Annotated[int, Path(title="The ID of the item to get")]
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(q: str, item_id: int = Path(title="The ID of the item to get")):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
必要に応じてパラメーターを並べ替える、裏技¶
ヒント
Annotated
を使用する場合は、これはそれほど重要ではないか、必要ありません。
便利なちょっとした裏技がありますが、頻繁に必要になることはありません。
次のようにしたい場合
Query
もデフォルト値もなしでq
クエリパラメーターを宣言するPath
を使用してパスパラメーターitem_id
を宣言する- それらを異なる順序にする
Annotated
を使用しない
...Python には、それに対する少し特別な構文があります。
関数の最初のパラメーターとして *
を渡します。
Python はその *
で何も行いませんが、それに続くすべてのパラメーターをキーワード引数(キーと値のペア)、別名 kwargs
として呼び出す必要があることを認識します。デフォルト値がない場合でもです。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(*, item_id: int = Path(title="The ID of the item to get"), q: str):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from typing import Annotated
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")], q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
from fastapi import FastAPI, Path
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")], q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
Annotated
を使用するとより良い¶
Annotated
を使用する場合、関数パラメーターのデフォルト値を使用しないため、この問題は発生せず、*
を使用する必要もありません。
from typing import Annotated
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")], q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from fastapi import FastAPI, Path
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get")], q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(*, item_id: int = Path(title="The ID of the item to get"), q: str):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
数値の検証: 以上¶
Query
と Path
(および後で説明するその他のもの)を使用すると、数値の制約を宣言できます。
ここで、ge=1
を指定すると、item_id
は 1
「以上」(g
reater than or e
qual)の整数である必要があります。
from typing import Annotated
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get", ge=1)], q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from fastapi import FastAPI, Path
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get", ge=1)], q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
*, item_id: int = Path(title="The ID of the item to get", ge=1), q: str
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
数値の検証: より大きい、以下¶
同じことが以下にも当てはまります。
gt
:g
reatert
han(より大きい)le
:l
ess than ore
qual(以下)
from typing import Annotated
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get", gt=0, le=1000)],
q: str,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
🤓 その他のバージョンとバリアント
from fastapi import FastAPI, Path
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
item_id: Annotated[int, Path(title="The ID of the item to get", gt=0, le=1000)],
q: str,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
*,
item_id: int = Path(title="The ID of the item to get", gt=0, le=1000),
q: str,
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
return results
数値の検証: 浮動小数点数、より大きい、より小さい¶
数値の検証は float
値にも機能します。
ここで、gt
を宣言でき、単に ge
だけでなくそれが重要になります。たとえば、値が 1
未満であっても、0
より大きいことを要求できます。
したがって、0.5
は有効な値ですが、0.0
や 0
は有効ではありません。
そして、lt
も同様です。
from typing import Annotated
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
*,
item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
q: str,
size: Annotated[float, Query(gt=0, lt=10.5)],
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
if size:
results.update({"size": size})
return results
🤓 その他のバージョンとバリアント
from fastapi import FastAPI, Path, Query
from typing_extensions import Annotated
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
*,
item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
q: str,
size: Annotated[float, Query(gt=0, lt=10.5)],
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
if size:
results.update({"size": size})
return results
ヒント
可能であれば`Annotated`バージョンを使用することをお勧めします。
from fastapi import FastAPI, Path, Query
app = FastAPI()
@app.get("/items/{item_id}")
async def read_items(
*,
item_id: int = Path(title="The ID of the item to get", ge=0, le=1000),
q: str,
size: float = Query(gt=0, lt=10.5),
):
results = {"item_id": item_id}
if q:
results.update({"q": q})
if size:
results.update({"size": size})
return results
まとめ¶
Query
、Path
(およびまだ見ていない他のクラス)を使用すると、クエリパラメーターと文字列の検証と同様の方法でメタデータと文字列の検証を宣言できます。
また、数値の検証も宣言できます。
gt
:g
reatert
han(より大きい)ge
:g
reater than ore
qual(以上)lt
:l
esst
han(より小さい)le
:l
ess than ore
qual(以下)
情報
Query
、Path
、および後で説明する他のクラスは、共通の Param
クラスのサブクラスです。
これらすべては、これまでに見てきた追加の検証とメタデータに同じパラメーターを共有しています。
技術的な詳細
fastapi
から Query
、Path
などをインポートすると、実際には関数です。
呼び出されると、同じ名前のクラスのインスタンスを返します。
したがって、関数である Query
をインポートします。そして、それを呼び出すと、同じく Query
という名前のクラスのインスタンスが返されます。
これらの関数が存在するのは(クラスを直接使用するのではなく)、エディタがそれらの型に関するエラーをマークしないようにするためです。
これにより、これらのエラーを無視するようにカスタム設定を追加することなく、通常のエディタとコーディングツールを使用できます。