fsmGenerate.py -- FSM/REST Application Generator

Dave Kuhlman


Release 1.00
Mar. 28, 2003

Front Matter

Copyright (c) 2003 Dave Kuhlman

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.



This document describes fsmGenerate.py. It explains what it does and how to use it. fsmGenerate.py generates skeletons of FSM/REST Web applications.


1. Introduction

fsmGenerate.py can produce:

And, optionally fsmGenerate.py will package the entire generated application into a .zip file that can be imported (by Python 2.3).

2. What It Does

fsmGenerate.py generates an FSM/REST application for the Quixote Web application server. For more information on FSM/REST see REST and FSM and BP for Quixote How-to.

2.1 FSM and REST -- Application Structure

fsmGenerate.py generates source code for an FSM/REST web application. The application is a skeleton in the sense that code implementing the special behavior of each state must be added by hand. (Note for future work: The FSM/REST application is generated from an XML document that describes the FSM. It may be possible to ``enrich'' that document so that it contains implementations of behaviors that implement actions and conditions used by each state.)

The application is structured as an FSM (finite state machine). This means that each request from a client provides input values that are used by the application (the current state in particular) to determine and perform a transition. Performing the transition causes the FSM to execute an action and select a new current state.

The application is a REST (representation state transfer) application. This means, among other things, the following:

The server and the client communicate with each other by passing XML documents back and forth. The definition of the XML interchange document is specific to each state in the FSM. For each state, fsmGenerate.py generates an XML Schema definition which describes the XML interchange document for that state. In addition, generateDS.py is used to translate the XML Schema document input Python code that implements a parser for the XML interchange document and classes that represent the elements defined by the XML Schema document.

The generated implementation is structured as a Python package (a directory containing a __init__.py file). The package contains a module (a Python .py file) for each state in the FSM. Each of these ``state'' modules contains a class that implements the state.

2.2 Output -- What fsmGenerate.py Generates

fsmGenerate.py generates a directory, which, because it contains a __init__.py file, is a Python package.

This package will contain, depending on the command-line options given to fsmGenerate.py and used to generate it, the following:

3. How to Use It

This section describes a suggested sequence of steps to be followed in using fsmGenerate.py.

3.1 Create an Application Description Document

You must create an FSM-XML document that describes your application. This FSM-XML document is used as input to fsmGenerate.py, which uses it to create the application and a client user interface (GUI).

The FSM-XML document contains elements that describe each state in the FSM. The distribution (fsmGenerate_examples.zip) contains an XML Schema (fsm.xsd) that describes the FSM-XML document type. There is also a sample document (fsm_plants.xml). Here is a brief description of the elements in that document:

fsm -- The wrapper element for the whole document. Contents:

state -- Contents:

transition -- Contents:

inputs -- Contents:

field -- Each field results in the generation of a graphical user interface (GUI) control in the .wxg file generated for wxGlade. Contents:

3.2 Run fsmGenerate.py

Run fsmGenerate.py to produce the application and support code. You can find fsmGenerate.py in the distribution file: fsmGenerate_examples.zip.

Here is the ``help'' message from fsmGenerate.py:

fsmGenerate -- Generate Quixote application skeleton, wxGlade GUI
    definition, and X Schema definitions for FSM REST Web application.
    python fsmGenerate.py [options] <in_file_name> <out_name>
    -h, --help      Display this help message.
    -a, --app       Generate Quixote application skeleton.
    -g, --gui       Generate .wxg file for client-side GUI.
    -s, --schema    Generate .xsd X Schema files for XML interchange docs.
    -z, --zip       Zip into PyZipFile.
    python -a -g -s -z fsmGenerate.py myapp1

And, here is a description of the options:

4. What To Do with The Generated Code

Because modifying and extending the code generated by fsmGenerate.py depends so much on your application and your needs, this section can at most contain guidelines. However, I'll at least try to offer suggestions on where to put things and how to use the generated code.

4.1 The XML Schemas and what to do with them

First, let's make clear what they are. The generated .xsd files describe the XML documents that are passed back and forth between an FSM/REST server and a client. Thus, from the client's point of view, the client must generate an XML document that satisfies the X Schema for the current state and submit that document as the content of the client's request. Likewise, from the client's point of view, the client will receive an XML document from the the server as the result of a request. From the server's point of view, the server will receive (and must parse) a document whose contents are described by the XML Schema for the current state. And, also from the server's point of view, the server must generate an XML document that satisfies the XML Schema for the current state as the representation of the resource for the current request.

Note that these modules generated by generateDS.py are there to help you but are not strictly necessary. Any of a variety of other methods for processing the XML interchange documents with Python could be used. Some examples are (1) using Python's DOM or minidom support and (2) using David Mertz's Gnosis tools (see the ``See Also'' section, below).

fsmGenerate.py helps you process the XML interchange documents by using generateDS.py to produce code that can parse a state specific XML interchange document and then access the elements in that document. It does this by loading the XML document into instances of (generated) Python classes that represent the elements.

For a given state ``X'', fsmGenerate.py produces the following files:

Here is an example of code that uses a sample module to parse and XML interchange document and then to extract an input value from it:

