0

I have a script that calls a POST endpoint but getting a 400 error. Meanwhile, the corresponding cURL request is successful.

First, here is the cURL:

curl -X 'POST' \
  'http://localhost:8080/api/predict?Key=123testkey' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@156ac81cde4b3f22faa4055b53867f38.jpg;type=image/jpeg'

And translated to requests:

import requests

url = 'http://localhost:8080/api/predict?Key=123testkey'

headers = {
    'accept': 'application/json',
    'Content-Type': 'multipart/form-data',
}

params = {'Key' : '123testkey'}

files = {'image': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')}

response = requests.post(url, files=files, params=params, headers=headers)

Have also tried using a URL that does not include the key, since the key is already specified in params:

import requests

url = 'http://localhost:8080/api/predict'

headers = {
    'accept': 'application/json',
    'Content-Type': 'multipart/form-data',
}

params = {'Key' : '123testkey'}

files = {'image': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')}

response = requests.post(url, files=files, params=params, headers=headers)

I thought this should be simple but I consistently get the 400 error with requests no matter what I try. Any suggestions?

Edit: have also tried 'image/jpeg' instead of 'image' to no avail.

Edit: replacing the "image" key with "file" unfortunately didn't work either

Edit: It works in postman desktop just fine, and generates the following code. However, this code also throws an error.

The generated code from postman:

import requests

url = "http://localhost:8080/api/predict?Key=123test"

payload={}
files=[
  ('file',('images19.jpg',open('156ac81cde4b3f22faa4055b53867f38.jpg','rb'),'image/jpeg'))
]
headers = {
  'Accept': 'application/json',
  'Content-Type': 'multipart/form-data'
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)

print(response.text)

And the error from the previously generated code from postman:

{"detail":"There was an error parsing the body"}

Any help figuring out what is going on would be much appreciated!

NominalSystems
  • 175
  • 1
  • 4
  • 13
  • 1
    In ```files```, the value for the key "image" is a file descriptor, not data. You need to read and encode (probably Base64) that data. – Martin Oct 13 '21 at 19:18
  • 1
    Try to do it with postman - https://stackoverflow.com/questions/39037049/how-to-upload-a-file-and-json-data-in-postman. Once it works there - make postman generate python code for you. – balderman Oct 13 '21 at 19:19
  • Thanks for the suggestion, I got it to work in postman just fine but the generated code throws the following error: {"detail":"There was an error parsing the body"}. – NominalSystems Oct 13 '21 at 21:17

1 Answers1

1

Your issue is in the variable files you need to add with the key 'file' instead of 'image' that's the difference between your curl and your python code, also remove the header because when you pass the file parameter the request set the proper header for send files. for example:

import requests

url = 'http://localhost:8080/api/predict?Key=123testkey'

params = {'Key' : '123testkey'}

files = {'file': open('156ac81cde4b3f22faa4055b53867f38.jpg', 'rb')}

response = requests.post(url, files=files, params=params)
Jose Lora
  • 1,392
  • 4
  • 12
  • 18