In this serie of section, you will find several interoperability examples using two important SOAP libraries for Python: SOAPpy and ZSI, to consume Java WSDP or .NET web services.
Let's start using SOAPpy, it's a very easy and relatively powerfull maen to consume a web service from Python. I assume here you have a recent Python install plus all the required packages installed for the use of SOAPpy: fpconst and PyXML. To test your PyXML install, type the following code in your Python command-line:
>>> import xml >>>
If you don't have any error message, your package PyXML is correctly installed. Do the same check with fpconst:
>>> import fpconst >>>
And finally with SOAPpy:
>>> import SOAPpy >>>
If you encounter any error, just install the package needed.
To make a SOAP client for a Java WSDP web service, with SOAPpy, you need to call the remote procedure and specify explicitely the parameter names. Let's see how to do that for my web service:
Once again, you will easily add the other simple call: readLSpercent() (returning the value of the light sensor, in percent, of my brick) and readTemp() (returning the temperature).
# the name of the parameter 'int_1' must be the same than # the one you will find in the wsdl print 'Light sensor value: ' + server._ns(namespace).readLSpercent(int_1 = "1") print 'Temperature sensor value: ' + server._ns(namespace).readTemp(int_1 = "1")
And that's all for the calls returning simple type, next section we will see how to handle complex types returned by the web service.
We just use the same template here, each call use the function _ns(), allowing to specify the namespace for the remote procedure (like in the wsdl). If you need to send a complex type as a parameter, shift to the section which explain how to consume a .NET web service using python.
# we start with the status() procedure, which return # the object rcxResponse containing some internal # values of my RCX brick. rcxResponse = server._ns(namespace).status() print 'Rcx message: '.ljust(20) , rcxResponse.status + \ '\nBattery level: '.ljust(20) , rcxResponse.battery + \ '\nInternal clock: '.ljust(20) , rcxResponse.currentTime + \ '\nMemory free: '.ljust(20) , rcxResponse.memory # the function collInt() (returning an array of integer) intarray = server._ns(namespace).collInt() print 'Remote procedure collInt() returning an array of integer:' for val in intarray : print val.rjust(5) # the function collPos() (returning an array of PosCol object PosColArray = server._ns(namespace).collPos() print 'Remote procedure collPos() returning an array of PosCol object:' for pc in PosColArray : print '[XPos]: '.ljust(10) + pc.XPos , '[YPos]: '.ljust(10) + pc.YPos
So we see how it is simple to use. The most important things are specify the namespace and the parameter name accordingly to the wsdl. With more experience, you will soon be able to easily find these info in any wsdl. And if you begin, just make a client with a well known tool and catch the SOAP message exchanged between your client and the web service you consume (eg: TcpTunnelGui). Knowing exactly the format of the SOAP message you have to send, it is easier to reproduce it in another language/platform and with other tools.
You can use the WSDL class to parse a WSDL and list, for you, all the methods available. And sometimes even the parameter name and type, took and returned by the methods. Test this code on a web service of your choice:
Example 4-2. How to parse a wsdl with SOAPpy.
from SOAPpy import WSDL
url = 'http://www.pascalbotte.be/rcx-ws/rcx'
# just use the path to the wsdl of your choice
wsdlObject = WSDL.Proxy(url + '?WSDL')
print 'Available methods:'
for method in wsdlObject.methods.keys() :
print method
ci = wsdlObject.methods[method]
# you can also use ci.inparams
for param in ci.outparams :
# list of the function and type
# depending of the wsdl...
print param.name.ljust(20) , param.type
print
In the case of my web service, there is one method taking an object as param (and returning the same object): the method RcxQuery queryRcx(RcxQuery obj). The RcxQuery object contain two simple integer variable: "x" and "y". When trying to consume this method with Python and SOAPpy, I could not order the two variables (x and y) of the class RcxQuery in the SOAP message created by SOAPpy. Because of that I faced a serialize exception throwed by my web service: SOAPpy was not able to send the variable "x" in first position, followed by the variable "y".
Due to this limitation, we can't cover the case of a SOAPpy, Python client for the Infobel web service (.NET). So when designing a web service, if you want to avoid the loss of all the potential Python SOAPpy developer and client, do not expose procedure taking object as parameter ;-).
![]() | ![]() | ![]() |
| Perl XML HTTP Post to a web service. | ![]() My home page Index RSS | Python XML HTTP Post to send a SOAP message to a JWSDP or to a .NET web service. |