Почему resquest.files в Flask возвращает пустой ImmutableMultiDict([]) при загрузке изображения

Я создаю API для отдыха, используя Flask, Flask-Restfull, Flask-Uploads и Marshmallow. Я использую Postman для проверки. Когда я отправляю запрос почтальону, я получаю изображение: [Отсутствуют данные для обязательного поля.]. Проблема заключается в том, что request.files возвращает пустой ImmutableMultiDict([]). Здесь я отправляю код и изображения запроса почтальона.

------------------ РЕСУРС

from flask_restful import Resource
from flask import send_file, request
from flask_jwt_extended import jwt_required, get_jwt_identity
import traceback
import os
from werkzeug.utils import secure_filename
from libs import image_helper
from libs.strings import gettext
from schemas.image import ImageSchema
import logging

image_schema = ImageSchema()

class ImageUpload(Resource):
    @jwt_required()
    def post(self):
        """
        This endpoint is used to upload an image file. It uses the
        JWT to retrieve user information and save the image in the user's folder.
        If a file with the same name exists in the user's folder, name conflicts
        will be automatically resolved by appending a underscore and a smallest
        unused integer. (eg. filename.png to filename_1.png).
        """

        print(request.files) # IT RETURNS  ImmutableMultiDict([])
        data = image_schema.load(request.files)
    
        user_id = get_jwt_identity()
        folder = f"user_{user_id}"
        try:
            # save(self, storage, folder=None, name=None)
            image_path = image_helper.save_image(data["image"], folder=folder)
            # here we only return the basename of the image and hide the internal folder structure from our user
            basename = image_helper.get_basename(image_path)
            return {"message": gettext("image_uploaded").format(basename)}, 201
        except: #UploadNotAllowed:  # forbidden file type
            extension = image_helper.get_extension(data["image"])
            return {"message": gettext("image_illegal_extension").format(extension)}, 400

------------------Схемы------------------------

class FileStorageField(fields.Field):
    default_error_messages = {
        "invalid": "Not a valid image."
    }

    def _deserialize(self, value, attr, data) -> FileStorage:
        if value is None:
            return None

        if not isinstance(value, FileStorage):
            self.fail("invalid")

        return value


class ImageSchema(Schema):
    image = FileStorageField(required=True)

------- ПОЧТОВЫЕ ИЗОБРАЖЕНИЯ------

Заголовок запроса

Тело запроса


person Ernesto Ruiz    schedule 17.03.2021    source источник
comment
могу я увидеть ваш html? У меня была эта ошибка в прошлом. Я думаю, что могу знать проблему   -  person Constantine Westerink    schedule 18.03.2021
comment
у меня нет хтмл. Я создаю API для отдыха. Вот почему я показываю вам фотографии моего запроса в Postman.   -  person Ernesto Ruiz    schedule 18.03.2021


Ответы (1)


Я попробовал ваш код, просто удалив unwanted code (не относится к вопросу). И я успешно могу получить файлы по запросу.

Вот код, который я использовал

from flask import Flask, request
from flask_restful import Api, Resource
from marshmallow import Schema, fields
from werkzeug.datastructures import FileStorage

app = Flask(__name__)
api = Api(app)


class FileStorageField(fields.Field):
    default_error_messages = {
        "invalid": "Not a valid image."
    }

    def _deserialize(self, value, attr, data, **kwargs) -> FileStorage:
        if value is None:
            return None

        if not isinstance(value, FileStorage):
            self.fail("invalid")

        return value


class ImageSchema(Schema):
    image = FileStorageField(required=True)


image_schema = ImageSchema()


class ImageUpload(Resource):
    def post(self):

        print(request.files)  # IT RETURNS  ImmutableMultiDict([])
        data = image_schema.load(request.files)
        print(data)

        return {"ok": True}


api.add_resource(ImageUpload, '/upload/image')

if __name__ == "__main__":
    app.run(debug=True)

Вот скрин от почтальона

введите здесь описание изображения

введите здесь описание изображения

person Gaurang Delvadiya    schedule 20.03.2021