FastAPI如何实现同时接收多请求参数与文件上传的端点功能
FastAPI同时上传文件和附加参数422报错问题处理
问题背景
我有一个用于存储文件及作者、评论等附加信息到数据库的应用,单独向FastAPI传递文件时功能正常,但将文件与其他参数一同传递时就会触发异常。查阅了相关技术讨论后仍未解决问题,我先后尝试了两种端点定义方案:
尝试的方案
方案1
尝试通过Pydantic模型接收非文件参数,代码如下:
from pydantic import BaseModel from typing import Optional from fastapi import FastAPI, File, UploadFile class Properties(BaseModel): language: Optional[str] = None author: Optional[str] = None app = FastAPI() @app.post("/uploadfile/") async def uploadfile(params: Properties, file: UploadFile = File(...)): # 内部业务逻辑
该方案的问题:当请求包含文件时,使用的是multipart/form-data编码格式,无法直接解析JSON类型的Pydantic模型参数,因此该方案本身不适用文件上传场景。
方案2
尝试直接通过Form接收非文件参数,代码如下:
from typing import Optional from fastapi import FastAPI, File, UploadFile, Form app = FastAPI() @app.post("/uploadfile/") async def uploadfile(file: UploadFile = File(...), language: str = Form(...), author: Optional[str] = Form(None)): # 内部业务逻辑
我使用的客户端请求代码如下:
import requests path = "你的本地文件路径" with open(path, 'rb') as f: response = requests.post('http://localhost:8005/uploadfile/', data={'language':'en', 'author':'me'}, files={'file': f})
上述两种方案请求后均返回422 Unprocessable Entity错误,通过Swagger测试时也会返回value is not a valid dict报错。
最终解决方案
文件上传场景仅可使用方案2的写法,问题出在端点的参数顺序:需要将所有Form类型的参数放在File类型参数的前面,调整后的端点代码如下:
from typing import Optional from fastapi import FastAPI, File, UploadFile, Form app = FastAPI() @app.post("/uploadfile/") async def uploadfile(language: str = Form(...), author: Optional[str] = Form(None), file: UploadFile = File(...)): # 内部业务逻辑
调整参数顺序后无需修改客户端代码,即可正常完成文件+附加参数的上传请求,Swagger测试也可正常运行。
内容的提问来源于stack exchange,提问作者Kosta
相关产品推荐
相关产品推荐

