4

我正在尝试使用 FastAPI 允许我的(dockerized)服务器响应返回的 API 调用

  • 一个图像image,和
  • 一本字典additional_dict

(对于机器学习示例,这可能是来自分类器和显着图的分类标签)。

就我而言,我认为使用相同的端点来获取两个对象是有意义的,因为它们是通过相同的计算生成的。

我可以使用类似于https://stackoverflow.com/a/55905051/4240413的内容成功地将图像作为二进制返回:

from PIL import Image
from fastapi import FastAPI, File
import tempfile
from starlette.responses import FileResponse

@app.post("/getstuff")
async def get_image_and_data(file: bytes = File(...)):

    image, additional_dict = process_image(image)

    with tempfile.NamedTemporaryFile(mode="w+b", suffix=".png", delete=False) as outfile:
        image.save(outfile)
        return FileResponse(outfile.name, media_type="image/png")

当我通过 localhost:8000/docs 上的招摇 UI 调用服务时,这甚至可以让我看到图像响应。

但是,我不知道如何将图像二进制文件和字典放在一起。

我尝试将我的退货声明替换为:

return FileResponse(outfile.name, media_type="image/png"), additional_dict

但这并没有真正起作用(在 localhost:8000/docs 上尝试招摇时,我只得到下面的 json 回复,并创建了临时文件的路径)

[{
"path": "/tmp/tmpldwe_79d.png",
"status_code": 200,
"filename": null,
"send_header_only": false,
"media_type": "image/png",
"background": null,
"raw_headers": [
    [
    "content-type",
    "image/png"
    ]
],
"stat_result": null
},
{
"foo": 1,
"bar": 2
}]

是否可以从同一端点获得二进制图像和附加字典的响应?如果是这样,最好的方法是什么?
是否可以在 Swagger UI 中呈现图像/docs并在那里读取 dict 值?

4

1 回答 1

7

您可以使用 base64 对二进制数据(在您的情况下为图像)进行编码,并通过字典发送编码的字符串。

   import base64

   with open("image.png", "rb") as image_file:
       encoded_image_string = base64.b64encode(image_file.read())

   payload = {
       "mime" : "image/png",
       "image": encoded_image_string,
       "some_other_data": None
   }

所以这个字典将包含 base64 编码的图像和任何其他数据字段。

在前端,您可以将图像从 base64 字符串解码回字节并将其呈现给用户。

于 2020-01-17T11:54:35.737 回答