Post a string as multipart/form-data using request

2019-08-13 18:19发布

I am posting to an API that seems to insist on receiving XML data as multipart/form-data with the name (file name?) xml. It works in postman but I can't get it to work using Python's requests. This is my Python code (based on https://stackoverflow.com/a/24443309/1011724):

requests.post(callpro_url,
              files={'xml':('data.xml',result)},
              verify=False).text

where result is a string containing XML. If I try this code I get the response:

xml post field is empty

which is the response this API give if you don't use the multipart/form-data header.

If I generate code from the working postman post I get something like this (slightly redacted):

import requests

url = "https://blablabla.blablab.com/blabla/api.php"

querystring = {"mode":"import","hash":"redacted-hash","xml":"\"xml\""}

payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"xml\"\r\n\r\n<?xml version=\"1.0\" ?>\n<importdata>\n --redacted-XML-- \n</importdata>\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
headers = {
    'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
    'cache-control': "no-cache",
    'postman-token': "8d3ec8ee-784e-3a65-5240-cf1a9534d1c4"
    }

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

print(response.text)

Executing this code in Python, it gives the correct response.

Note that the params=querystring part in the postman code is taken care of in the URL in my code.

I'm confused by the payload in the postman code. It adds things like Content-Disposition and name in the string. I assume that I can put this stuff in the tuple in the files parameter but I'm not sure how to to do it. I've tried files={'xml':('data.xml',result,'form-data')} for example and also files={'xml':('data.csv',result)} and {'xml':('xml',result)}.

Also, the postman code explicitly defines the header as

 'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"

whereas the requests documentation say that I should never explicitly define the headers in that way. However the postman code works and my code does not.

Any suggestions?

1条回答
smile是对你的礼貌
2楼-- · 2019-08-13 18:57

I don't know if this is worth answering or if I should delete the question but what was needed was to name the file "xml" not xml. so this works:

requests.post(callpro_url,
              files={'xml':('"xml"',result)},
              verify=False).text
查看更多
登录 后发表回答