Sending SOAP request using Python Requests

Sending SOAP request using Python Requests

It is indeed possible.

Here is an example calling the Weather SOAP Service using plain requests lib:

import requests
url=http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL
#headers = {content-type: application/soap+xml}
headers = {content-type: text/xml}
body = <?xml version=1.0 encoding=UTF-8?>
         <SOAP-ENV:Envelope xmlns_ns0=http://ws.cdyne.com/WeatherWS/ xmlns_ns1=http://schemas.xmlsoap.org/soap/envelope/ 
            xmlns_xsi=http://www.w3.org/2001/XMLSchema-instance xmlns:SOAP-ENV=http://schemas.xmlsoap.org/soap/envelope/>
            <SOAP-ENV:Header/>
              <ns1:Body><ns0:GetWeatherInformation/></ns1:Body>
         </SOAP-ENV:Envelope>

response = requests.post(url,data=body,headers=headers)
print response.content

Some notes:

  • The headers are important. Most SOAP requests will not work without the correct headers. application/soap+xml is probably the more correct header to use (but the weatherservice prefers text/xml
  • This will return the response as a string of xml – you would then need to parse that xml.
  • For simplicity I have included the request as plain text. But best practise would be to store this as a template, then you can load it using jinja2 (for example) – and also pass in variables.

For example:

from jinja2 import Environment, PackageLoader
env = Environment(loader=PackageLoader(myapp, templates))
template = env.get_template(soaprequests/WeatherSericeRequest.xml)
body = template.render()

Some people have mentioned the suds library. Suds is probably the more correct way to be interacting with SOAP, but I often find that it panics a little when you have WDSLs that are badly formed (which, TBH, is more likely than not when youre dealing with an institution that still uses SOAP 😉 ).

You can do the above with suds like so:

from suds.client import Client
url=http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL
client = Client(url)
print client ## shows the details of this service

result = client.service.GetWeatherInformation() 
print result 

Note: when using suds, you will almost always end up needing to use the doctor!

Finally, a little bonus for debugging SOAP; TCPdump is your friend. On Mac, you can run TCPdump like so:

sudo tcpdump -As 0 

This can be helpful for inspecting the requests that actually go over the wire.

The above two code snippets are also available as gists:

Sending SOAP request using Python Requests

Leave a Reply

Your email address will not be published. Required fields are marked *