0

With flask_server.py running:

from flask import Flask, request, Response
import logging

logging.basicConfig(level=logging.DEBUG, 
                    format='%(levelname)s-%(message)s')

app = Flask(__name__)


@app.route('/test', methods=['GET','POST'])
def route():   
    logging.info('get_json: %s : %s' % (request.get_json(), type(request.get_json())))
    logging.info('files: %s : %s' % (request.files, type(request.files)))
    return Response()

if __name__ == '__main__':
    app.run('0.0.0.0', 5000)

send the http request using requests.post method supplying it with Python dictionary as json argument:

import json, requests    
dictionary = {"file": {"url": "https://bootstrap.pypa.io/get-pip.py"}}  
response = requests.post("http://127.0.0.1:5000/test", json=dictionary)

Flask server logs that it gets the dictionary with Flask.request.get_json method:

root - INFO - get_json: {u'file': {u'url': u'https://bootstrap.pypa.io/get-pip.py'}} : <type 'dict'>
root - INFO - files: ImmutableMultiDict([]) : <class 'werkzeug.datastructures.ImmutableMultiDict'>

Again, via requests.post method's files argument send an open file object. Flask server will get it via Flask.request.files attribute:

files = {'key_1': open('/any_file.txt', 'rb')}
response = requests.post(url, files = files)

Flask server logs:

root - INFO - get_json: None : <type 'NoneType'>
root - INFO - files: ImmutableMultiDict([('file_slot_1', <FileStorage: u'any_file.txt' (None)>)]) : <class 'werkzeug.datastructures.ImmutableMultiDict'>

Lastly, send both: the dictionary and open file object using same requests.post method:

response = requests.post("http://127.0.0.1:5000/test",
                         json=dictionary, 
                         files=files)

Server logs that it gets the file but does not get the json dictionary.

Is it be possible to send a request supplying it with multiple data arguments: such as 'json' and 'files'?

1 Answer 1

2

You can send multiple file objects using the file parameter and a list. However, your json data will need to be among one of those files. That's because even though you're just doing json=dictionary in the first request, it's actually sending Content-Type: application/json in the header. When you want to send multiple parts, you need to use multipart/form-data, via files=<a list>:

json_data = json.dumps({"file": {"url": "https://bootstrap.pypa.io/get-pip.py"}})
multiple_files = [
    ('targets', ('data.json', json_data, 'application/json')),
    ('targets', ('key_1', open('/any_file.txt', 'rb'), 'text/plain'))
]
response = requests.post(url, files=multiple_files)

The target's name here is assumed to be targets. You can make up your own if your Flask app is the recipient of the uploads.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.