Importing a SOAP client object to be used by python scripts
Loading external data is a topic frequently seen in Plone, as with any CMS. One way to accomplish this is with SOAP, if your data sources support it. With these tools, you can also use Plone to view, and even manage content in a heterogeneous platform.
You should be careful of the performance issues relating to any request relying on external systems. It would not be realistic to expect a fast response from Amazon for every visitor to your site!
Getting ZSI
There are several Python SOAP implementations and two of the most well-know are SOAPpy and ZSI . You will need ZSI installed to follow this example but before you do so, see the section below titled Altering the Offending Code.
WSDL2PY
ZSI includes a handy tool, WSDL2PY which generates types and interface code from a WSDL. For more info on WSDL2PY see OpenSourceTutorials.com Python SOAP libraries, Part 4, page 2 .
Connecting to Amazon
Amazon offers web services implementations for developers and can be had from Amazon Web Services .
To subscribe to their service, you need to register as a deveoper and be granted a Subscription ID AKA Developer Token AKA Developer Tag.
As of this writing, WSDL2PY was not compatible with Amazon E-Commerce Service (ECS) version 4.0, so I reverted to version 3.0. Finally here's the WSDL for version 3.0
Generating Python Code
To Generate their code:
wsdl2py -f <wsdl file>
Modifying the generated code for use with restricted python and ZPT
To use a generated class, you will need to have the objects inherit from, at minimum, Acquisition.Explicit or Acquisition.Implicit. I was lazy, and inherited from OFS.SimpleItem. The object that I wanted to use in ZPT was Amazon's Details_Def, found in the generated AmazonSearch_services_types.py. import SimpleItem and Change:
class Details_Def(ZSI.TCcompound.Struct)
To:
class Details_Def(ZSI.TCcompound.Struct, SimpleItem)
Next, in all generated files, Change every instance of:
.__init__(...)
to:
.__dict__['__init__'](...)
That's easy. Is that it?
Well it should be. Unfortunately, as of this writing there exists an inheritance problem with ZSI which will not allow you to also inherit from an Acquisition class. If you haven't installed ZSI yet, you might as well make the following adjustments before you install.
Altering the Offending Code
In ZSI-1.6.0, the offending code should have been installed by ZSI in python/site_packages/ZSI/TCcompound.py. You will need to alter the typechecking to also check for extension classes. This is beyond my python skills so I simply commented out the following lines:
TCcompound.py:63
if TypeCode.typechecks:
if self.pyclass is not None and type(self.pyclass) != types.ClassType:
raise TypeError('pyclass must be None or a class, not ' +
str(type(self.pyclass)))
_check_typecode_list(self.ofwhat, 'Struct')
TCcompound.py:272
if t != types.InstanceType:
raise TypeError(
'Array ofwhat must be an instance, not ' + str(t))
Using Generated Code in a Tool
Using the generated code is relatively easy. Creating a tool lets you query the service and manipulate the reqults as needed. Add the :
from Products.CMFCore.utils import getToolByName, UniqueObject
from Globals import InitializeClass
from OFS.SimpleItem import SimpleItem
from AmazonSearch_services import *
import AmazonSearch_services_types
class AmazonClass
def extractByKeyword(zope,KEYWORD,mode,offset):
tracefile=open('path/to/logfile','w')
tracefile.write('Starting log session\n')
kw = { 'tracefile' : tracefile }
loc = AmazonSearchServiceLocator()
porttype = loc.getAmazonSearchPort(**kw)
keyword = ns1.KeywordRequest_Def()
keyword._type='heavy'
keyword._keyword=KEYWORD
keyword._mode=mode
keyword._page=offset
keyword._devtag=<your developer id>
keyword._tag=<your developer id>
request=KeywordSearchRequestWrapper()
request._KeywordSearchRequest=keyword
response = porttype.KeywordSearchRequest(request)
details = response._return._Details
dli = []
for detail in details:
detail.manage_permission(CMFCorePermissions.View, ('Anonymous','Manager','Mod','Owner'), 0)
dli.append(detail.__of__(zope))
return dli

Author: