Architecture of a Python + Flex application

My product, slideboxx, has an unusual architecture.  It is a desktop application but follows a client-server model.  This creates some challenges but also strongly enforces some good design such as separating application logic from data presentation.  I’ll discuss why I use a Flex front end in a future post.

The challenges include:

  • must serialize Python objects/data to something that Actionscript can understand
  • since slideboxx runs in the browser, it can’t see the filesystem so the server (Python) code needs to act as a proxy for interactions with the filesystem (I realize AIR applications can see the filesystem, but felt AIR would not be sufficiently familiar [yet] to our customers)
  • many changes in application state, such as setting a preference, require a trip to the server — this is cumbersome but not technically challenging
  • debugging can be difficult because you sometimes need to correlate tracebacks between client and server

Serializing the data is probably the most fundamental issue.  Fortunately it is generally easy to solve.  I use a mix of XML and JSON to serialize data.  The mix is partly historical and partly to fit in easily with the Flex framework. The historical part of this is that I originally wrote the slideboxx interface in Javascript using the YUI library and at that point YUI did not have JSON handling.  An example of fitting into the Flex framework is that XML result sets can be translated directly to ArrayCollections.  So for results that are going to target something like a Flex List component, returning an XML result set means I don’t need to write any parsing code.  The relevant part of the XML I use to pass slide search results from Python to Flex looks something like this:

<ResultSet>
    <Result>
        <ID>...</ID>
        <name>...</name>
        etc...
    </Result>
    <Result>
         ...
    </Result>
    ...
</ResultSet>

You can see it is a <ResultSet> with a list of <Result> elements. I generate it using string operations in Python, which in this case is straightfoward.

On the Flex side this becomes an ArrayCollection which is bound as a dataProvider for a TileList element:
In the Actionscript part:

[Bindable]
public var feed:ArrayCollection = new ArrayCollection( );
...
private function resultHandler( event : ResultEvent ) : void {
    ...
    try {
        feed = event.result.ResultSet.Result; 
    } catcht( e : Error ) {
        feed = new ArrayCollection( ArrayUtil.toArray( event.result.ResultSet.Result ) ) ;
   }
   ...
}

and in the MXML:

<mx:TileList ... id="theList" dataProvider="{feed}" ...>
    <mx:itemRenderer>
        <mx:Component>
            <!-- put some custom component here that can bind some
                 the elements of each <Result>, these will be referenced
                 as "{data.<elementName>}" e.g., "{data.ID}" -->
        </mx:Component>
     </mx:itemRenderer>
</mx:TileList>

I realize there is a library for serializing Python objects to AMF. I’ve tried to keep the external dependencies to a minimum so I didn’t use PyAMF. We don’t currently see any performance issues using XML and JSON but will continue to evaluate if/when it makes sense to introduce PyAMF.

I should also mention that communication between client and server happens over HTTP using the WSGIServer from the wsgiref.simple_server module with a threading mixin and over sockets using asyncore (I use sockets for cases where I need to push notifications from the Python code to the Flex GUI).  I do not use the SimpleXMLRPCServer in Python.

Advertisement

About this entry