【问题标题】:Requests format for uploading multiple images in FastAPIFastAPI上传多张图片的请求格式
【发布时间】:2020-10-23 06:06:47
【问题描述】:

示例

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

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)

说明

我正在尝试通过 url api 上传图像列表。在这里,我使用请求(python 包),但也许我的请求格式错误,然后我无法发布到 url api。我收到错误代码 422:

"detail":[{"loc":["body","files",0],"msg":"Expected UploadFile, received: <class 'str'>","type":"value_error"}

这是我的请求格式:

{'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')]}

我尝试了很多方法,但总是失败。非常感谢你们帮助解决它。

环境

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

试过了还是不行

lst_img.append(("file", (p, open(p, 'rb'), "image/jpeg")))

我的 FastAPI main.py

from typing import List

from fastapi import FastAPI, File, UploadFile
from fastapi.responses import StreamingResponse, FileResponse

app = FastAPI()

@app.post("/")
async def main(files: List[UploadFile] = File(...)):
    # file_like = open(video_path, mode="rb")
    # return StreamingResponse(file_like, media_type="video/mp4")
    return {"filenames": [file.filename for file in files]}

【问题讨论】:

  • FastAPI 是否在 localhost:6789 上运行?请也分享该代码
  • 是的,我在 localhost 上使用自定义端口 6789 运行,我编辑了我的问题,让我们再看看

标签: python python-requests fastapi


【解决方案1】:

以下是如何使用 Python 请求和 FastAPI 上传多个文件(图像)的示例。如果您在上传文件时需要发送额外的数据,请查看here。另外,如果您需要async 编写以将图像保存在服务器端,请查看this answer

app.py

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

app = FastAPI()


def save_file(filename, data):
    with open(filename, 'wb') as f:
        f.write(data)

@app.post("/upload")
async def upload(files: List[UploadFile] = File(...)):

    # in case you need the files saved, once they are uploaded
    for file in files:
        contents = await file.read()
        save_file(file.filename, contents)

    return {"Uploaded Files": [file.filename for file in files]}
    

if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)

test.py

import requests
import glob

paths = glob.glob("images/*", recursive=True) # returns a list of files/pathnames
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())

【讨论】:

    【解决方案2】:

    您应该使用request 模块的files 参数来发送文件

    import requests
    import glob
    
    path = glob.glob("test_folder/*", recursive=True) # a list of image's path
    
    lst_img = []
    for p in path[:3]:
        lst_img.append({"files": open(p, 'rb')})
    
    url = "http://localhost:6789/" # url api of app
    
    for data in lst_img:
        res = requests.post(url=url, files=data)
        print(res.status_code)
        print(res.text)
    
    

    【讨论】:

    • 谢谢你,但我想我想同时发送多个图像,而不是每个图像,因为 FastAPI 允许图像列表。如果我包装一个 for..loop 那就没用了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2015-03-05
    • 2011-09-01
    • 2021-06-24
    • 2019-11-15
    相关资源
    最近更新 更多