graphql-python / flask-graphql

Adds GraphQL support to your Flask application.
MIT License
1.32k stars 139 forks source link

File Upload #33

Open vladinator1000 opened 7 years ago

vladinator1000 commented 7 years ago

I'm working on an example repo and was wondering, what would be the simplest way to implement that? This is what I tried without GraphQL:

@app.route('/upload', methods=['POST'])
def uploadFile():
    for key in request.files:
        file = request.files[key]
        file.save(os.path.join(UPLOAD_FOLDER, file.filename))

    return 'uploaded'

This is what I used in Node.js, would love to do something like that for Flask in Python.

If it's not supported by flask-graphql I'd be happy to work on a pull request. Also, how would you test this without a browser, using Graphiql, Postman or something like that?

michaelkuty commented 6 years ago
    def mutate(cls, info, **kwargs):

        file = info.context.files.get('file', None)
hxuanhung commented 6 years ago

@michaelkuty can you make it work with Apollo? I got "Must provide query string." error when trying to send multipart/form-data; to the server.

michaelkuty commented 6 years ago

In apollo you must use something like middleware or something else..

hxuanhung commented 6 years ago

hm, have you actually worked on it? I'm using https://github.com/jaydenseric/apollo-upload-client for a client that sends multipart/form-data to the server but it seems not working.

rshk commented 6 years ago

Ok, just managed to get it to work with Apollo. The problem lies with incorrect handling of the multipart-encoded request, here: https://github.com/graphql-python/flask-graphql/blob/master/flask_graphql/graphqlview.py#L126-L127

I sub-classed the GraphQLView to properly handle multipart/form-data, as per the spec. I also created a custom scalar field that can be used for file uploads, so no need to get files out of info.context or flask.request.

https://gist.github.com/rshk/97fd7b444e48c60218addb2b64897572

This will work with the version of flask-graphql currently in pypi; I haven't tested whith the master version yet (but should still work).

I can open a PR with the changes (I have unit tests covering that place_files_in_operations too).

hxuanhung commented 6 years ago

Similar to https://github.com/lmcgartland/graphene-file-upload/blob/master/graphene_file_upload/__init__.py We can change a few things like I mentioned in https://github.com/lmcgartland/graphene-file-upload/issues/3 to make it work for Flask.

rshk commented 6 years ago

See #51