mike watkins dot ca : Python Web Application Diary

Python Web Application Diary

May 31, 2007

I have a number of tutorial projects in various stages of completion, and I'm itching to put some of this stuff out there in the hope that its useful to someone.

It occurred to me that I could do a project or two and document them along the way, tutorial style, in order to present one or more tutorials on writing web applications with QP, a stable but relatively unknown web application framework from the same folks who brought Quixote to Python.

I'm going to try something a little different than the typical blog in 20 minutes style tutorial and instead try to take readers along a real-world path as I document what I do.

This tutorial isn't intended to be the last word on web development or Python or even on using QP and related bits, but hopefully it will be accessible enough for new Python users, while remaining informative and brief enough for those with more experience.

I'm not even going to delve into the question "Why QP and not TurboGears or Django or Zope?", except to simply say that QP, like its older cousin Quixote, provides an easy to use and understand framework which makes publishing your Python objects to the web simple. Quixote and QP have been around a long time, QP somewhat less so but acquires its maturity by sharing the principal publish/request and resource representation architecture of its older cousin, Quixote. QP also shares a philosophical constraint: no magic.

If you are looking for a tool set that has every single size of screwdriver ever produced, then a tool like QP might not appeal to you. But if you are looking for an easy to understand and work with web application development framework that you can more or less keep in your head, QP is worth a close look. If you are also a ZODB or object database aficionado, or would like to see what the object database world is like, then QP and Durus are a compelling duo.

The Project

The project I have in mind is to redevelop the blog software that powers my own personal site, http://mikewatkins.ca/. You are soaking in it right now, if you are reading this in early June 2007.

Why bother? While there are many blog applications out there, what I want at the end of this are a set of objects and UI components that can be integrated into other QP applications.

I've wanted to move off of PyBlosxom for some time now, but with something else always on my plate, doing so has never been a priority for me. Its the prospect of killing two birds with one stone -- wiring up a simple web log or journal, and documenting it tutorial style -- that is pushing me forward now.

Before Going Further

QP's developers rather unabashedly adopted some preferences which are built into the system and its design. It was designed to run on Unix-like systems. While some enterprising people have looked at running it on Windows, if you are a Windows-only or Windows-sometime developer, you might want to search and read the QP mailing list archives first before venturing forth.

First Steps

Today's installment for readers is to install QP and related components. But before we get there, first a word on my environment so that subsequent notes make sense.

My development, test and production environments have similar file system layouts and installed software. Of note to us in this tutorial you'll want:

  • Python 2.5.x installed
  • Python Imaging Library (PIL)
  • HTMLTidy (will be used eventually)
  • Perhaps a component or two more as we go through this.

I install all Python related tools into the default locations; tools and libraries and non-QP applications that I write are located in:

/www/lib - added to PYTHONPATH (in your .profile or .cshrc)

QP by default looks along certain paths for applications to manage (start, stop, restart, interact with, view log). This allows you to have user-space apps which QP can see with no re-installation of the base software, as well as system or privileged user applications. First lets look at the command line help:

%qp -h
Usage: qp [options] [start|stop|restart] [site]*

Control the servers for the sites in your qp installation.
No options is the same as "--status".
"stop" is the same as "--stop".
"start" is the same as "--start".
"restart" is the same as "--stop --start".

If "--stop" and "--start" are both present and the durus server
is already running, only the web server is restarted.

The script searches for sites in the qp.sites package, which
in turn searches through the following list, by default.
    ${QP_SITES}
    ~/qp_sites
    ~/.qp_sites
    /var/qp_sites
    /usr/local/lib/python2.5/site-packages/qp/sites

Options:
  -h, --help           show this help message and exit
  -u, --start          Start the durus and web servers.
  -d, --stop           Stop the durus and web servers.
  -q, --quickrestart   Quick restart of the web server(s) of the named sites.
  -v, --status         Show the current status of the durus and web servers.
  -c, --configuration  Show the site configuration.
  -l, --log            tail -f the log for the last named site.
  -i, --interact       Open an interactive session with the last named site.

QP applications other than demo apps or quick one-offs or test apps go:

/www/qp_sites

And I've created a symlink in /var that points to qp_sites:

cd /var
ln -s /www/qp_sites qp_sites

I put demo apps / quick one-offs / test apps in:

~/qp_sites

Also under /www for convenience:

/www/docs - a collection of documentation that I refer to
/www/python - symlink to /usr/local/lib/python2.5/

All the library work I do is contained in a Python package called "parlez". The development files live in /www/lib/Parlez, and a symlink to its lib subdir is created in /www/lib. Parlez contains:

/www/lib/Parlez         - including CHANGES, LICENSE, README
/www/lib/Parlez/bin     - related scripts
/www/lib/Parlez/doc     - documentation
/www/lib/Parlez/lib     - the Parlez package itself
/www/lib/Parlez/site    - a demo application

In /www/lib I create a symlink:

@ln -s /www/lib/Parlez/lib parlez@

Install QP and related packages

We want to install Durus, an object database closely related to QP but which can be used quite independently of QP, as well as QPY, QP, and Dulcinea. More on each of these later. Install them now, in the following order:

  • Durus - a Python object database similar to ZODB
  • QPY - Python-centric "templating" or if you prefer, untemplating
  • QP - A web framework for easy publishing of "objects" to the web
  • Dulcinea - pre-made components that work with QP and Durus
  • Sancho - A unit testing suite

All of the software components listed above are available at http://www.mems-exchange.org/software/ under an open source license.

Once installed, run and play with one or more of the three QP demo applications provided:

qp proto start

or start proto like this:

qp -u proto

See what's running by issuing qp with no parameters:

%qp

proto  durus[61859]:localhost:7002 web[61860] http::8002 as_https:localhost:9002 https:localhost:10002
sr     durus:down web:down
recipe durus[60590]:localhost:7005 web[60591] http::8005
contact web[54418] http::8080
test   web:down
hello  web:down

And then visit http://localhost:8002/ to explore the prototype application.

Once you've looked at the basic QP demos and peeked at some of the underlying code to grasp how simple this all is going to be, then see what Dulcinea brings to the table by way of pre-made components and user interface bits. In your ~/qp_sites subdirectory, create a link to the Dulcinea demo application and run that.

In our next installment, we'll create some basic objects, introduce Sancho unit testing, and write a bloxsom to "Parlez" conversion script so we have some real data to work with going forward.