处理文件与 Pydantic 模型中定义的表单数据时出现 FastAPI 错误

问题描述 投票:0回答:1

由于某种原因,同时处理

Form
数据和
File
上传会引发错误。

from typing import Annotated

from pydantic import BaseModel, StringConstraints, EmailStr

class RouteBody(BaseModel):
    email: Annotated[EmailStr, StringConstraints(
        max_length = 255
    )]
    password: Annotated[str, StringConstraints(
        max_length = 60
    )]

这强制了路由主体是正确的。超级好看。

from fastapi import UploadFile, File

@some_api_router.post("/some-route")
async def handleRoute(routeBody: RouteBody = Form(), profilePicture: UploadFile = File(...)):
    return {"msg": "Route"}

我使用 SwaggerUI 文档对其进行了测试:

enter image description here

我收到以下错误:

error [{'type': 'model_attributes_type', 'loc': ('body', 'routeBody'), 'msg': 'Input should be a valid dictionary or object to extract fields from', 'input': '{"email":"[email protected]","password":"string"}'}]

  • 在没有“RouteBody”的单独路线上对其进行了测试,效果非常好。
  • 从头开始重写路由处理程序
  • 更改了参数的顺序(不知道为什么我认为这很重要......也许确实如此?)
  • 我没有为 RouteBody 使用 Pydantic 模型类型,而是选择使用单独的参数来使其发挥作用。然而,这不是一个理想的解决方案,因为如果您有很多参数,它需要列出所有参数。
  • 向 ChatGPT 寻求指导
python swagger fastapi multipartform-data openapi
1个回答
0
投票

要使用带有文件输入的 Pydantic 模型,您只需将该文件包含在 Pydantic 模型本身中。不要向函数添加额外的参数,而是将文件字段直接集成到 Pydantic 模型中。例如,它看起来像这样

class RouteBody(BaseModel):
    email: Annotated[EmailStr, StringConstraints(
        max_length = 255
    )]
    password: Annotated[str, StringConstraints(
        max_length = 60
    )]
    image: Annotated[UploadFile, File()]
    model_config = {"extra": "forbid"}

@some_api_router.post("/some-route")
async def handleRoute(routeBody: RouteBody = Form()):
    return {"msg": "Route"}

在 SwaggerUI 中,您仍然会遇到错误,因为内容类型默认为“application/x-www-form-urlencoded”。为了避免这种情况,切换到 Postman 并将正文类型设置为“form-data”,它应该可以顺利工作。最重要的是所有验证都将正常运行,这是一个很大的优点。这种方法比在函数参数中列出每个必需的输入更好,因为它可以让您一次性定义逻辑,而无需不必要的重复,而且方式更干净。

© www.soinside.com 2019 - 2024. All rights reserved.