不带参数的 Depends 有什么作用?

cod*_*ddy 12 python-3.x fastapi

我正在尝试使用 fastapi 来实现 JWT。目前正在查看以下库 fastapi-users FastAPI JWT Auth

在这两种情况下,我都在方法参数中看到 Depends() 。当参数中没有任何内容时,Depends 会做什么?

https://github.com/frankie567/fastapi-users/blob/master/fastapi_users/router/auth.py

@router.post("/login")
    async def login(
        response: Response, credentials: OAuth2PasswordRequestForm = Depends()
    ):
Run Code Online (Sandbox Code Playgroud)

https://indominusbyte.github.io/fastapi-jwt-auth/usage/basic/

@app.post('/login')
def login(user: User, Authorize: AuthJWT = Depends()):
Run Code Online (Sandbox Code Playgroud)

我不明白参数内有一个函数,但是你能教我当 Depends 没有参数时它会做什么吗?

ale*_*ame 13

Depends()without argument 只是类作为依赖项的快捷方式

您会看到我们在这里有一些代码重复,写了CommonQueryParams两次:

commons: CommonQueryParams = Depends(CommonQueryParams)
Run Code Online (Sandbox Code Playgroud)

FastAPI 为这些情况提供了一种快捷方式,其中依赖项具体是一个类,FastAPI 将“调用”该类来创建该类本身的实例。

对于这些特定情况,您可以执行以下操作:

而不是写:

commons: CommonQueryParams = Depends(CommonQueryParams)
Run Code Online (Sandbox Code Playgroud)

...你写:

commons: CommonQueryParams = Depends()
Run Code Online (Sandbox Code Playgroud)

您将 声明为dependency 参数 的类型,并使用Depends()该函数参数的“默认”值(= 之后的值),而 中不带任何参数Depends(),而不必在 中再次编写完整的类Depends(CommonQueryParams)


Yag*_*nci 7

在这两种情况下,我都在方法参数中看到 Depends() 。当参数中没有任何内容时,Depends 会做什么?

这是一个很好的问题。

假设您有以下代码。

from fastapi import FastAPI, Depends
from pydantic import BaseModel
from typing import Optional


class Location(BaseModel):
    city: str
    country: str
    state: str


app = FastAPI()


@app.post("/withoutdepends")
async def with_depends(location: Location):
    return location


@app.post("/withdepends")
async def with_depends(location: Location = Depends()):
    return lcoation
Run Code Online (Sandbox Code Playgroud)

我们Location在两个不同的端点上有相同的模型,一个Depends端点不使用另一个端点。

有什么不同?

由于 FastAPI 基于 OpenAPI 规范,我们可以开始从自动生成的 Swagger 文档中发现差异。

没有 Depends,它需要一个请求正文。

这是Depends,它期望它们作为查询参数。

这有什么用处以及它是如何工作的?

事实上,就是这样,它期待着Callable那里。

但是,当您将Pydantic 模型与 一起使用时Depends,它实际上会为 init__init__函数内的参数创建一个查询参数。

例如,这是我们上面使用的模型。

class Location(BaseModel):
    city: str
    country: str
    state: str
Run Code Online (Sandbox Code Playgroud)

就变成这样了Depends


class Location(BaseModel):
    def __init__(self, city: str, country: str, state: str) -> None:
        ...
Run Code Online (Sandbox Code Playgroud)

然后它们将成为查询参数。这是端点的 OpenAPI 架构/withdepends

"parameters": [
    {
        "required":true,
        "schema":{
            "title":"City",
            "type":"string"
        },
        "name":"city",
        "in":"query"
    },
    {
        "required":true,
        "schema":{
            "title":"Country",
            "type":"string"
        },
        "name":"country",
        "in":"query"
    },
    {
        "required":true,
        "schema":{
            "title":"State",
            "type":"string"
        },
        "name":"state",
        "in":"query"
    }
]
Run Code Online (Sandbox Code Playgroud)

这是它为端点创建的 OpenAPI 架构/withoutdepends

"requestBody": {
    "content":{
        "application/json":{
            "schema":{
                "$ref":"#/components/schemas/Location"
            }
        }
    },
    "required":true
}
Run Code Online (Sandbox Code Playgroud)

结论

您可以使用相同的模型创建查询参数,而不是请求正文。

Pydantic 模型对于具有 +5 个参数的情况非常有用。但它默认需要一个请求正文。OpenAPI 规范不允许在GET操作中使用请求正文。正如规范中所说。

GET、DELETE 和 HEAD 不再允许具有请求正文,因为它没有按照 RFC 7231 定义的语义。

因此,通过使用,Depends您可以使用相同的模型为GET端点创建查询参数。