Developer Forums | About Us | Site Map


Useful Lists

Web Host
site hosted by netplex

Online Manuals

Python SOAP libraries, Part 4
By Scott Archer and Uche Ogbuji - 2004-10-05 Page:  1 2 3

New developments for ZSI

The last time ZSI was covered in this column, it was version 1.2. ZSI has enjoyed a recent spate of activity including the contributions for other developers besides the lead Rich Salz. It is now in version 1.4.1 and has added some WSDL support. Uche Ogbuji and Scott Archer take a look at these new developments and also discover a third-party wrapper option for ZSI.

The "Web Services for Python" project, which forms an umbrella for ZSI and SOAPpy, provides the best-maintained and most usable Web services tools for Python. We have looked closely at these packages previously in this column:

Since we wrote those articles, these packages have made important improvements and added features. In this article we will look at what's new with ZSI, looking to put it to work against a more industrial strength public Web service.

A look at ZSI 1.4.1

We had a look at ZSI 1.4.1, testing it on Python 2.2.2. The most significant update in ZSI is support for WSDL. There is a new ZSI class ServiceProxy, which you initialize with the URL of a WSDL file. The documentation says it "uses a WSDL instance to send and receive messages." If you've followed our coverage of ZSI in this column you'll remember that ZSI has been an excellent library for Web services that follow certain narrow rules, but unfortunately requires a number of obscure tricks and tweaks (and more code than you might expect) to get it to handle the general case.

Certainly it seems that ZSI can handle any Web service out there. It's just that it doesn't take much variation before you find yourself writing all sorts of complex code to process structures with type codes. The root of the problem is that SOAP message structure tries to combine the traditional rigors of RPC with the flexibility of XML. One of the purposes of WSDL is to provide a structured-enough description of a service's message protocol so that it allows applications to automatically figure out things the developer would have to sort out. The addition of WSDL support to ZSI offers the promise of reducing the need for the developer to be too clever about interpreting the SOAP message. Whether the Web service uses positional parameters, named parameters, or both, and whether it uses simple, complex, or custom data types, the WSDL file should provide the needed intelligence. As such, it was with some anticipation that we tried ServiceProxy not on the sorts of toy Web services (such as the Captain Haddock curser or the simple calendar service) we have used with ZSI in the past, but rather one of the more useful public SOAP-based Web services that are finally beginning to make their appearance.

Richard Hastings' Air Fare Quote Search is implemented in Apache Axis and searches some airline Web sites in real time to find the best available flight prices for a given itinerary (see Resources). It aggregates and returns the results, sorted by price. The WSDL is at It defines two operations: getAirFareQuote and getAirlines. The former is used to execute the price search and takes 4 parameters: two W3C XML Schema Language Data Types (WXSDT) dateTime values giving the approximate start of the departure and end of the return flights and two WXSDT string values giving the three-letter airport codes between which the travel is to take place. In interactive Python, we tried the following code:

>>> from ZSI import ServiceProxy
>>> wsdl = '\
... /axis/services/SBGGetAirFareQuote?wsdl'
>>> proxy = ServiceProxy(wsdl)

The examples in the ZSI manual also show the use of a typesmodule keyword parameter to the ServiceProxy initializer but doesn't really explain this parameter properly, so we ignored it.

When dates are a real struggle

We need two date/time objects for the service invocation, and the ZSI manual says that "SOAP dates and times are Python time tuples in UTC (GMT), as documented in the Python time module." We tried the following code to see what it would cost to get us to the XML 2003 conference in Philadelphia:

>>> import time
>>> ISO_8601_DATETIME = '%Y-%m-%dT%H:%M:%S'
>>> dep = time.strptime('2003-12-06T12:30:59', ISO_8601_DATETIME)
>>> ret = time.strptime('2003-12-12T12:30:59', ISO_8601_DATETIME)
>>> proxy.getAirFareQuote(dep, ret, 'den', 'phl')

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/lib/python2.2/site-packages/ZSI/", line 82, in __call__
    return self.parent()._call(self.__name__, *args, **kwargs)
  File "/usr/lib/python2.2/site-packages/ZSI/", line 65, in _call
    apply(getattr(binding, callinfo.methodName), args)
  File "/usr/lib/python2.2/site-packages/ZSI/", line 28, in __call__
    requesttypecode=TC.Any(, aslist=1))
  File "/usr/lib/python2.2/site-packages/ZSI/", line 131, in RPC
    self.Send(url, opname, obj, **kw)
  File "/usr/lib/python2.2/site-packages/ZSI/", line 169, in Send
    sw.serialize(obj, tc, typed=0)
  File "/usr/lib/python2.2/site-packages/ZSI/", line 73, in serialize
    typecode.serialize(self, pyobj, **kw)
  File "/usr/lib/python2.2/site-packages/ZSI/", line 282, in serialize
    Any().serialize(sw, val)
  File "/usr/lib/python2.2/site-packages/ZSI/", line 315, in serialize
    raise EvaluateException('''Any can't serialize ''' + \
ZSI.EvaluateException: Any can't serialize (2003, 12, 6, 12, 30, 59, 5, 340, 0)

After a lot of vain experimentation (including with ZSI's gDateTime class), poring over the documentation, and even some Google searches on the topic we couldn't figure how to get ZSI to pass a date/time as a parameter without writing a special class for date/time objects using the gDateTime class as a type code. This seems an amazing hurdle to make a programmer jump over for such a common data type.

View Python SOAP libraries, Part 4 Discussion

Page:  1 2 3 Next Page: wsdl2py

First published by IBM developerWorks

Copyright 2004-2024 All rights reserved.
Article copyright and all rights retained by the author.