sending a handmade SOAP request

Van Gale vangale at gmail.com
Thu Jan 31 15:23:51 EST 2008


On Thu, 31 Jan 2008 11:03:26 -0800, Bernard wrote:

> Hey y'all,
> 
> Is there a way to POST a handmade SOAP request *without* using any
> libraries like SOAPpy?

Yes, it's quite easy to SOAP by hand.

I use Oren Tirosh's ElementBuilder class (on top of lxml instead of 
ElementTree) to build the SOAP request and the xpath capabilities in lxml 
to pull out the data I need from the response.

http://www.tothink.com/python/ElementBuilder/
http://codespeak.net/lxml/

An incomplete example for contructing a request looks something like this:

body = Element('soap:Envelope',
         { 'xmlns:soap': nss['soap']},
         Element('soap:Header'), Element('soap:Body',
           { 'xmlns:msgs': nss['msgs'] },
           Element('msgs:login',
             Element('msgs:passport',
               { 'xmlns:core': nss['core'] },
                 Element('core:password', password),
                 Element('core:account', account)))))

I use httplib2 for sending the HTTP requests:

http://code.google.com/p/httplib2/

Incomplete example:

headers['SOAPAction'] = action
headers['Content-length'] = str(len(etree.tostring(body)))
response, content = self._client.request(
   self.ns_uri, "POST",
   body=etree.tostring(body), headers=self._headers)
if response.status == 500 and not \
    (response["content-type"].startswith("text/xml") and \
    len(content) > 0):
        raise HTTPError(response.status, content)
if response.status not in (200, 500):
    raise HTTPError(response.status, content)
doc = etree.parse(StringIO(content))
if response.status == 500:
    faultstring = doc.findtext(".//faultstring")
    raise HTTPError(response.status, faultstring)

Now it's just a matter of using xpath expressions to dig into the "doc" 
structure for the bits you need.



More information about the Python-list mailing list