FastAPI Swagger 文档显示不正确的响应状态?

FastAPI Swagger Documentation Showing Incorrect Response Status?

提问人:Della 提问时间:9/21/2023 最后编辑:Della 更新时间:9/21/2023 访问量:196

问:

通过 FastAPI(下面的代码片段)实现的路由工作正常。

@app.post(path='/user/create/')
async def create_user(response: Response,
                      email: str = Form(),
                      password: str = Form()) -> None:
    """
    Create a new user with this route.
    Possible responses:
    201: New User Created
    400: Bad email id supplied.
    409: User already signed up, hence causing conflict with existing id.
    """
    logging.info(msg=f'New user sign up request from {email}.')
    try:
        user: WebUser = WebUser(email=email, password=password)
        # Either 409 or 201
        response.status_code = [CONFLICT, CREATED][await user.create_new()]
    except ValidationError:
        logging.error(
            msg=f'User creation for {email} failed because of bad request.')
        response.status_code = BAD_REQUEST  # 400

但是 FastAPI swagger 文档显示了不正确的(实际上是完全随机的)响应。这是屏幕截图。

enter image description here

因此,它没有显示 409 和 400,而是以某种方式显示 422 作为可能的响应。此外,成功的响应实际上是 201。

那么,FastAPI 是如何在幕后形成这些文档的,我是否做错了什么来误导它呢?还是 FastAPI 中的错误?

python fastapi httpresponse asgi

评论

0赞 Chris 9/21/2023
回答了你的问题吗?

答:

2赞 larsks 9/21/2023 #1

这记录在文档的 OpenAPI的其他状态代码和附加响应部分中。

如果我们像这样重写你的代码:

import random
import logging
import pydantic
from fastapi import FastAPI, Response, Form
from fastapi.responses import JSONResponse

app = FastAPI()


class BaseModel(pydantic.BaseModel):
    pass


class Message(BaseModel):
    message: str


class WebUser(BaseModel):
    email: str
    password: str


def user_create_new(user: WebUser):
    if random.randint(0, 100) > 50:
        pass
    else:
        raise ValueError()


@app.post(
    path="/user/create",
    responses={400: {"model": Message}, 409: {"model": Message}},
)
async def create_user(
    response: Response, email: str = Form(), password: str = Form()
) -> None:
    logging.info(msg=f"New user sign up request from {email}.")
    user: WebUser = WebUser(email=email, password=password)
    try:
        user_create_new(user)
        return Message(message=f"Created user {email}")
    except ValueError:
        return JSONResponse(
            status_code=400, content=Message(message="Unable to create user").dict()
        )

然后 http://localhost/openapi 得到我们:

enter image description here

评论

0赞 Della 9/21/2023
非常感谢您的分享。但它并没有告诉我为什么我的代码会生成明显不正确和误导性的文档。是否必须提供这些高级响应格式才能获得正确的文档?或者,我可以从我的首页中删除这些详细信息吗?
0赞 Della 9/21/2023
此外,甚至您的实现也显示了 ,这实际上不是响应模型的一部分。FastAPI 是否将该添加为默认值?有什么方法可以从我的所有路线中删除那个?422
0赞 larsks 9/21/2023
根据文档,这是记录其他响应代码的方法,以便它们将显示在生成的 openapi 规范中。 W/r/t 到 422 响应,这是响应模型的一部分——这是 FastAPI 在 pydantic 验证失败时将返回的内容,因此从 FastAPI 的角度来看,每个方法都可以返回 422 状态。