0

Assume api url is https://34.35.36.37:8000/api

Sent a POST request from postman app which is successfull enter image description here

enter image description here

The attached file(key = user_image) is a .jpg file

On the server side (https://34.35.36.37:8000/api):

@app.route('/api', methods=['POST'])
def api():
    print("check1")
    user_image = request.files['user_image']
    print("check2")
    return "some text"

But when I try a post request using a flask app in which a form is displayed to upload an image which is then sent to the api url, there is an error

api_url = "https://34.35.36.37:8000/api"
content_type = 'application/json' 
headers = {'Content-Type': content_type}

class UploadForm(FlaskForm):
    user_image = FileField('Upload an image',validators=[FileAllowed(['jpg', 'png', 'jpeg'], u'Image only!'), FileRequired(u'File was empty!')])
    submit = SubmitField('Submit')

@app.route('/', methods=['GET','POST'])
def predict():
    form = UploadForm()
    if form.validate_on_submit():
        payload = {}
        files = [
          ('user_image', form.data['user_image'])
        ]
        #response = requests.post(api_url, data={'user_image': form.data['user_image']}, headers=headers, verify=False)
        response = requests.request("POST", api_url, headers=headers, data = payload, files = files, verify=False)
        print(response.text)
        return 'some text'

     return render_template('index.html', form=form)

When checked on the server side, the line print('check1') is executed but the line print('check2') is not executed.

I think the error is with the following 2 lines which involves sending image to the api url in the post request

Line1:

files = [
              ('user_image', form.data['user_image'])
            ]

Line2:

response = requests.request("POST", api_url, headers=headers, data = payload, files = files, verify=False)
R-R
  • 317
  • 1
  • 6
  • 18
  • Looks like the `files` parameter sends the data as a stream and you need to do a little bit more work to upload the files. Check out @gihanchanuka's answer on https://stackoverflow.com/questions/22567306/python-requests-file-upload – PGHE Mar 04 '20 at 20:22
  • @PGHE The problem is postman uses file location to read the file 'files = {'user_image': open('C://file.jpg', 'rb')}' . Is there a way to do this when using flask form OR When using images in POST request, is there no way we can make it work in both flask and postman? – R-R Mar 05 '20 at 04:57

2 Answers2

2
api_url = "https://34.35.36.37:8000/api"

class UploadForm(FlaskForm):
    user_image = FileField('Upload an image',validators=[FileAllowed(['jpg', 'png', 'jpeg'], u'Image only!'), FileRequired(u'File was empty!')])
    submit = SubmitField('Submit')

@app.route('/', methods=['GET','POST'])
def predict():
    form = UploadForm()
    if form.validate_on_submit():
        file_uploaded = request.files['user_image']
        files = {'user_image': (file_uploaded.filename, file_uploaded.read())}
        response = requests.post(api_url, files = files)
        return 'some text'

     return render_template('index.html', form=form)

The above code worked for me. It is equivalent to sending a 'POST' request from postman after selecting a file in 'Body' section with key 'user_image'. Do not use any headers in the post request response = requests.post(api_url, files = files)

On the server side(api_url), the file can be received with user_image = request.files['user_image']

R-R
  • 317
  • 1
  • 6
  • 18
0

For me I had to have debug mode set to false on both applications.