flask-restplus icon indicating copy to clipboard operation
flask-restplus copied to clipboard

FileUpload with required=True

Open hhllcks opened this issue 7 years ago • 12 comments

Hi,

it seems that using the parameter required=True for a FileUpload like it is shown in the documentation does not seem to work. If the parameter is set, I get the following error:

{
  "errors": {
    "file": "Missing required parameter in an uploaded file"
  },
  "message": "Input payload validation failed"
}

If the parameter is not there, everything works fine.

I am using Flask 1.0.2 and Flask_restplus 0.11.0.

Here is the full code of my example:

from flask import Flask, Response, jsonify, request
from flask_restplus import Api, Resource
from flask_cors import CORS 
from werkzeug.datastructures import FileStorage

app = Flask(__name__) 
CORS(app) 
api = Api(app, version='1.0', title='My API', validate=False)

upload_parser = api.parser()
upload_parser.add_argument('file', location='files', type=FileStorage, required=True)

@api.route('/upload')
@api.expect(upload_parser)
class Upload(Resource):
    def post(self):
        args = upload_parser.parse_args()
        uploaded_file = args['file']  # This is FileStorage instance
        print(list(args.keys()))
        # url = do_something_with_file(uploaded_file)
        return {'Hello': 'File'}, 201

if __name__ == '__main__': 
    app.run(host='0.0.0.0', debug=True)

hhllcks avatar Jun 04 '18 15:06 hhllcks

It seems that my problem could lie somewhere else. It seems that the swagger ui does not upload the files correctly.

If you curl myself like this everything works fine:

curl -X POST "http://localhost:5000/upload" -H "accept: application/json" -F "[email protected]"

The questions is then: why does swagger ui create a curl call that looks like this:

curl -X POST "http://localhost:5000/digit" -H "accept: application/json" -H "Content-Type: application/json" -d {"file":{}}

Why does it want to send it as json?

hhllcks avatar Jun 04 '18 16:06 hhllcks

I'm experiencing the exact same error. And I also think that the problem is on the SwaggerUI part of flask-restplus since it generates this wrong curl call.. Please solve this issue since it's very annoying to upload the file per terminal and then test the rest of the API in the SwaggerUI I build a WebApp where I upload the file from a standard HTML Form and it works perfectly fine.

floschne avatar Aug 14 '18 12:08 floschne

+1 here. Currently using Postman as a workaround (as described here) . Would love to see this solved as well!

SimonVerhoek avatar Sep 25 '18 11:09 SimonVerhoek

+1, also facing the same problem

liviaalmeida avatar Sep 27 '18 17:09 liviaalmeida

+1 same problem

pk8189 avatar Mar 08 '19 15:03 pk8189

+1 same problem

Sanix-Darker avatar Mar 29 '19 11:03 Sanix-Darker

Does anyone found a solution to this? Same problem here

romulofff avatar Nov 05 '19 20:11 romulofff

issue was genrated in june 2018 and we are still facing this issue.

gaurav02712 avatar Mar 27 '20 12:03 gaurav02712

This is my code in my case, I use reqparse from flask_restplus parser.py

import werkzeug
from flask_restplus import reqparse


image_upload = reqparse.RequestParser()
image_upload.add_argument('propic',
                          type=werkzeug.datastructures.FileStorage,
                          location='files',
                          required=True,
                          help='Image file cannot empty')

image_resource.py

    @namespace_user.expect(parser.image_upload)  #namespace maybe could change to api from flask_restplus
    def put(self):
        output = {}
        img_arg = 'propic'
        args = parser.image_upload.parse_args()
        if args[img_arg].mimetype == 'multipart/form-data' or args[img_arg].mimetype == 'image/png':
            data_user_propics_path = 'data/propics/'
            destination = os.path.join(os.path.dirname(os.path.abspath(__file__)),data_user_propics_path)

            if not os.path.exists(destination):
                os.makedirs(destination)

            img_hash_filename = hash_filename_by_md5("something_what_you_want")
            img_file = '%s%s' % (destination, img_hash_filename)

            try:
                args[img_arg].save(img_file)

                return make_response(jsonify({
                    'url': img_file
                }), 201)

            except Exception as e:

                print(e)
                return make_response(jsonify({
                    'message': 'image storage error'
                }), 500)

        else:
            return make_response(jsonify({
                'message': 'image type error'
            }), 401)

and it's work fine.

dsp85103 avatar Apr 17 '20 07:04 dsp85103

also meet the same problem, any work around?

wbqtac avatar May 22 '21 21:05 wbqtac

Any update on this issue? Facing the same problem here

mdylan2 avatar May 02 '22 21:05 mdylan2

When making a front-end request, try to remove the header configuration and keep the default header

g5539220y avatar Jul 20 '22 12:07 g5539220y