1

I have the following curl command

curl -X POST "http://localhost:5000/api/v1/image/cad1b12e-c374-4d46-b43b-3ddbe7d683c4" -H  "accept: application/json" -H  "Content-Type: multipart/form-data" -F "file=@tests/test.jpg;type=image/jpeg"

I am trying to construct a pytest function with the same behavior that the command above but I am not getting the exact result, the pytest function is the following

url = "http://localhost:5000/api/v1/image/cad1b12e-c374-4d46-b43b-3ddbe7d683c4"

payload={}

files=[('file',('test.png',open('./tests/test.png','rb'),'image/png'))]
headers = {
    'accept': 'application/json',
    'Content-Type': 'multipart/form-data'
}

response = requests.request("POST", url, headers=headers, data=payload, files=files)
davidism
  • 121,510
  • 29
  • 395
  • 339
chatzich
  • 1,083
  • 2
  • 11
  • 26

1 Answers1

1

Short answer:

Don't specify a Content-Type in the headers dictionary, when providing a files argument to the requests.request method.

Longer answer

I tried to test that functionality to my own Flask upload script.

This worked when removing 'Content-Type': 'multipart/form-data' form the headers dictionary, otherwise the response was 400 bad request (see response.content)

I noted that after making the request, and inspecting response.request.headers I could see that

  • when specifying that header it was part of the request, as-is:

     'Content-Type': 'multipart/form-data'
    
  • however when not specifying it requests automatically generates the header with a boundary, and the request succeeded:

     'Content-Type': 'multipart/form-data; boundary=1beba22d28ce1e2cdcd76d253f8ef1fe'
    

Also:

  • To find the headers sent from curl, either by using the trace method or if you have access to the server, printing request.headers within the upload route, you can see that the curl command automatically appends a boundary to the header, even when the flag -H "Content-Type: multipart/form-data" is provided:

      Content-Type: multipart/form-data; boundary=------------------------c263b5b9297c78d3
    
  • The same can be observed via the Network tab in your browser dev-tools, when uploading via an HTML form with enctype="multipart/form-data" set as an attribute.


I had always thought that manually adding 'Content-Type:':'multipart/form-data' to the headers dict was required, but it appears when using the the files argument to requests.request method, this is automatically generated with the boundary.

In fact the requests docs make no mention of setting this header yourself.

v25
  • 7,096
  • 2
  • 20
  • 36
  • Exactly!Correct! but Postman code generator for python suggested these headers with `'Content-Type:':'multipart/form-data'` – chatzich Dec 28 '20 at 21:42