使用Pydantic模型(FastAPI)在Swagger文档中设置查询参数的描述

18

这篇文章是之前问题的延续。

我已经添加了一个模型来获取pydantic模型的查询参数。

class QueryParams(BaseModel):
    x: str = Field(description="query x")
    y: str = Field(description="query y")
    z: str = Field(description="query z")


@app.get("/test-query-url/{test_id}")
async def get_by_query(test_id: int, query_params: QueryParams = Depends()):
    print(test_id)
    print(query_params.dict(by_alias=True))
    return True

它按预期工作,但模型中添加的描述未在Swagger UI中反映出来。

enter image description here

但是,如果同一模型用于请求正文,则Swagger会显示描述。

enter image description here

我是否错过了任何东西,以便在Swagger UI中获取QueryParams(模型)的描述?


2
我不同意Arakkabal的答案,我能够做到这一点,而且OpenAPI规范和Swagger也允许这样做,查询参数有一个描述字段参见。这意味着你应该这样做,因为FastAPI基于OpenAPI规范。我稍后会再次查看这个问题。 - Yagiz Degirmenci
谢谢,如果您发现任何问题,请告诉我。 - karsas
4个回答

18

Pydantic models无法实现此功能。

要获得所需的结果,可以使用自定义依赖类(或函数)而不是Pydantic模型。

from fastapi import Depends, FastAPI, Query

app = FastAPI()


class CustomQueryParams:
    def __init__(
        self,
        foo: str = Query(..., description="Cool Description for foo"),
        bar: str = Query(..., description="Cool Description for bar"),
    ):
        self.foo = foo
        self.bar = bar


@app.get("/test-query/")
async def get_by_query(params: CustomQueryParams = Depends()):
    return params
因此,你将会得到这份文档:

screenshot


参考资料

  1. 在 FastAPI 中验证 GET 参数--(FastAPI GitHub) 看起来似乎较少关注扩展 Pydantic 模型以验证 GET 参数。
  2. 类作为依赖项--(FastAPI 文档)

1
这样做可以。但是我想要一个 Pydantic 模型。 - karsas
你不能使用Pydantic来实现这个。参考链接 - JPG
不确定为什么要使用Query,它与pydantic Field具有类似的属性。 - karsas
Query(...) 用于生成 OpenAPI 模式。 - JPG

12

这对我很有用


from fastapi import Depends, FastAPI, Query

@app.post("/route")
def some_api(
        self,
        query_param_1: float = Query(None, description="description goes here", ),
        query_param_2: float = Query(None, description="Param 2 does xyz"),
):
    
return "hello world"



3
接受的答案提到了使用FastAPI自定义依赖项,可以使用类作为依赖项来批量定义查询参数。虽然这种方法很好用,但我认为在这种情况下使用数据类会更好,因为它可以自动生成__init__,减少代码重复。 普通类作为依赖项
class QueryParams:
    def __init__(self, 
    x:  Query(
            None, description="Arg1", example=10),
    y:  Query(
            None, description="Arg2", example=20)
    ):
        self.x = x
        self.y = y

对于较少的查询参数,这种方法可能很好用,但如果参数数量像我其中一个API端点那样很大,这种方式很快变得繁琐。

使用数据类作为依赖项

@dataclass
class QueryParams:
    x:  Query(None, description="Arg1", example=10)
    y:  Query(None, description="Arg2", example=20)
此外,如果您需要更复杂的功能,则还可以使用数据类的附加好处。

像基于Pydantic的模型一样,这不适用于_path_参数;例如:stage: tp.Literal['add','delete'] = fa.Path(description='this is the stage') - undefined

1
这是一个简单的工作示例,演示了如何将Pydantic与FastAPI结合使用来处理查询参数。
from enum import Enum
from typing import List
from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel, Field

ROUTER = APIRouter()

class MyEnum(str, Enum):
    OPTION_ONE = "option_one"
    OPTION_TWO = "option_two"

class QueryParams(BaseModel):
    foo: List[str] = Field(Query(
        default_factory=list,
        description="List of foo parameters",
    ))
    bar: MyEnum = Field(Query(
        default=MyEnum.OPTION_ONE,
        description="Enum for bar parameters",
    ))

@ROUTER.get("/endpoint")
async def endpoint(params: QueryParams = Depends()):
    foobar = "something"  # Dummy response
    return {"foobar": foobar}

生成的Swagger文档: Swagger文档

看起来这个解决方案也展示了如何做到这一点。


事实上,将Query函数调用中的Query包裹起来并不完全起作用。pydantic.Field实际上有自己的defaultdescriptionexample参数,它们的工作方式与fastapi.Query完全相同。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,