Working with Web Services is not an easy task. We must know about XML, WSDL and some other technologies and also the framework that we are using. In this article I will try to demonstrate how easy is the task of sending objects through Web Services. First of all I’m using SOAPpy as my Web Services framework and the second element in the recipe is pyxser my Python-Object to XML serializer and deserializer.
A single web service that should receive an XML string, now can convert that input into a Python Object. Let’s see the server code under SOAPpy framework ;)
#!/usr/bin/env python # # import pyxser as ser from testpkg.sample import * import SOAPpy def hello(request): ### so we take the input string as xml and we deserialize it req = ser.unserialize(obj = request, enc = "ascii") ### we create a response object reqo = TestAnotherObject() ### we assign equal .first_element properties reqo.first_element = req.first_element ### we set a custom .second_element property reqo.second_element = "client" ### we serialize the response object rep = ser.serialize(obj = reqo, enc = "ascii", depth = 0) ### we return back the response object as xml string return rep ### create the server server = SOAPpy.Server.SOAPServer(("localhost", 8888)) ### register the hello function server.registerFunction(hello) print "Starting server..." ### and let server run... server.serve_forever()
The code above show a single server with one operation hello(). The pyxser serializer can not serialize/deserialize classes declared in the __main__ module. So we declare a class in an external module testpkg.sample with the code bellow.
__all__ = [ 'TestAnotherObject'] class TestAnotherObject: first_element = "123" second_element = "456" def __str__(self): return repr(self.__dict__) def __repr__(self): return repr(self.__dict__)
This module contains our serialization target data transfer object. Now, at the client side, we have a complete support to send and receive objects using pyxser ;).
#!/usr/bin/env python # # # import pyxser as ser import sys, httplib from testpkg.sample import * import SOAPpy HELLOWS_NS = "http://localhost/hellows/" def GetHello(): ### we create a request object reqo = TestAnotherObject() ### we set the object properties as we need reqo.first_element = "client" reqo.second_element = "server" ### we serialize the object using pyxser hstr = ser.serialize(obj = reqo, enc = "ascii", depth = 0) ### we create a SOAP proxy to our server server = SOAPpy.SOAPProxy("http://localhost:8888/") ### we call the server method and we get the xml string resp = server.hello(hstr) ### we convert the response xml into a python object and ### return it! return ser.unserialize(obj = resp, enc = "ascii") if __name__ == "__main__": ### then we can manipulate the object easily newobj = GetHello() print newobj.first_element[0:2]
We can do more expertize work with pyxser. You can try using WSDL, and importing the complete pyxser 1.0 XML Schema as follows…
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/Hello/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pyxs="http://projects.coder.cl/pyxser/model/" name="Hello" targetNamespace="http://www.example.org/Hello/"> <wsdl:types> <xsd:schema targetNamespace="http://www.example.org/Hello/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.example.org/Hello/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pyxs="http://projects.coder.cl/pyxser/model/"> <xsd:import namespace="http://projects.coder.cl/pyxser/model/" schemaLocation="pyxser-1.0.xsd" /> <xsd:element name="obj" /> </xsd:schema> </wsdl:types> <wsdl:message name="HelloRequest"> <wsdl:part element="tns:obj" name="request" /> </wsdl:message> <wsdl:message name="HelloResponse"> <wsdl:part element="tns:obj" name="response" /> </wsdl:message> <wsdl:portType name="Hello"> <wsdl:operation name="Hello"> <wsdl:input message="tns:HelloRequest" /> <wsdl:output message="tns:HelloResponse" /> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloSOAP" type="tns:Hello"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name="Hello"> <soap:operation soapAction="http://www.example.org/Hello/Hello" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Hello"> <wsdl:port binding="tns:HelloSOAP" name="HelloSOAP"> <soap:address location="http://www.example.org/" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
So we can use integrate our Python web services by calling with other platforms and let the other platforms know the pyxser serialization model to allow us to develop more complex Web Services…
Certainly the pyxser package comes with with both standard and C14N XML schemas, and both standard and C14N XML DTDs — or document type definitions — so you can use them in your Web Services development.