Sending SOAP request using Python Requests Sending SOAP request using Python Requests python python

Sending SOAP request using Python Requests


It is indeed possible.

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

import requestsurl="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, PackageLoaderenv = 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 you're dealing with an institution that still uses SOAP ;) ).

You can do the above with suds like so:

from suds.client import Clienturl="http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL"client = Client(url)print client ## shows the details of this serviceresult = 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: