How to send JSON as part of multipart POST-request

后端 未结 2 1936
囚心锁ツ
囚心锁ツ 2020-12-01 22:06

I have following POST-request form (simplified):

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

--A         


        
相关标签:
2条回答
  • 2020-12-01 22:38

    In case if someone searches ready to use method to transform python dicts to multipart-form data structures here is a simple gist example to do such transformation:

    {"some": ["balls", "toys"], "field": "value", "nested": {"objects": "here"}}
        ->
    {"some[0]": "balls", "some[1]": "toys", "field": "value", "nested[objects]": "here"}
    

    To send some data you may want to use the multipartify method from this gist like this:

    import requests  # library for making requests
    
    payload = {
        "person": {"name": "John", "age": "31"},
        "pets": ["Dog", "Parrot"],
        "special_mark": 42,
    }  # Example payload
    
    requests.post("https://example.com/", files=multipartify(payload))
    

    To send same data along with any file (as OP wanted) you may simply add it like this:

    converted_data = multipartify(payload)
    converted_data["attachment[0]"] = ("file.png", b'binary-file', "image/png")
    
    requests.post("https://example.com/", files=converted_data)
    

    Note, that attachment is a name defined by server endpoint and may vary. Also attachment[0] indicates that it is first file in you request - this is also should be defined by API documentation.

    0 讨论(0)
  • 2020-12-01 23:02

    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.

    0 讨论(0)
提交回复
热议问题