import Xsub
doc = Xsub.parseString(content)
value = doc.getFsminput().getArg1()

And, here is another example. This one sets a value in the interchange document structure, then uses that structure to generate XML content:

import Xsub
import StringIO
doc = Xsub.parseString(content)
value = doc.getFsminput().getArg1()
contentStream = StringIO.StringIO()
doc.export(contentStream, 0)
newContent = contentStream.getvalue()
# Do something with newContent.

4.2 The FSM/REST/Quixote state modules and what to do with them

For each state named ``X'' in the FSM XML specification file, fsmGenerate.py generates a file named X.py. You can add application specific code to each of these Python modules.

Here is an example -- a generated module that implements a state named ``Plant'':

# Plant.py

from states import State

class Plant(State):
    def __init__(self, doc):
        State.__init__(self, doc)
    def _q_index(self, request):
        nextState = None
        # Transition tr_plant_1
        if compareArg(arg1, "fruit"):
            nextState = 'Fruit'
        # Transition tr_plant_2
        if compareArg(arg1, "vegetable"):
            nextState = 'Vegetable'
        content = self.generateContent()
        return content

Here are some things you will need to do to this generated code:

4.3 The wxGlade definition file and what to do with it

The generated file has the name gui.wxg.

Start up wxGlade and then open this file.

This file contains a number of dialog/frame definitions, one for each state in the FSM. From within wxGlade, you can modify these dialog definitions, then use wxGlade to generate Python code that implements the dialogs. If you do not change the name of the output, it will generate a Python file/module named gui.py.

4.4 Implementing a client

You will want to implement a client. I'm going to assume that you will do this in Python. If you want to implement your client in some other programming language, you will have to do a bit of translation of my guidance.

The distribution contains a minimal example of a client: client.py. There are more client examples in the fsm examples file, which are described in http://www.rexx.com/ dkuhlman/fsm_howto.html.

Here are a few comments and guide-lines:

If your client talks to a warm body and you want that end-user to be able to enter input values into a graphical user interface, then you may want to use the ``- -gui'' option and then work with the generated .wxg file. Here are a few suggestions:

5. Future Work

5.1 Business process markup language

It would be helpful if we could capture FSM XML files from a BPML. We might even consider modifying fsmGenerate.py (actually, the underlying fsmgenapp module) so that it could read the BPML directly.

Another possibly approach would be to take a UML diagram editor such as PyUt, and modify it so that it can export our FSM XML documents. I am investigating that one. I'll have to resolve the following questions, at least:

Requirements and desirables -- What would make this usable and valuable? Remember that our goal is to connect BPs to FSMs, i.e. to implement BPs on the Web with FSM/REST.

5.2 Alternative URIs

The examples discussed in this document pass the current state name between the server and the client by including that state name in the XML interchange document. Doing so makes things a bit awkward because (1) you need the current state name in order to determine which parser to use and (2) before you can determine the current state name (and thus the document type), you must at least partially parse the document.

This means that you have to use something like SAX or a regular expression to partially parse the document and obtain the state name and, then use the generated parser to parse the document. (The generated code and the sample client (client.py) use a regular expression.)

A possibly more convenient approach might be to pass the current state as part of the URI. This would solve the problem for the server, though not for the client.

6. Software Requirements

In order to use fsmGenerate.pyyou will need several software packages. See the "See Also" section for links to these packages.

End Matter

Acknowledgements and Thanks

Thanks to the implementors of Quixote for producing an exceptionally usable application server that is so suitable for REST.

Thanks to Alberto Griggio <albgrig@tiscalinet.it> for wxGlade.

See Also:

The main Python Web Site
for more information on Python

The Python XML Special Interest Group
for more information on processing XML with Python

Dave's Web Site
for more software and information on using Python for XML and the Web

The RESTWiki
for more information and links on REST

Quixote home page
for more information on the Quixote Python Web application framework

Beginner's How-to for AOLserver, PyWX, and PostgreSQL
for more information on using AOLserver, PyWX, PostgreSQL and Quixote

REST for AOLserver, PyWX, and Quixote
for more information on implementing REST-ful applications with Quixote

REST and FSM and BP for Quixote How-to
for more information on implementing complex process with FSMs with Quixote in a REST-ful way

Project: LLEU: Summary
for more information on flux

generateDS.py -- Generate Python data structures from XML Schema
for more information on generateDS.py

for more information on wxPython

wxGlade -- a GUI builder for wxWindows
for more information on wxGlade

David Mertz's Gnosis download directory
for the latest Gnosis XML library

David Mertz's technical publications at Gnosis
for ``XML Matters'' articles on Gnosis/objectify and other topics

About this document ...

fsmGenerate.py -- FSM/REST Application Generator, Mar. 28, 2003, Release 1.00

This document was generated using the LaTeX2HTML translator.

LaTeX2HTML is Copyright © 1993, 1994, 1995, 1996, 1997, Nikos Drakos, Computer Based Learning Unit, University of Leeds, and Copyright © 1997, 1998, Ross Moore, Mathematics Department, Macquarie University, Sydney.

The application of LaTeX2HTML to the Python documentation has been heavily tailored by Fred L. Drake, Jr. Original navigation icons were contributed by Christopher Petrilli.