Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upload list of files using restX + Swagger #177

Open
maory69 opened this issue Jul 20, 2020 · 14 comments
Open

Upload list of files using restX + Swagger #177

maory69 opened this issue Jul 20, 2020 · 14 comments
Labels
question Further information is requested

Comments

@maory69
Copy link

maory69 commented Jul 20, 2020

Hey,

I'm trying to upload a list of files to my post method using the swaggerUI
I am defining my input using RequestParser and add_argument method.
Uploading one file works just fine, but once I'm adding 'action=append' to make it a list of files it doesn't work.

my code looks like this:

from flask_restx import Namespace, Resource, reqparse
from werkzeug.datastructures import FileStorage
upload_parser = reqparse.RequestParser()
upload_parser.add_argument('images', location='files',
                           type=FileStorage, required=True, action="append")


@api.route("/")
class MyResource(Resource):
    @api.expect(upload_parser)
    def post(self):
        args = upload_parser.parse_args()
        images = args['images']

This is the cUrl from swagger:
curl -X POST "http://127.0.0.1:8000/" -H "accept: application/json" -H "Content-Type: application/x-www-form-urlencoded" -d "images=%5Bobject%20File%5D&images=%5Bobject%20File%5D"

And the problem is that swagger sends it as application/x-www-form-urlencoded and not multipart/form-data
Saying again, if I don't add the action='append' to the add_argument method, and I only send one file using Swagger it sends it as multipart/form-data

Is there any way to control it?

Screen Shot 2020-07-20 at 19 25 22

Screen Shot 2020-07-20 at 19 25 33

Screen Shot 2020-07-20 at 19 25 40

@maory69 maory69 added the question Further information is requested label Jul 20, 2020
@datavistics
Copy link

Im also having this issue. It appears to be similar to this: noirbizarre/flask-restplus#463
Quite annoying...

@datavistics
Copy link

I tried forcing the content type with the decorator and the argument location as 'headers' as in the documentation
but had the same issues as this issue: #67

@subu604
Copy link

subu604 commented Jan 10, 2021

I Tried the same code and uploaded multiple files got to knew that if
upload_parser.add_argument('images', location='files',
type=FileStorage, required=True, action="append")

  1. If i use required=True then i am getting below error
    {
    "errors": {
    "file": "Missing required parameter in an uploaded file"
    },
    "message": "Input payload validation failed"
    }
  2. If i remove the require=True, then i am getting None on the args
    class Upload(Resource):
    def post(self):
    args = upload_parser.parse_args()
    print(args, '&&&&&&&&')
    file = args.get('file')
    print(file.filename)
    return "Uploaded file is " + file.filename

output{'file': None} &&&&&&&&
AttributeError: 'NoneType' object has no attribute 'filename'

Could anyone help me on this while uploading multiple files how to get the filenames and swagger documentation for that as well

@ltpitt
Copy link

ltpitt commented Mar 24, 2021

I am also having the same problem...
Was this never solved?

@pletessier
Copy link

I think the problem is coming from the line

if any(p["type"] == "file" for p in all_params):

It works when I replaced it by

if any(p["type"] == "file" or (p["type"] == "array" and p["items"]["type"]=="file") for p in all_params):

@philnagel
Copy link

This actually does not seem to be supported in Swagger UI currently. See Swagger Docs and GitHub Issue.
But it seems that it still works when submitting multiple files via other means, such as Postman. This is even without this patch.

@pletessier
Copy link

Well, I do use Swagger UI to test my API, and my "patch" allows sending multiple files.
screenshot-trombinos-dev priv ina-2021 08 17-17_21_46

Maybe it does not work in all contexts...

@ClimenteA
Copy link

I think the problem is coming from the line

if any(p["type"] == "file" for p in all_params):

It works when I replaced it by

if any(p["type"] == "file" or (p["type"] == "array" and p["items"]["type"]=="file") for p in all_params):

This solves the issue for me.

@philnagel
Copy link

philnagel commented Oct 21, 2021

While it makes the Swagger UI look correct, it does not actually submit the files in the correct way though.
This is what it looks like recorded with Fiddler - just getting empty objects, and 2 files here are sent in the same key:
image

And this is what it should look like, files sent as file objects with the correct Content-Type. Maybe the issue is just the missing Content-Type?
image

When sent from a client other than swagger, the files do come through properly.

And also, when removing the action='append' arg, the single file is sent correctly as well:
image

@ClimenteA
Copy link

Indeed, not sure why it worked for a while...
Closed the pull request the solution doesn't work.

Used for tests:
main.py.txt

@mdylan2
Copy link

mdylan2 commented May 2, 2022

Any updates on this issue?

@wernersbacher
Copy link

PR is still not approved. So you have to fork and merge for yourself

@mdylan2
Copy link

mdylan2 commented Nov 11, 2022

Thank you!

TraivsBrookes96 added a commit to TraivsBrookes96/flask-restx that referenced this issue May 11, 2023
… accounts for multiple arguments as part of the form and sets the correct "consumes" values so that "multipart/form-data" gets submitted, as with a single file, when a list of files is present.
TraivsBrookes96 added a commit to TraivsBrookes96/flask-restx that referenced this issue May 11, 2023
@TraivsBrookes96
Copy link

#542 PR in for this issue, takes @jingapore solution slightly further resolving issues with list comprehensions for keys that do not always exist in the dict & corresponding unit test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

10 participants