问题
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:
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
来源:https://stackoverflow.com/questions/51141881/post-a-string-as-multipart-form-data-using-requests