简体   繁体   中英

Uploading an image from python client to a flask server

I am using requests and requests_toolbelt to send an image to the cloud and so far I have something like this

import requests
import json
from requests_toolbelt import MultipartEncoder

m = MultipartEncoder(
    fields={"user_name":"tom", "password":"tom", "method":"login",
            "location":"landing", "cam_id":"c00001", "datetime":"hammaTime!"
            ,'image': ('filename', open('image.jpg', 'rb'))}
    )
r = requests.post(url, data=m)
print r.text

After it gets to the server, how to I get back a dictionary of something usable? The toolbelt docs show only how to post, not how to handle it on the other end. Any advice?

You can see a working example of Flask server which accepts POSTS like the on you're trying to make on HTTPbin . If you do something like:

m = MultipartEncoder(fields=your_fields)
r = requests.post('https://httpbin.org/post', data=m, headers={'Content-Type': m.content_type})
print(r.json()['form'])

You'll see that everything in your post should be in that dictionary.

Using HTTPBin's source, you can then see that the form section is generated from request.form . You can use that to retrieve the rest of your data. Then you can use request.files to access the image you wish to upload.

The example Flask route handler would look like:

@app.route('/upload', methods=['POST'])
def upload_files():
    resp = flask.make_response()
    if authenticate_user(request.form):
        request.files['image'].save('path/to/file.jpg')
        resp.status_code = 204
    else:
        resp.status_code = 411
    return resp

You should read into Uploading Files documentation though. It is really invaluable when using common patterns like this in Flask.

requests-toolbelt can only send the file to the server but it is up to you to save that on the server side and then return meaningful result. You can create a flask endpoint to handle the file upload, return the desired result dictionary as a JSON and then convert the JSON back to dict on the client side with json.loads .

@app.route('/upload', methods=['POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['image']
        f.save('uploads/uploaded_file')
        # do other stuff with values in request.form
        # and return desired output in JSON format
        return jsonify({'success': True})

See flask documentation for more info on file uploading.

Also, you need to specify the mime-type while including the image in MultipartEncoder and content-type in the header while making the request. (I'm not sure you if you can even upload images with MultipartEncoder. I was successful with only the text files.)

m = MultipartEncoder(
    fields={"user_name":"tom", "password":"tom", "method":"login",
            "location":"landing", "cam_id":"c00001", "datetime":"hammaTime!"
            ,'image': ('filename', open('file.txt', 'rb'), 'text/plain')}  # added mime-type here
    )
r = requests.post(url, data=m, headers={'Content-Type': m.content_type})  # added content-type header here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM