高度な依存関係¶
パラメーター化された依存関係¶
これまでに見てきたすべての依存関係は、固定された関数またはクラスです。
しかし、多くの異なる関数やクラスを宣言しなくても、依存関係にパラメータを設定したい場合があるかもしれません。
クエリパラメータq
がいくつかの固定されたコンテンツを含むかどうかをチェックする依存関係があると想像してみましょう。
しかし、その固定されたコンテンツをパラメーター化できるようにしたいと考えています。
「呼び出し可能」なインスタンス¶
Pythonでは、クラスのインスタンスを「呼び出し可能」にする方法があります。
(既に呼び出し可能である)クラス自体ではなく、そのクラスのインスタンスです。
そのためには、__call__
メソッドを宣言します。
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
from fastapi import Depends, FastAPI
from typing_extensions import Annotated
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
ヒント
可能であれば、Annotated
バージョンを使用することをお勧めします。
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: bool = Depends(checker)):
return {"fixed_content_in_query": fixed_content_included}
この場合、この__call__
は、FastAPIが追加のパラメータとサブ依存関係をチェックするために使用し、後で*パスオペレーション関数*のパラメータに値を渡すために呼び出されるものです。
インスタンスをパラメーター化する¶
そして今、私たちは__init__
を使用して、依存関係を「パラメーター化」するために使用できるインスタンスのパラメータを宣言できます。
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
from fastapi import Depends, FastAPI
from typing_extensions import Annotated
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
ヒント
可能であれば、Annotated
バージョンを使用することをお勧めします。
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: bool = Depends(checker)):
return {"fixed_content_in_query": fixed_content_included}
この場合、FastAPIは__init__
に一切触れたり気にもしません。私たちはコードの中で直接それを使用します。
インスタンスを作成する¶
このクラスのインスタンスを次のように作成できます。
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
from fastapi import Depends, FastAPI
from typing_extensions import Annotated
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
ヒント
可能であれば、Annotated
バージョンを使用することをお勧めします。
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: bool = Depends(checker)):
return {"fixed_content_in_query": fixed_content_included}
そして、そのようにして、依存関係を「パラメーター化」することができます。これは、checker.fixed_content
属性として、内部に"bar"
を持つようになりました。
インスタンスを依存関係として使用する¶
その後、依存関係はインスタンスchecker
であり、クラス自体ではないため、Depends(FixedContentQueryChecker)
ではなく、Depends(checker)
でこのchecker
を使用できます。
そして、依存関係を解決するとき、FastAPIはこのchecker
を次のように呼び出します。
checker(q="somequery")
...そして、それを*パスオペレーション関数*のパラメータfixed_content_included
の値として渡します。
from typing import Annotated
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
from fastapi import Depends, FastAPI
from typing_extensions import Annotated
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
return {"fixed_content_in_query": fixed_content_included}
ヒント
可能であれば、Annotated
バージョンを使用することをお勧めします。
from fastapi import Depends, FastAPI
app = FastAPI()
class FixedContentQueryChecker:
def __init__(self, fixed_content: str):
self.fixed_content = fixed_content
def __call__(self, q: str = ""):
if q:
return self.fixed_content in q
return False
checker = FixedContentQueryChecker("bar")
@app.get("/query-checker/")
async def read_query_check(fixed_content_included: bool = Depends(checker)):
return {"fixed_content_in_query": fixed_content_included}
ヒント
これらはすべて、ややこしく見えるかもしれません。そして、それがどのように役に立つのかはまだ明確ではないかもしれません。
これらの例は意図的に単純化されていますが、すべてがどのように機能するかを示しています。
セキュリティに関する章では、同じ方法で実装されたユーティリティ関数があります。
これらすべてを理解していれば、セキュリティのためのそれらのユーティリティツールが内部でどのように機能するのかが既に分かります。