Python SOAP Options

Support for web services in Python is emerging, but is not complete. At the time of this writing, there is lively debate in the XML-SIG (Python XML Special Interest Group; see http://www.python.org/sigs/xml-sig/) concerning SOAP client and server implementations and their ability to interoperate.

SOAP and WSDL, and therefore web services, are being driven largely by companies such as IBM and Microsoft. Microsoft has robust client and server support for web services in their SOAP Toolkit, while IBM is making headway contributing to the Apache SOAP project. Both camps feature support for two common styles of web service access: RPC-like proxy access, and SOAP Serialization access.

You can implement Python web service clients easily today by using one of Python’s bridge mechanisms into subsystems such as COM and Java. Python’s COM support is excellent and is enabled by installing PythonCOM (part of the win32all.exe package from the ActiveState web site). Detailed instructions are provided in Section 9.4.1 later in this chapter.

Through the accepted APIs of web services today, you’ll likely be able to quickly adapt your Python code to use native Python web service support when it matures, although it may be more desirable to write your logic in Python but utilize APIs from Python that are implemented in faster C++. Python makes a great glue language due to its robust object model, sophisticated text and file manipulation, and component access. Utilizing components that are resource intensive (such as Parsers or SOAP clients) may work better if the components are written in fast native code and are driven by your Python code.

With one cross-platform exception, the Python client examples in this chapter rely primarily on using COM to bridge Microsoft’s mature SOAP Serializer and SOAP Connector. Therefore, the Python examples in this section primarily run on Windows platforms, due to their utilization of COM. However, the SOAPy API is covered as well. This is a native Python RPC-like SOAP client implementation. SOAPy should run anywhere Python runs.

Working with SOAPy

As of this writing, SOAPy provides support for RPC-like interaction with WSDL-published web services. SOAPy is currently available on SourceForge (http://soapy.sourceforge.net). SOAPy is inherently cross-platform because it is a native Python implementation.

Working with SOAPy is very simple, as it’s designed to transparently present a remote web service as if it were a local Python object. If you download one of the source distributions of SOAPy, you get a few examples that allow SOAPy to strut its stuff. For instance, the get_temperature example that ships with SOAPy allows you to enter a zip code and query a remote weather service for the current temperature. So, to check the temperature in Woodinville, Washington:

C:c9>python get_temperature.py 98072
Temperature for 98072 = 53.0 degrees F

While this application is impressive, it immediately inspires curiosity as to how SOAPy works. SOAPy performs this trick in three lines of code:

import soap
server = soap.get_proxy('http://www.xmethods.net/sd/TemperatureService.wsdl')

temperature = server.getTemp(zipcode=zip)

The secret is that SOAPy interprets the WSDL file, and creates a local stub object for you to work with that seemingly has all of the methods of the remote service.

Ideally, when working with SOAPy, the only method you call is get_proxy. Afterwards, you should be able to use the methods described in the WSDL file located at the remote service.

Working with MSSOAP

When working with MSSOAP, you have the option of using an RPC client or a Serialization client.

The RPC client works essentially the same way that SOAPy does; however, there are some subtle differences. For example, to initialize a connection with remote service description, use the mssoapinit method as opposed to SOAPy’s get_proxy, but the net effect is the same as shown here:

import win32com.client

sc = win32com.client.Dispatch("MSSOAP.SoapClient")
sc.mssoapinit("http://WebServiceDomain/service.wsdl")

response = sc.methodName(param, param)

print(response)

Again, the net effect of web service RPC implementations is to allow you to work with a remote object as if it were local. The Serialization method works slightly differently, but gives you finer control over how an actual SOAP request is structured, and allows you to work with a service without necessarily relying upon a service description WSDL file.

MSSOAP Serialization Basics

Using serialization is more involved than using RPC, but it has its own advantages as well as drawbacks. Serialization gives you fine control over exactly how a SOAP XML request appears. Implementing serialization also allows you to interact with a web service without having to understand WSDL, something that may be of considerable value as SOAP implementations (both client and server) mature.

The main trade-off between RPC and Serialization is the WSDL file. The WSDL file provides an RPC implementation with the information it needs about the service end-point, such as the URIs and namespaces involved, or the parameters and their types. Without RPC and WSDL, you’d need to supply these extra details manually.

Adding URIs and namespaces

Creating a SOAP packet with MSSOAP requires a few objects, but start with the connector and the serializer. You must give the connector information that is normally held in a WSDL file. For example, you need to supply the end-point, the SOAP Action URI, and the namespace:

import win32com.client

SoapActionUri = "http://tempuri.org/action/Calc.Add"
ElementNamespace = "http://tempuri.org/message/"
EndPointUrl = "http://centauri/MSSoapSamples/Calc/Service/SrSz/AspVbs/Calc.asp"

connector = win32com.client.Dispatch("MSSOAP.HttpConnector")
connector.SetProperty("EndPointURL", EndPointUrl)
connector.SetProperty("SoapAction", SoapActionUri)
connector.BeginMessage(  )

The connector is now prepared to connect to the service. All that is left to do is to prepare the SOAP envelope and execute the call. The SOAP envelope is also prepared manually.

serializer = win32com.client.Dispatch("MSSOAP.SoapSerializer")
serializer.Init(connector.InputStream)

Once the serializer is created, it is attached to the connector for writing to the service.

Creating the SOAP envelope

You use the serializer’s methods to actually construct the SOAP packet, including the method you are targeting, as well as to supply the parameters. The following lines prepare a SOAP packet for delivery to a calculator service expecting that parameters A and B are integer parameters to a method named Add:

# Create SOAP Envelope
serializer.startEnvelope(  )
serializer.startBody(  )
serializer.startElement("Add", ElementNamespace, '', "m")
serializer.startElement("A")
serializer.writeString("4")
serializer.endElement(  )
serializer.startElement("B")
serializer.writeString("5")
serializer.endElement(  )
serializer.endElement(  )
serializer.endBody(  )
serializer.endEnvelope(  )

# Finish SOAP message
connector.EndMessage(  )

As shown in the previous code, the connector is then instructed that the complete SOAP message has been prepared with a call to EndMessage.

Making the call

After you’ve completed constructing your serializer and connector, a final step is to instantiate a reader object to check for errors with the service and to retrieve the result of the call.

reader = win32com.client.Dispatch("MSSOAP.SoapReader")
reader.Load(connector.OutputStream)

Here, the reader is associated with the connector’s output stream in order to retrieve the result of the call to the service. The Fault attribute of the reader indicates success or failure.

if reader.Fault:
  print("Error: ", reader.faultstring.Text)

print reader.RPCResult.Text

The response from the service is contained in the reader.RPCResult object. In this particular case, the response from the calculator service is “9,” and the sum of the supplied parameters is 4 and 5.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.223.10