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@