Skip to main content

If you don't have an IBM ID and password, register here.

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. This profile includes the first name, last name, and display name you identified when you registered with developerWorks. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

The Python web services developer: Python SOAP libraries, Part 4

New developments for ZSI

Scott Archer, Software Architect, GlowingOrb, Inc.
Scott Archer is a software architect and co-founder of GlowingOrb, Inc., a software tools developer focusing on model-driven solutions and their integration into core business processes. Mr. Archer holds an M.Phil in Computational Molecular Biology from the University of Hong Kong. You can contact Mr. Archer at scott.archer at glowingorb.com.
Uche Ogbuji (uche@ogbuji.net), Principal Consultant, Fourthought, Inc.
Uche Ogbuji is a consultant and co-founder of Fourthought Inc., a software vendor and consultancy specializing in XML solutions for enterprise knowledge management applications. Fourthought develops 4Suite, open source platforms for XML middleware. Mr. Ogbuji is a Computer Engineer and writer born in Nigeria, living and working in Boulder, Colorado, USA. You can contact Mr. Ogbuji at uche@ogbuji.net.

Summary:  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.

Date:  30 Dec 2003
Level:  Introductory

Comments:  

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 http://wavendon.dsdata.co.uk:8080/axis/services/SBGGetAirFareQuote?wsdl. 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 = 'http://wavendon.dsdata.co.uk:8080\
... /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/ServiceProxy.py", line 82, in __call__
    return self.parent()._call(self.__name__, *args, **kwargs)
  File "/usr/lib/python2.2/site-packages/ZSI/ServiceProxy.py", line 65, in _call
    apply(getattr(binding, callinfo.methodName), args)
  File "/usr/lib/python2.2/site-packages/ZSI/client.py", line 28, in __call__
    requesttypecode=TC.Any(self.name, aslist=1))
  File "/usr/lib/python2.2/site-packages/ZSI/client.py", line 131, in RPC
    self.Send(url, opname, obj, **kw)
  File "/usr/lib/python2.2/site-packages/ZSI/client.py", line 169, in Send
    sw.serialize(obj, tc, typed=0)
  File "/usr/lib/python2.2/site-packages/ZSI/writer.py", line 73, in serialize
    typecode.serialize(self, pyobj, **kw)
  File "/usr/lib/python2.2/site-packages/ZSI/TC.py", line 282, in serialize
    Any().serialize(sw, val)
  File "/usr/lib/python2.2/site-packages/ZSI/TC.py", 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.


wsdl2py

ZSI also now comes with a script, wsdl2py, which is undocumented as far as we can tell, but the Python source carries the doc string:

"A utility for automatically generating client interface code from a wsdl definition, and a set of classes representing element declarations and type definitions. This will produce two files in the current working directory named after the wsdl definition name."

This sounds promising, and we thought it might see the WXSDT dateTime parameters defined in the WSDL file and generate all the magic we needed to marshall these values from Python. The script can't handle WSDL URLs, so we had to download the definition to a local file. Here is an example of how to use the wget command on UNIX:

wget -O SBGGetAirFareQuote.wsdl \
http://wavendon.dsdata.co.uk:8080/axis/services/SBGGetAirFareQuote?wsdl

Unfortunately, we didn't get very far with the wsdl2py script, as the following listing shows:

wsdl2py -f SBGGetAirFareQuote.wsdl

Traceback (most recent call last):

  ... Part of traceback omitted for brevity ...

  File "/usr/lib/python2.2/site-packages/ZSI/wsdl2python.py", line 1058, 
  in _fromComplexType
    self._complexTypeComplexContent(tp)
  File "/usr/lib/python2.2/site-packages/ZSI/wsdl2python.py", line 1147, 
  in _complexTypeComplexContent
    arrayinfo = dt.getArrayType()
  File "/usr/lib/python2.2/site-packages/ZSI/wsdlInterface.py", line 1712, 
  in getArrayType
    raise WsdlInterfaceError, 'could not determine array type'
ZSI.wsdlInterface.WsdlInterfaceError: could not determine array type

