Python Example

From Ladon Webservice

Jump to: navigation, search

Simple Example

Let's start out with one of the simplest examples at all. A calculator service that can add two integers and return the result.

Example 1

from ladon.ladonizer import ladonize

class Calculator(object):
  """
  This service does the math, and serves as example for new potential Ladon users.
  """

  @ladonize(int,int,rtype=int)
  def add(self,a,b):
    """
    Add two integers together and return the result

    @param a: 1st integer
    @param b: 2nd integer
    @rtype: The result of the addition
    """

    return a+b

Go to the API browser

Try it

JavaScript JSON-WSP client

Request a feature

Help ease the development

Using the jsonwspclient.js script it is easy to load and parse the jsonwsp/description generated by the Calculator service. With the client object you can do AJAX style requests to the web service with very little effort. The JSONWSPClient integrates well into a jQuery based web application but jQuery is not a requirement.

NOTE: Make sure to load the json2.js script before jsonwspclient.js or Internet Explorer won't work.

Loading the description

Before we can start calling service methods with a JSONWSPClient object it needs to know which methods are available. This is done by using the loadDescription method. In the example below a client is created and the Calculator service is loaded:

var client = new JSONWSPClient();
client.loadDescription("http://ladonize.org/python-demos/Calculator/jsonwsp/description",function(){
  // Called when description has been loaded and the client is ready for use.
})

Click the button below to load the description from Example 1

Call a service method

After loading the description the client object is ready to invoke service methods. In the example below it is shown how the method add() is called:

client.add({
  a: <1st integer>,
  b: <2nd integer>
  },
  <mirror value or null>,
  function (result) {
    // Handle the result
  }
})

Try it for real by filling in integers in the two fields below (Must load the service description) and then press "Fetch Result" to invoke the method.

+ =

If you are interested in examining the request/response objects involved in the method invocation it is recommended that you use Firefox with the Firebug extension installed. You can also use wireshark or maybe built-in development tools for other browsers.

SOAP

Online SOAP Client

It is pretty easy to test the SOAP interface for a service. Just copy the url to the service's SOAP interface description (http://ladonize.org/python-demos/Calculator/soap/description) and paste it into an online SOAP client (ie: http://www.validwsdl.com).

Suds Client

You can access the SOAP interface of the Calculator service from Python using suds:

from suds.client import Client
client = Client('http://ladonize.org/python-demos/Calculator/soap/description')
 
# Calculate 34+56
result = client.service.add(34,56)
print result

LadonType, Lists and Portable Types

Example 2 shows how you can implement data structures in Ladon which enables you to send and recieve more complex/organized data between clients and server. To implement a structure you must create a new class that inherits LadonType. Example 2 also shows how you can create Python 2/3 compatible services using the ladon.compat module.

LadonType

LadonType is an interface class defined in the Ladon framework which all service structures must inherit. It let's you operate with objects making it possible to send and recieve nicely structured results. LadonTypes can be referenced in other LadonTypes. For instance if you have a LadonType named Group, and another LadonType named User you might need an attribute called primary_group on User of type Group - thus the User LadonType references the Group LadonType:

Snippet 1

from ladon.types.ladontype import LadonType

class Group(LadonType):
  gid = int
  name = unicode
  display_name = unicode

class User(LadonType):
  uid = int
  username = unicode
  primary_group = Group
  secondary_groups = [ Group ]

Lists

Notice that the attribute secondary_groups in Snippet 1 is declared as a list with one element. This means that a list of values with that type is expected by the Ladon Framework in requests and responses. In this particular case it is a list of the LadonType Group. You can also use primitives as list types like [ int ].

Portable Types

Snippet 1 clearly is not Python 3 compatible as it uses the unicode type directly. In Python 3 the type you want to use if you need unicode support is str. Ladon has a simple solution to this problem if you wish to make use of it. Instead of stating the actual Python type names (bytes/str/unicode) use the type defines PORTABLE_BYTES and PORTABLE_STRING from ladon.compat. This will make the Ladon framework resolv string/bytes types according to the Python version.

So if you use the PORTABLE_STRING definition in your service implementation and start your service with Python 2 it will resolve to unicode, if you start it with Python 3 it will resolve to str

Let's rewrite Snippet 1 and make it work in both Python 2 and 3:

Snippet 2

from ladon.types.ladontype import LadonType
from ladon.compat import PORTABLE_STRING

class Group(LadonType):
  gid = int
  name = PORTABLE_STRING
  display_name = PORTABLE_STRING

