simple SOAP client using Suds
Yet another way of enabling SOAP calls from your Plone code.
Why would you want another way? Well, for one, the Suds way of doing SOAP calls is very elegant, needs very few lines of code, and uses the WSDL of the service for introspection and definitions, so as to save you from doing that. Also, the Suds library is well documented, and seems more lively than alternatives, like ZSI/SOAPpy. Enough reasons, I'd say.
The use case
Many websites out there offer webservices using SOAP. For integrating those services into your Plone site, you'll need to be able to do a SOAP call, or in other words, you'll need a SOAP client.
Setup
Add suds to either your global libraries, or to your buildout config file. I assume you know how to do this...
The code
Time to do some coding. We assume that we have a specific SOAP service, that has provided a WSDL file for introspection. Most, if not all serious SOAP services will be defined with an on-line WSD. We'll take the same service (Amazon) that is used in Importing a SOAP client object to be used by python scripts, so as to provide a clear comparison between suds and ZSI.
import suds
from suds.xsd.doctor import ImportDoctor, Import
WSDL_URL = "http://soap.amazon.com/schemas3/AmazonWebServices.wsdl"
class AmazonClient(object):
def __init__(self):
self._v_client = None
def getClient(self):
if not self._v_client:
# Fix import for parsing this WSDL
imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
d = ImportDoctor(imp)
self._v_client = suds.client.Client(WSDL_URL, doctor=d)
return self._v_client
def extractByKeyword(self, keyword, mode, offset):
""" fetch the calendar given the data provided by the user """
client = self.getClient()
req = client.factory.create("KeywordRequest")
req.type='heavy'
req.keyword=keyword
req.mode=mode
req.page=offset
req.devtag='<your developer id>'
req.tag='<your developer id>'
return client.service.KeywordSearchRequest(req)
The relevant code for the actual request is in the definition of the extractByKeyword method. The code in the getClient method is more or less equivalent in function to the wsdl2py script, in that is sets up the client types, based on the WSDL. Note the fix for an import problem in suds...
In the extractByKeyword method, you can see how to create complex parameters, using the factory.create method of the client (that holds all WSDL definitions). The client that is returned from the getClient method can be printed, and provides a nice overview of the inspected WSDL. This is easiest done on the command line, like so:
>>> import suds
>>> from suds.xsd.doctor import ImportDoctor, Import
>>> imp = Import('http://schemas.xmlsoap.org/soap/encoding/')
>>> d = ImportDoctor(imp)
>>> url = "http://soap.amazon.com/schemas2/AmazonWebServices.wsdl"
>>> client = suds.client.Client(url, doctor=d)
>>> print client
This will display all available services declared in the WSDL, and all type info, so that you may know what type of parameters to create for what requests. The response object can similarly be printed from the command line, showing what is returned.

Author: