パスパラメーターと数値の検証¶
Queryを使ってクエリパラメーターに追加の検証やメタデータを宣言できるのと同じように、Pathを使ってパスパラメーターにも同じ種類の検証やメタデータを宣言できます。
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
Note
パスパラメーターはパスの一部である必要があるため、常に必須です。Noneで宣言したり、デフォルト値を設定したりしても、何も影響せず、常に必須のままです。
必要に応じてパラメーターを並べ替える¶
ヒント
Annotatedを使用する場合、これはそれほど重要ではないか、必要ないかもしれません。
クエリパラメーターqを必須のstrとして宣言したいとします。
そして、そのパラメーターについて他には何も宣言する必要がないため、Queryを使用する必要は実際にはありません。
しかし、item_idパスパラメーターにはPathを使用する必要があります。そして、何らかの理由でAnnotatedを使用したくないとします。
Pythonは、「デフォルト」を持つ値を「デフォルト」を持たない値の前に置くと不平を言います。
しかし、それらを並べ替えて、デフォルトを持たない値(クエリパラメーターq)を最初にすることができます。
FastAPIにとっては問題ありません。パラメーターをその名前、型、およびデフォルト宣言(Query、Pathなど)で検出するため、順序は関係ありません。
したがって、関数を次のように宣言できます。
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「以上」の整数である必要があります。
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:greaterthan (より大きい)le:less than orequal (以下)
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:greaterthan (より大きい)ge:greater than orequal (以上)lt:lessthan (より小さい)le:less than orequal (以下)
情報
Query、Path、および後で説明するその他のクラスは、共通のParamクラスのサブクラスです。
それらはすべて、見てきた追加の検証とメタデータのための同じパラメーターを共有します。
技術的な詳細
fastapiからQuery、Pathなどをインポートするとき、それらは実際には関数です。
呼び出されると、同じ名前のクラスのインスタンスを返します。
したがって、関数であるQueryをインポートし、それを呼び出すと、同じくQueryという名前のクラスのインスタンスが返されます。
これらの関数は、(クラスを直接使用するのではなく)エディターがその型に関するエラーをマークしないように存在します。
これにより、それらのエラーを無視するためのカスタム設定を追加することなく、通常のエディターとコーディングツールを使用できます。