0

I am little confused. I want to create API that can post image, and one dictionary along with that image. How can I do it ? for one image, I can do it like this. What if I want to post another variable which is not a file, lets say variable meta_data?

url = 'http://127.0.0.1:5000/im_size'
my_img = {'image': open('test.jpg', 'rb')}
r = requests.post(url, files=my_img)

What change should be in my API script as well which is as follow

from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route("/im_size", methods=["POST"])
def process_image():
    file = request.files['image']
    # Read the image via file.stream
    img = Image.open(file.stream)

    return jsonify({'msg': 'success', 'size': [img.width, img.height]})


if __name__ == "__main__":
    app.run(debug=True)

1 Answers1

2

requests.post supports a json argument which sets the correct content type ('application/json') for that data to then be accessed via request.get_json() method in Flask.

However this plays up when you're also providing the files argument, which sets the content type to 'multipart/form-data'.

With help from this thread I found the solution is to send your JSON data as part of the multipart form.

So on the client define a dictionary, and add it to the my_img dict as follows:

import json

meta_data = {'message':'I am a picture', 'another_message':'About to upload'}

my_img = {'image': open('test.jpg', 'rb'),
          'json_data':  ('j', json.dumps(meta_data), 'application/json')}

Then on the server end you'll also need to import json and within your process_image view function you can access that data with:

    image = request.files['image'] # The Werkzeug FileStorage object.

    json_data = request.files['json_data']
    meta_data = json.load(json_data)

    print (meta_data)
    print (json_data.filename)

Server output:

{'message': 'I am a picture', 'another_message': 'About to upload'}
j
v25
  • 7,096
  • 2
  • 20
  • 36