FastAPI中上传多张图片的请求格式

hoa*_*ham 4 python file-upload python-requests fastapi

例子

这是我尝试上传图像列表的代码:

import requests
import glob
import cv2

path = glob.glob("test_folder/*", recursive=True) # a list of image's path

lst_img = []
for p in path[:3]:
    # img = cv2.imread(p)
    lst_img.append((p, open(p, 'rb'), "image/jpeg"))

data = {"files": lst_img}

url = "http://localhost:6789/" # url api of app

res = requests.post(url=url, data=data)

print(res.status_code)

print(res.text)

Run Code Online (Sandbox Code Playgroud)

描述

我正在尝试通过 Python 请求(包)将图像列表上传到 FastAPI 端点,但也许我的请求格式错误,导致错误422

import requests
import glob
import cv2

path = glob.glob("test_folder/*", recursive=True) # a list of image's path

lst_img = []
for p in path[:3]:
    # img = cv2.imread(p)
    lst_img.append((p, open(p, 'rb'), "image/jpeg"))

data = {"files": lst_img}

url = "http://localhost:6789/" # url api of app

res = requests.post(url=url, data=data)

print(res.status_code)

print(res.text)

Run Code Online (Sandbox Code Playgroud)

这是我的请求的格式:

"detail":[{"loc":["body","files",0],"msg":"Expected UploadFile, received: <class 'str'>","type":"value_error"}
Run Code Online (Sandbox Code Playgroud)

我尝试了很多方法,但总是失败。非常感谢你们帮忙解决这个问题。

环境

  • 操作系统:Linux:(Ubuntu 18.04)
  • FastAPI版本:0.61.1
  • 请求版本:2.24.0
  • Python版本:3.7.5

我尝试了以下方法,但仍然不起作用:

{'files': [('test_folder/image77.jpeg', <_io.BufferedReader name='test_folder/image77.jpeg'>, 'image/jpeg'), ('test_folder/image84.jpeg', <_io.BufferedReader name='test_folder/image84.jpeg'>, 'image/jpeg'), ('test_folder/image82.jpeg', <_io.BufferedReader name='test_folder/image82.jpeg'>, 'image/jpeg')]}
Run Code Online (Sandbox Code Playgroud)

我的 FastAPImain.py

lst_img.append(("file", (p, open(p, 'rb'), "image/jpeg")))
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 5

下面是如何使用 Python 请求和 FastAPI 上传多个文件(图像)的示例。如果您在上传文件时需要发送额外的数据,请查看此处。另外,如果您需要async 阅读以及编写在服务器端保存图像的内容,请查看此答案

应用程序.py

import uvicorn
from fastapi import File, UploadFile, FastAPI
from typing import List

app = FastAPI()

@app.post("/upload")
def upload(files: List[UploadFile] = File(...)):
    for file in files:
        try:
            contents = file.file.read()
            with open(file.filename, 'wb') as f:
                f.write(contents)
        except Exception:
            return {"message": "There was an error uploading the file(s)"}
        finally:
            file.file.close()

    return {"message": f"Successfuly uploaded {[file.filename for file in files]}"}    

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)
Run Code Online (Sandbox Code Playgroud)

测试.py

import requests
import glob

paths = glob.glob("images/*", recursive=True) # returns a list of file paths
images = [('files', open(p, 'rb')) for p in paths] # or paths[:3] to select the first 3 images
url = 'http://127.0.0.1:8000/upload'
resp = requests.post(url=url, files=images) 
print(resp.json())
Run Code Online (Sandbox Code Playgroud)