web developer & system programmer

coder . cl

ramblings and thoughts on programming...


easy web services with pyxser

published: 10-05-2009 / updated: 10-05-2009
posted in: programming, python, pyxser, sysadmin, tips
by Daniel Molina Wegener

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.


No coments yet.

post a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>