Multiple files upload (mutlipart/form-data) is ignored for Flask
Description
Consider following endpoint definition:
/test-formData-file-upload:
post:
summary: 'Test formData with file type, for file upload'
operationId: fakeapi.hello.test_formdata_file_upload
responses:
'200':
description: OK
requestBody:
content:
multipart/form-data:
schema:
x-body-name: formData
type: object
properties:
formData:
type: array
items:
type: string
format: binary
required:
- formData
What we are doing in here is uploading multiple files from the same mulipart field.
That gets correctly pulled from flask_request but ignored later in connexion.operations.abstract.AbstractOperation#_get_file_arguments
Expected behaviour
Request to Flask-based application with multiple files is correctly processed and we get multiple files available inside of handler.
Actual behaviour
Multiple files are ignored, only first is taken into account.
Steps to reproduce
- open
connexion/tests/fixtures/simple/openapi.yaml - find
/test-formData-file-uploaddefinition - Use snippet from above to replace the definition
- Go to
tests.api.test_parameters.test_formdata_file_upload - Use following code to replace the function
def test_formdata_file_upload(simple_app):
app_client = simple_app.app.test_client()
resp = app_client.post('/v1.0/test-formData-file-upload',
data={'formData': [(BytesIO(b'file contents'), 'filename1.txt'), (BytesIO(b'file contents'), 'filename2.txt')]})
assert resp.status_code == 200
response = json.loads(resp.data.decode('utf-8', 'replace'))
assert response == {'filename1.txt': 'file contents'}
- Observe test to pass, which it should not do.
Additional info:
Output of the commands:
python --version->3.7.3pip show connexion | grep "^Version\:"->master branchflask --version->1.1.0
cc @dtkav @hjacobs
Looks like a duplicate of #510. You can see my fork here https://github.com/simondrabble/connexion for a fix.
I think this is closed by #1000 Please re-open if there's something I missed.
I think this is closed by #1000 Please re-open if there's something I missed.
https://github.com/zalando/connexion/pull/1000 was reverted in https://github.com/zalando/connexion/pull/1101 because it broke httpaio backend
I think this is being followed in https://github.com/zalando/connexion/pull/987
Kindly bumping :) I could use Flask multipart file upload, perhaps this issue should be reopened?
What is the status of this issue? Can we expect to have the possibility to perform multiple files uploads or should we choose another framework? It is indeed related to #987, which seems to be slightly updated though.
status?
@dfeinzeig it looks like its being worked on here if you want to check it out :wink: : https://github.com/zalando/connexion/pull/1222
@kornicameister, I know it's been a while, but would you mind checking if either master or my PR #1222 fixes your issue? Do you still have what's needed to check it?
Thanks
hey @ddurham2 I do not have any project setup available, that project is long gone.
My only suggestion to actually verify that would be to write extensive test that loads bunch of files, sends them and you are trying to read them, but this is exactly what you have done. I think that if you manage to write really decent test coverage, it ill be proof enough to verify your PR ;-)
I have left some suggestions in PR.
You can get the files from connexion.request.files.getlist('formData')
Bumping it up. It would be very helpful to have multiple files upload out of the box. Waiting for #1222 to be merged : )
closable by my account
@ddurham2 this has been fixed for aiohttp, but not flask. I tested the provided example to be sure.
@RobbeSneyders, while I don't utilize flask in any projects, I'd be willing to take a stab at it if you thought it was worth it... Do the flask-based unit tests run by default? I'd guess the procedure would be to add a unit tests that reproduces the problem and then make fixes from there. Otherwise, I can leave it alone.
Sounds good @ddurham2.
We should be able to reuse #1000, which includes a test, but still need to resolve the same issue that caused it to be reverted in #1101. The implementation uses request.files.getlist() which works for Flask since request.files is a MultiDict there, but fails for aiohttp since files is a normal dict there.