Python SOAP libraries
In this first of a two-part series, Web services columnists Mike Olson and Uche Ogbuji discuss the various SOAP implementations available for Python, giving detailed code examples.
In the past 3 installments we have developed a Web services implementation using 4Suite Server, and taken advantage of the SOAP support of that product. (See Resources.) There have also been other SOAP implementations for Python; in fact, this seems to be quite a popular corner of open-source activity in Python. In this article, we shall take a look at Soap.py in action. For an update on the other open source SOAP projects, please see the sidebar. One immediate nit, though, is the naming of Python SOAP modules. It appears there hasn't been much talking between the different projects because there is a good deal of confusing similarity between the names. Recently, when explaining these choices to colleagues, we found ourselves at a loss to remember what was characteristic of SOAPy and what was characteristic of SOAP.py -- and that was after having spent a decent amount of time with both. This problem gets even worse, when one has to deal with module names within the actual libraries themselves, as we can see in the sidebar.
We covered 4Suite SOAP in the last three installments to this column; in this article and the next one, we shall present examples from the SOAP.py and SOAPy projects, which seem to have been the furthest along of this bunch at the time they became frozen. Note that although the W3C's XML protocol working group has produced a draft called SOAP 1.2, the common level of SOAP implementation across platforms and languages is still SOAP 1.1, with a strong representation of even earlier versions. The spread of SOAP versions these days causes complexity that might be greater than the simplicity promised by SOAP.
Clients and servers with SOAP.py
SOAP.py covers the basics. No Web Services Description Language (WSDL) or any other add-ons, but transparent support for implementing SOAP clients and servers in Python. Even the one nifty feature of the package relates to infrastructure: SOAP.py supports secure sockets layer (SSL), for encrypted SOAP transmissions. In order to use this feature you must have M2Crypto set up, which is a library covering a variety of cryptographic tools and formats, from RSA and DSA to HTTPs, S/MIME, and more. We shall not be examining the SSL support for SOAP.py in this installment.
4Suite SOAP is our own implementation, which we used in the last three installments of this column (see Resources for a link). It is under active development.
SOAPy was posted in April 2001, is currently in pre-alpha stages, and doesn't seem to be under active development.
SOAP.py development is frozen. SOAP.py as a project was being sponsored by a company called actzero, and actzero is no longer in business. New developers/maintainers are invited to volunteer.
soaplib' s development appears to have stalled, which is perhaps understandable given the huge body of work that Secret Labs undertakes these days. This Swedish company is led by Fredrik Lundh, famous in Python circles as the "eff-bot," and member of the Python Association board. Secret Labs also produces PythonWare, a kernel of Python and important add-on modules; PythonWorks, a leading Python IDE; the Python Imaging Library, and a host of other goodies (not least of which is the daily Python-URL Web log).
Orchard is a data management framework, basically a way to manage diverse data formats with a common interface. It implements a SOAP client as a basic way to send Orchard data items, known as Nodes, in a remote procedure call to a SOAP server.
PySOAP is a project intended as part of Dave Warner's Church-management suite, but has never released any files, and appears to be a dead project.
Start by downloading the distribution (SOAPpy 0.9.7 was the latest at the time of writing), unpacking the files, changing to the resulting directory, and copying the file SOAP.py to an apt location. Of course this "apt" is the tricky bit. Because so many of these SOAP libs use the module name "soap.py" in some combination of case, one must be careful. Of course UNIX users need only worry if the case matches exactly, but Windows users can be bitten by a clash even between "SOAP.py" and "soap.py." Orchard's SOAP.py also has a clashing name, but it properly avoids any problems because its modules are sensibly tucked away under the Orchard package.
The short of all this is that we suggest ensuring that all your Python SOAP module installations use a differentiating package name. In our case, we found a suitable directory in our PYTHONPATH and created a WebServices package in which we placed SOAP.py. Therefore, in Linux:
Note the important second command, which sets up the
__init__.py file that marks the WebServices directory as a Python package. If you ever need to bundle this code to Windows, you
might want to enter some comment into the empty file because some Windows
tools refuse to create empty files.
You're soaking in it
There are already several active registries for publically-available SOAP servers. Probably the most popular is XMethods. Of course, it's also a pretty interesting guide to the state of SOAP reality, as opposed to its hype. Most of the public Web services out there are still trinkets, and hardly worth the noise our brave new model generates, but that is another story. As it is, we shall select a public service to demonstrate and test the use of SOAP.py as a SOAP client.
Or rather, we shall try to. The very first service the authors tried, a health care provider locator, showed up the pitfalls of the current state of SOAP interoperability when it choked with the following message:
Uh oh. SOAPAction is an HTTP header which is supposed to signal the
service being accessed. It is a mandatory header in a SOAP request, but
even after setting the required header (just a pair of empty quotes), the
above error persisted. The authors found this to be the case with most MS
SOAP implementations. After trying out a bunch of these services, we
determined that Delphi implementations seem to work best with SOAP.py,
although when trying services -- even implemented in Delphi -- which
returned complex types such as lists, SOAP.py had trouble with them,
returning, say, a
WebServices.SOAP.typedArrayType instance with no
Appropriately enough, in the end, the authors chose a Web service that returns vintage curses by the Captain Haddock character in Tin Tin comics (yes, such are most Web services). Listing 1 (curse.py) is the program.Listing 1: SOAP.py program to access Curse generator SOAP service