Возврат нескольких файлов из fastapi - PullRequest
0 голосов
/ 11 апреля 2020

Используя fastapi , я не могу понять, как отправить несколько файлов в ответ. Например, чтобы отправить один файл, я буду использовать что-то вроде этого

from fastapi import FastAPI, Response

app = FastAPI()

@app.get("/image_from_id/")
async def image_from_id(image_id: int):

    # Get image from the database
    img = ...
    return Response(content=img, media_type="application/png")

Однако я не уверен, как выглядит отправка списка изображений. В идеале я хотел бы сделать что-то вроде этого:

@app.get("/images_from_ids/")
async def image_from_id(image_ids: List[int]):

    # Get a list of images from the database
    images = ...
    return Response(content=images, media_type="multipart/form-data")

Однако, это возвращает ошибку

    def render(self, content: typing.Any) -> bytes:
        if content is None:
            return b""
        if isinstance(content, bytes):
            return content
>       return content.encode(self.charset)
E       AttributeError: 'list' object has no attribute 'encode'

1 Ответ

1 голос
/ 11 апреля 2020

Zipping - лучший вариант, который будет иметь одинаковые результаты во всех браузерах. Вы можете архивировать файлы динамически.

import os
import zipfile
import StringIO


def zipfiles(filenames):
    zip_subdir = "archive"
    zip_filename = "%s.zip" % zip_subdir

    # Open StringIO to grab in-memory ZIP contents
    s = StringIO.StringIO()
    # The zip compressor
    zf = zipfile.ZipFile(s, "w")

    for fpath in filenames:
        # Calculate path for file in zip
        fdir, fname = os.path.split(fpath)
        zip_path = os.path.join(zip_subdir, fname)

        # Add file, at correct path
        zf.write(fpath, zip_path)

    # Must close zip for all contents to be written
    zf.close()

    # Grab ZIP file from in-memory, make response with correct MIME-type
    resp = Response(s.getvalue(), mimetype = "application/x-zip-compressed")
    # ..and correct content-disposition
    resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename

    return resp


@app.get("/image_from_id/")
async def image_from_id(image_id: int):

    # Get image from the database
    img = ...
    return zipfiles(img)

В качестве альтернативы вы можете использовать кодировку base64 для встраивания (очень маленького) изображения в ответ json. но я не рекомендую его.

Вы также можете использовать MIME / multipart, но имейте в виду, что я был создан для сообщений электронной почты и / или передачи POST на сервер HTTP. Он никогда не предназначался для получения и анализа на стороне клиента транзакции HTTP. Некоторые браузеры поддерживают это, другие нет. (поэтому я думаю, что вы не должны использовать это тоже)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...