class User(LadonType):
  uid = int
  username = PORTABLE_STRING
  primary_group = Group
  secondary_groups = [ Group ]

Example 2

Let's go ahead to example 2 which utilizes LadonType, Lists and ladon.compat. Example 2 will actually run on both the Python 2 and 3 version of Ladon. The service exposes two methods: listBands() and listAlbums() that use a python module named albumdata as back-end. albumdata defines a dictionary called albums which is just a subset of my CD collection.

A real-world version of this service would ofcourse use a database as back-end, but for demonstration this will do:

# -*- coding: utf-8 -*-
from ladon.ladonizer import ladonize
from ladon.types.ladontype import LadonType
from ladon.compat import PORTABLE_STRING
from albumdata import albums

class Band(LadonType):
  name = PORTABLE_STRING
  album_titles = [ PORTABLE_STRING ]

class Album(LadonType):
  band = Band
  title = PORTABLE_STRING
  songs = [ PORTABLE_STRING ]


class AlbumService(object):
  """
  Search through albums and bands.
  """

 
  @ladonize(PORTABLE_STRING,rtype=[ Album ])
  def listAlbums(self,search_frase=PORTABLE_STRING('')):
    """
    Fetch a list of albums matching search_frase
    """

    album_list = []
    for band_name,albums_dict in albums.items():
      b = Band()
      b.name = band_name
      b.album_titles = []
      for album_title,songs in albums_dict.items():
        b.album_titles += [ album_title ]
        if len(search_frase)==0 or album_title.find(search_frase)>-1:
          a = Album()
          a.band = b
          a.title = album_title
          a.songs = [ ]
          for idx,song_title in songs:
            a.songs += [song_title]
          album_list += [a]
    return album_list

  @ladonize(PORTABLE_STRING,rtype=[ Band ])
  def listBands(self,search_frase=PORTABLE_STRING('')):
    """
    Fetch a list of albums matching search_frase
    """

    bands = []
    for band_name,albums_dict in albums.items():
      if len(search_frase)==0 or band_name.find(search_frase)>-1:
        b = Band()
        b.name = band_name
        b.album_titles = []
        for album_title,songs in albums_dict.items():
          b.album_titles += [ album_title ]
        bands += [b]
    return bands

Go to the API browser

Further reading

Ladon supports attachments for JSON-WSP via the special ladon type attachment (ladon.types.attachment):

It is possible to override Ladon's HTTP responses completely by implementing specialized custom response classes:

Try it

Python JSON-WSP Client

This time I suggest trying out the jsonwsp Python client that is installed with Ladon. Below is an example of how use it:

# -*- coding: utf-8 -*-http://ladonize.org/index.php/

from ladon.clients.jsonwsp import JSONWSPClient
import pprint

cli = JSONWSPClient('http://ladonize.org/python-demos/AlbumService')

# Fetch albums containing the substring "Zoo" in the album title
pprint.pprint(cli.listAlbums(search_frase='Zooropa'),indent=2)

# Fetch all bands containing the substring "Bowie" in the band name
pprint.pprint(cli.listBands(search_frase='Bowie'),indent=2)

# Fetch all bands
pprint.pprint(cli.listBands(),indent=2)

SOAP

Online SOAP Client

It is pretty easy to test the SOAP interface for a service. Just copy the url to the service's SOAP interface description (http://ladonize.org/python-demos/AlbumService/soap/description) and paste it into an online SOAP client (ie: http://www.validwsdl.com).

suds Client

You can access the SOAP interface of the AlbumService service from Python using suds:

from suds.client import Client
client = Client('http://ladonize.org/python-demos/AlbumService/soap/description')
 
# List all bands in the collection
result = client.service.listBands('')
print result
 
# List albums containing "Zoo" in album title
result = client.service.listAlbums('Zoo')
print result

Install local examples

Ladon for Python
From pypi.python.org
Latest (tar.gz)

If you are looking for a real example to download and run on your own system then you will find the official Ladon examples in the source distribution of Ladon. Look for the subdirectory "examples".

Download it via Python Package Index (click the green button to the right)

The examples expose different services that you can play with and study, including how to use attachments and task-type methods in Ladon.

It also shows how you can use custom skins in your service API Browser. Look at the "appearance" directory under "examples" to study the skins that are put into the Ladon example project. You can create your own skin by copying one of the skins in the "appearance" directory and then altering it.

After downloading the source package simply unpack it on your system, start a command prompt and go the the unpack directory and then into the "examples" subdirectory. Now issue the following command:

python runserver.py

Now start a new prompt to test the service. Again change directory to the "examples" directory and run the following command:

python clienttest.py