tags:

views:

491

answers:

1

Hi all,

I am trying to write a Python consumer for Sage CRM using their Web Services interface. I am using SOAPpy as Python SOAP library (not married to it, was easy to install on Ubuntu so went with it).

Managed to fetch the WSDL using the Proxy and executed the logon method exposed by Sage CRM.


from SOAPpy import *
proxy = WSDL.Proxy('http://192.168.0.3/MATE/eware.dll/webservice/webservice.wsdl')
It returns a session object which sort of looks like
SOAPpy.Types.structType result at 151924492: {'sessionid': '170911104429792'}

Now I am trying to use Sage CRM's queryrecord method to query the data, and that returns

Fault SOAP-ENV:Server: No active usersession detected

Reading the documentation reveals that I have to send back to the session id that recd. when I logged in back with each requests.

According to the Sage documentation I have to send it back as such


SID = binding.logon("admin", ""); 
binding.SessionHeaderValue = new SessionHeader(); 
binding.SessionHeaderValue.sessionId = SID.sessionid;

Any ideas how to do append this to the headers using SOAPpy?

Any pointers will be greatly appreciated.

A: 

First, just to comment on SOAPpy vs. other soap libraries... SOAPpy traditionally has been the easy-to-use library that didn't support complex data structures. So if it works for your case then you are better off. For more complex data structures in the WSDL you'd need to move ZSI.

Anyway, the documentation link for the project on SourceForge seems to be broken, so I'll just cut+paste the header documentation here with some minor formatting changes:

Using Headers

SOAPpy has a Header class to hold data for the header of a SOAP message. Each Header instance has methods to set/get the MustUnderstand attribute, and methods to set/get the Actor attribute.

SOAPpy also has a SOAPContext class so that each server method can be implemented in such a way that it gets the context of the connecting client. This includes both common SOAP information and connection information (see below for an example).

Client Examples

import SOAPpy
test = 42
server = SOAPpy.SOAPProxy("http://localhost:8888")
server = server._sa ("urn:soapinterop")

hd = SOAPpy.Header()
hd.InteropTestHeader ='This should fault, as you don\'t understand the header.'
hd._setMustUnderstand ('InteropTestHeader', 0)
hd._setActor ('InteropTestHeader','http://schemas.xmlsoap.org/soap/actor/next')
server = server._hd (hd)

print server.echoInteger (test)

This should succeed (provided the server has defined echoInteger), as it builds a valid header into this client with MustUnderstand set to 0 and then sends the SOAP with this header.

import SOAPpy
test = 42
server = SOAPpy.SOAPProxy("http://localhost:8888")
server = server._sa ("urn:soapinterop")
#Header
hd = SOAPpy.Header()
hd.InteropTestHeader = 'This should fault,as you don\'t understand the header.'
hd._setMustUnderstand ('InteropTestHeader', 1)
hd._setActor ('InteropTestHeader','http://schemas.xmlsoap.org/soap/actor/next')
server = server._hd (hd)

print server.echoInteger (test)

This should fail (even if the server has defined 'echoInteger'), as it builds a valid header into this client, but sets MustUnderstand to 1 for a message that the server presumably won't understand before sending.

Van Gale
Appreciate your response Van.Which version of SOAPpy does SOAPpy.Header ship with? My Ubuntu (Hardy) machine distributes 0.12.0-2 and doesn't seem to have SOAPpy.Header.I did find some documentation regarding SOAPpy.Header during my Google around and was at a loss when the I couldn't find it in the package.Do I have to fetch SOAPpy from SVN?
Devraj
Hi Devraj, it looks like 0.12.0 is the latest packaged version, so that means you'll need to get it from SVN at http://pywebsvcs.svn.sourceforge.net/viewvc/pywebsvcs/trunk/SOAPpy/
Van Gale