参数化的dependencies

我们看到的所有dependencies都是一个固定的函数或类
但在某些情况下,您可能希望能够设置依赖项的参数,无需声明许多不同的函数或类。

假设我们需要一个依赖项来检查查询参数q是否包含一些固定内容。
但我们希望能够参数化固定内容

一个callable实例

在Python中,有一种方法可以使类的实例成为“callable”。
不是类本身(已经是可调用的),而是该类的实例。
为此,我们声明一个call方法调用:

  1. from fastapi import Depends, FastAPI
  2. app = FastAPI()
  3. class FixedContentQueryChecker:
  4. def __init__(self, fixed_content: str):
  5. self.fixed_content = fixed_content
  6. def __call__(self, q: str = ""):
  7. if q:
  8. return self.fixed_content in q
  9. return False
  10. checker = FixedContentQueryChecker("bar")
  11. @app.get("/query-checker/")
  12. async def read_query_check(fixed_content_included: bool = Depends(checker)):
  13. return {"fixed_content_in_query": fixed_content_included}

在这个例子中,FastAPI将使用这个__call__ 来检查额外参数和子依赖项,这就是稍后在路径操作函数中将要调用的函数,以将值传递给参数。

参数化的实例

现在,我们使用__init__ 去声明实例参数,我们可以使用这些参数来”参数化”依赖关系:

  1. from fastapi import Depends, FastAPI
  2. app = FastAPI()
  3. class FixedContentQueryChecker:
  4. def __init__(self, fixed_content: str):
  5. self.fixed_content = fixed_content
  6. def __call__(self, q: str = ""):
  7. if q:
  8. return self.fixed_content in q
  9. return False
  10. checker = FixedContentQueryChecker("bar")
  11. @app.get("/query-checker/")
  12. async def read_query_check(fixed_content_included: bool = Depends(checker)):
  13. return {"fixed_content_in_query": fixed_content_included}

在这个例子中,FastAPI永远不会触及或关心init,我们将在代码中直接使用它

创建一个实例

我们可以通过这个类创建一个实例:

  1. from fastapi import Depends, FastAPI
  2. app = FastAPI()
  3. class FixedContentQueryChecker:
  4. def __init__(self, fixed_content: str):
  5. self.fixed_content = fixed_content
  6. def __call__(self, q: str = ""):
  7. if q:
  8. return self.fixed_content in q
  9. return False
  10. checker = FixedContentQueryChecker("bar")
  11. @app.get("/query-checker/")
  12. async def read_query_check(fixed_content_included: bool = Depends(checker)):
  13. return {"fixed_content_in_query": fixed_content_included}

这样,我们就可以参数化我们的依赖,现在有”bar”在里面作为checker.fixed_content的属性

将实例用作依赖项

然后,我们能够在Depends(checker)中使用checker,代替Depends(FixedContentQueryChecker),因为依赖checker是一个实例,不是类本身。

在解决依赖关系时,FastAPI将调用checker

  1. checker(q="somequery")

…并将作为路径操作函数中依赖项的值返回的任何内容作为参数fixed_content_included传递:

  1. from fastapi import Depends, FastAPI
  2. app = FastAPI()
  3. class FixedContentQueryChecker:
  4. def __init__(self, fixed_content: str):
  5. self.fixed_content = fixed_content
  6. def __call__(self, q: str = ""):
  7. if q:
  8. return self.fixed_content in q
  9. return False
  10. checker = FixedContentQueryChecker("bar")
  11. @app.get("/query-checker/")
  12. async def read_query_check(fixed_content_included: bool = Depends(checker)):
  13. return {"fixed_content_in_query": fixed_content_included}

:::info Tip
这一切可能显得像预谋好的。而且讲的还不是很清楚它是如何有用的。
这些例子是故意简单的,但显示了这一切是如何工作的。
在关于安全的章节中,有一些实用函数也是以这种方式实现的。
如果你了解了这些,你就已经知道下面那些安全的实用工具是如何工作的了。 :::