Python Web Services with Tornado

Riyad Parvez edited this page Oct 10, 2013 · 10 revisions

Welcome to the tornado-webservices wiki!.

This is an API for the development of soap web services using the python programming language and tornado web server. The goals of this api, is provide an simple and easy way of develop and deploy soap web service.

Prerequisites:

You need to have installed:

  1. python (version 2.6 or later, it's not has tested with python 3) (http://www.python.org/download/).
  2. tornado web server 2.1.1 (https://github.com/facebook/tornado/downloads/tornado-2.1.1.tar.gz).

Installing tornado-webservices:

Step 1:

Download the last version from https://github.com/rancavil/tornado-webservices/downloads

Step 2:

In a directory decompress the file (.zip or tar.gz).

On Linux:

$ tar zxvf tornadows-x.y.z.tar.gz
$ cd tornadows-x.y.z/ 
$ python setup.py build 
$ sudo python setup.py install

On Windows:

Decompress the zip file with WinRAR, WinZip or similar.

C:\> cd tornadows-x.y.z
C:\tornadows-x.y.z\> python setup.py build
C:\tornadows-x.y.z\> python setup.py install

A First Web Service (a little bit more complex than "Hello World!"):

Step 1:

For test the demos and examples, I recommend use of SoapUI and python-suds.

SoapUI, can be download from http://www.soapui.org or http://www.eviware.com/Download-soapUI/download-older-versions.html (i am using version 3.5.1).

python-suds, can be download from https://fedorahosted.org/releases/s/u/suds/python-suds-0.3.7.tar.gz.

Step 2:

A first example: We will created a service that generate and return a xml document that represent a birth certificate.

Create a file CertService.py

Write the next code:

   import tornado.ioloop
   from tornadows import soaphandler, webservices, complextypes
   from tornadows.soaphandler import webservice
   import datetime

   """ This class represent a xml document with the request of birth certificate """
   class InputRequest(complextypes.ComplexType):
       idperson = str

   """ This class represent the birth certificate (the xml document with the response) """
   class CertificateResponse(complextypes.ComplexType):
       numcert = int
       idperson = str
       nameperson = str
       birthday = datetime.date
       datetimecert = datetime.datetime
       isvalid = bool

   """ This class is the web service that return the birth certificate """
   class CertService(soaphandler.SoapHandler):
       @webservice(_params=InputRequest, _returns=CertificateResponse)
       def getCertificate(self, input):
           idperson = input.idperson

           cert = CertificateResponse()
           cert.numcert = 1
           cert.idperson = idperson
           cert.nameperson = 'Steve J'
           cert.birthday = datetime.date(1973,12,11)
           cert.datetimecert = datetime.datetime.now()
           cert.isvalid = True

           return cert

   """ Here, we will deployed the web service through tornado web server """
   if __name__ == '__main__':
      service = [('CertService',CertService)]
      app = webservices.WebService(service)
      app.listen(8080)
      tornado.ioloop.IOLoop.instance().start()

As you can see, I use the data types available in python (int, str, datetime module) on the attributes of the classes, this allow defined the xml complex types into the xml schema of the WSDL document.

Step 3:

Run and test the web service.

Running on Linux:

   $ python CertService.py

Running on Windows:

   c:\> python CertService.py

To test that web service is running:

In a web browser put the URL: http://localhost:8080/CertService?wsdl

You should see the WSDL document that defines the web service.

Testing the service:

To test the web service, I recommend using soapUI. Because you can to appreciate how the web service work at low level.

To test the web service with a client with suds-0.3.7, write this code in the file clientCertService.py:

   import suds

   url = 'http://localhost:8080/CertService?wsdl'
   client = suds.client.Client(url,cache=None)
   print(client)

   birthCert = client.factory.create('CertificateResponse')
   birthCert = client.service.getCertificate('1-9')
   print('-------------------------------------------')
   print('SOAP Request')
   print('-------------------------------------------')
   print(client.last_sent())
   print('-------------------------------------------')
   print()
   print('-------------------------------------------')
   print('SOAP Response')
   print('-------------------------------------------')
   print(client.last_received())
   print('-------------------------------------------')
   print()
   print('Bith Certicate')
   print('-------------------------------------------')
   print('Certificate number : ',birthCert.numcert)
   print('Id Person          : ',birthCert.idperson)
   print('Name               : ',birthCert.nameperson)
   print('Birthday           : ',birthCert.birthday)
   print('Datetime emition   : ',birthCert.datetimecert)
   print('Is valid           : ',birthCert.isvalid)
   print('-------------------------------------------')

Exceute the client with:

   $ python clientCertService.py

Note: is the same way in Linux and Windows

   print(client.last_sent())     # Show the soap request message (xml document)
   print(client.last_received()) # Show the soap response message (xml document)

TODO: is any one find some problem about clientCertService.py?

1: SOAP Response

<?xml version="1.0" encoding="UTF-8"?> soapenv:Envelope soapenv:Header/ soapenv:Body Error in web service : 'InputRequest' object has no attribute 'idperson' /soapenv:Fault /soapenv:Body /soapenv:Envelope

2: Certificate number : Traceback (most recent call last): File "E:\jia__file\eclipse_code\Test\src\tornado_webservices\clientCertService.py", line 24, in print 'Certificate number : ',birthCert.numcert AttributeError: 'NoneType' object has no attribute 'numcert'


I am sorry the words above. The fault is my mistake. I use tornado-1.2.1,tornadows0.9.1, and cannot run the clientCertService.py successfuly. now, I update the tornado & tornadows, and it's okay.

Bith Certicate

Certificate number : 1 Id Person : 1-9 Name : Steve J Birthday : 1973-12-11 Datetime emition : 2011-11-30 11:35:06

Is valid : True