It appears the script cannot handle the array of complex types in the search return structure for the getAirFareQuote operation, as represented in the WSDL types section:

      <complexType name="ArrayOfAirFareQuote">
        <complexContent>
          <restriction base="soapenc:Array">
            <attribute wsdl:arrayType="impl:AirFareQuote[]" ref=
            "soapenc:arrayType"/>
          </restriction>
        </complexContent>
      </complexType>
      <element nillable="true" type="impl:ArrayOfAirFareQuote" name=
      "ArrayOfAirFareQuote"/>
      <complexType name="ArrayOf_xsd_string">
        <complexContent>
          <restriction base="soapenc:Array">
            <attribute wsdl:arrayType="xsd:string[]" ref=
            "soapenc:arrayType"/>
          </restriction>
        </complexContent>
      </complexType>
      <element nillable="true" type="impl:ArrayOf_xsd_string" name=
      "ArrayOf_xsd_string"/>

To be fair to ZSI, WSDL array types are perhaps the most notable exemplar of everything that is poor about encoding RPC payloads in XML, but that's a topic for another article. After commenting out the above type definitions -- and replacing them in the WSDL with dummy WXSDT string types -- wsdl2py succeeded in producing two modules packed with impressive-looking code. Unfortunately squinting at all this code didn't shed much light into how to properly marshall the input date parameters, so we sadly called it a defeat. To be sure we weren't completely off the rails, we asked one of the ZSI developers about the trouble marshalling date types. His response indicates that it probably is indeed a bug in ZSI, but it is also likely to be fixed soon. If we learn more about this problem we'll make sure it's posted to the forum for this column (see Resources).


A wrapper for ZSI and a wrap-up

At least one developer trying to use ZSI has decided that there has to be an easier way to take advantage of the richness underlying ZSI's difficult interface. OSE is a framework for distributed and web-based applications which offers SOAP support, building on ZSI. Part of OSE is the zsirpc package which provides a more friendly wrapper for ZSI, although it only handles web services that are encoded in similar fashion to XML-RPC. Most usefully, it provides straightforward wrappers for passing boolean, binary (encoded as BASE64), date, dateTime, time and duration types, which ZSI supports, but as we have learned, only with a lot of extra work by the programmer writing specialized structures.

We hope that some of the code from zsirpc makes it into ZSI itself. This would make life a lot easier for developers of RPC-style web services. Then again, perhaps it is better to continue to encourage developers towards the document-literal style of web services. We have long been advocates of such style and it is good to see that the mainstream of web services finally tend in this direction. It will finally allow developers to express messages in terms of the dynamics of XML itself, rather than bewildering layers of conventions to try to extend a single data model for communications across platforms and languages.

ZSI isn't the only Python web services library to go through significant development. SOAPpy is also in active development, and WSDL is also a large part of this work. We shall have a look at what's new in SOAPpy in the near future.


Resources

About the authors

Scott Archer is a software architect and co-founder of GlowingOrb, Inc., a software tools developer focusing on model-driven solutions and their integration into core business processes. Mr. Archer holds an M.Phil in Computational Molecular Biology from the University of Hong Kong. You can contact Mr. Archer at scott.archer at glowingorb.com.

Uche Ogbuji

Uche Ogbuji is a consultant and co-founder of Fourthought Inc., a software vendor and consultancy specializing in XML solutions for enterprise knowledge management applications. Fourthought develops 4Suite, open source platforms for XML middleware. Mr. Ogbuji is a Computer Engineer and writer born in Nigeria, living and working in Boulder, Colorado, USA. You can contact Mr. Ogbuji at uche@ogbuji.net.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in

If you don't have an IBM ID and password, register here.


Forgot your IBM ID?


Forgot your password?
Change your password


By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. This profile includes the first name, last name, and display name you identified when you registered with developerWorks. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)


By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=SOA and web services
ArticleID=11866
ArticleTitle=The Python web services developer: Python SOAP libraries, Part 4
publish-date=12302003
author1-email=
author1-email-cc=
author2-email=uche@ogbuji.net
author2-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).