如何在 FastAPI 中使用具有多个正文参数和文件上传的端点?

时间:2021-05-27 20:07:44

标签: python python-3.x post fastapi

我有一个应用程序可以存储文件和其他信息,例如作者,评论 DB。我可以将文件传递给 FastAPI,但是通过将文件与参数一起传递会出现问题。

我检查了以下问题 How to add multiple body params with fileupload in FastAPI? 和此问题 [QUESTION] Use UploadFile in Pydantic model #657 但没有成功。

我在 FastAPI 端点中尝试了 2 个定义

选项 1

class Properties(BaseModel):
   language: Optional[str] = None
   author: Optional[str] = None

@app.post("/uploadfile/")
async def uploadfile(params: Properties, file: UploadFile = File(...)):
    #internal logic

选项 2

@app.post("/uploadfile/")
async def uploadfile(file: UploadFile = File(...),
                         language: str = Form(...),
                         author: Optional[str] = Form(None)):
   #internal logic

客户端代码: 以下代码用于客户端,但两个选项的响应都是422 Unprocessable Entity

with open(path, 'rb') as f:
     response = requests.post('http://localhost:8005/uploadfile/', data={'language':'en', 
     'author':'me'}, files={'file': f})

无法从 swagger 测试这两个选项,我得到了回应:值不是有效的字典。数据对我来说看起来不错,但也许我遗漏了一些东西。

好像是客户端代码不对,我也试了几次都没成功。

提前感谢您的支持!

适合我的解决方案

正如 'Drdilyor' 在他的评论中所写的,我使用了选项 2,因为我们正在发送文件。我的问题是在争论的顺序内。更改它们后,一切都开始工作了。

1 个答案:

答案 0 :(得分:1)

根据 this issue,我认为这是 HTTP 限制,我们必须使用 application/jsonmultipart/formdata,但不能同时使用。由于我们正在上传文件,因此必须使用 multipart/formdata。此代码(以某种方式)有效:

@app.post("/uploadfile/")
async def uploadfile(author: Optional[str] = Form(...),
                     language: Optional[str] = Form(...),
                     file: UploadFile = File(...)):

我用 curl http://localhost:8000/uploadfile/ -X POST -F author=me -F language=en -F file=@/path/to/file,不确定 requests

我认为您也可以使用查询参数