【问题标题】:What does Depends with no parameter do?没有参数的 Depends 有什么作用?
【发布时间】:2020-11-29 11:56:26
【问题描述】:

我正在尝试使用 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()
    ):

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

@app.post('/login')
def login(user: User, Authorize: AuthJWT = Depends()):

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

【问题讨论】:

  • 你从哪里得到取决于?它的文档对它所期望的论点有什么看法?

标签: python-3.x fastapi


【解决方案1】:

不带参数的Depends() 只是shortcutclasses as dependencies

你看我们这里有一些代码重复,写了两次CommonQueryParams

commons: CommonQueryParams = Depends(CommonQueryParams)

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

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

而不是写:

commons: CommonQueryParams = Depends(CommonQueryParams)

...你写:

commons: CommonQueryParams = Depends()

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

【讨论】:

  • 在投票后指出我的答案中的错误会很棒
  • 我认为这是对所提问题的正确答案
【解决方案2】:

在这两种情况下,我都在方法参数中看到了 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

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

有什么区别?

由于 FastAPI 基于 OpenAPI 规范,我们可以开始发现与自动生成的 Swagger 文档的不同之处。

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

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

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

其实就是这样,它期望那里有一个Callable

但是当您使用带有DependsPydantic 模型 时,它实际上会为init __init__ 函数中的参数创建一个查询参数。

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

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

Depends变成这个。


class Location(BaseModel):
    def __init__(self, city: str, country: str, state: str) -> None:
        ...

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

"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"
    }
]

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

"requestBody": {
    "content":{
        "application/json":{
            "schema":{
                "$ref":"#/components/schemas/Location"
            }
        }
    },
    "required":true
}

结论

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

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

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

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

【讨论】:

    猜你喜欢
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    相关资源
    最近更新 更多