Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send JSON as part of multipart POST-request

I have following POST-request form (simplified):

POST /target_page HTTP/1.1  
Host: server_IP:8080
Content-Type: multipart/form-data; boundary=AaaBbbCcc

--AaaBbbCcc
Content-Disposition: form-data; name="json" 
Content-Type: application/json

{ "param_1": "value_1", "param_2": "value_2"}

--AaaBbbCcc
Content-Disposition: form-data; name="file"; filename="..." 
Content-Type: application/octet-stream

<..file data..>
--AaaBbbCcc--

I try to send POST-request with requests:

import requests
import json

file = "C:\\Path\\To\\File\\file.zip"
url = 'http://server_IP:8080/target_page'


def send_request():
    headers = {'Content-type': 'multipart/form-data; boundary=AaaBbbCcc'}

    payload = { "param_1": "value_1", "param_2": "value_2"}

    r = requests.post(url, files={'json': (None, json.dumps(payload), 'application/json'), 'file': (open(file, 'rb'), 'application/octet-stream')}, headers=headers)

    print(r.content)

if __name__ == '__main__':
    send_request()

but it returns status 400 with following comment:

Required request part \'json\' is not present.
The request sent by the client was syntactically incorrect.

Please point on my mistake. What should I change to make it work?

like image 738
Andersson Avatar asked Mar 11 '16 12:03

Andersson


People also ask

Can we send JSON object in post request?

POST requests In Postman, change the method next to the URL to 'POST', and under the 'Body' tab choose the 'raw' radio button and then 'JSON (application/json)' from the drop down. You can now type in the JSON you want to send along with the POST request.

Can we send JSON object in post request in REST API?

To post JSON to a REST API endpoint, you must send an HTTP POST request to the REST API server and provide JSON data in the body of the POST message. You also need to specify the data type in the body of the POST message using the Content-Type: application/json request header.


1 Answers

You are setting the header yourself, including a boundary. Don't do this; requests generates a boundary for you and sets it in the header, but if you already set the header then the resulting payload and the header will not match. Just drop you headers altogether:

def send_request():
    payload = {"param_1": "value_1", "param_2": "value_2"}
    files = {
         'json': (None, json.dumps(payload), 'application/json'),
         'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
    }

    r = requests.post(url, files=files)
    print(r.content)

Note that I also gave the file part a filename (the base name of the file path`).

For more information on multi-part POST requests, see the advanced section of the documentation.

like image 122
Martijn Pieters Avatar answered Sep 17 '22 20:09

Martijn Pieters