Quixote Programming Overview

This document explains how a Quixote application is structured. The demo.txt file should probably be read before you read this file. There are three components to a Quixote application:

  1. A driver script, usually a CGI or FastCGI script. This is the interface between your web server (eg., Apache) and the bulk of your application code. The driver script is responsible for creating a Quixote publisher customized for your application and invoking its publishing loop.

  2. A configuration file. This file specifies various features of the Publisher class, such as how errors are handled, the paths of various log files, and various other things. Read through quixote/config.py for the full list of configuration settings.

    The most important configuration parameters are:

    ERROR_EMAIL

    e-mail address to which errors will be mailed

    ERROR_LOG

    file to which errors will be logged

    For development/debugging, you should also set DISPLAY_EXCEPTIONS true; the default value is false, to favor security over convenience.

  3. Finally, the bulk of the code will be called through a call (by the Publisher) to the _q_traverse() method of an instance designated as the root_directory. Normally, the root_directory will be an instance of the Directory class.

Driver script

The driver script is the interface between your web server and Quixote's "publishing loop", which in turn is the gateway to your application code. Thus, there are two things that your Quixote driver script must do:

The publisher is responsible for translating URLs to Python objects and calling the appropriate function, method, or PTL template to retrieve the information and/or carry out the action requested by the URL.

The most important application-specific customization done by the driver script is to set the root directory of your application.

The quixote.servers package includes driver modules for cgi, fastcgi, scgi, medusa, twisted, and the simple_server. Each of these modules includes a run() function that you can use in a driver script that provides a function to create the publisher that you want. For an example of this pattern, see the __main__ part of demo/mini_demo.py. You could run the mini_demo.py with scgi by using the run() function imported from quixote.server.scgi_server instead of the one from quixote.server.simple_server. (You would also need your http server set up to use the scgi server.)

That's almost the simplest possible case -- there's no application-specific configuration info apart from the root directory.

Getting the driver script to actually run is between you and your web server. See the web-server.txt document for help.

Configuration file

By default, the Publisher uses the configuration information from quixote/config.py. You should never edit the default values in quixote/config.py, because your edits will be lost if you upgrade to a newer Quixote version. You should certainly read it, though, to understand what all the configuration variables are. If you want to customize any of the configuration variables, your driver script should provide your customized Config instance as an argument to the Publisher constructor.

Logging

The publisher also accepts an optional logger keyword argument, that should, if provided, support the same methods as the default value, an instance of DefaultLogger. Even if you use the default logger, you can still customize the behavior by setting configuration values for access_log, error_log, and/or error_email. These configuration variables are described more fully in config.py.

Quixote writes one (rather long) line to the access log for each request it handles; we have split that line up here to make it easier to read:

127.0.0.1 - 2001-10-15 09:48:43
  2504 "GET /catalog/ HTTP/1.1"
  200 'Opera/6.0 (Linux; U)' 0.100s

This line consists of:

If no access log is configured (ie., ACCESS_LOG is None), then Quixote will not do any access logging.

The error log is used for three purposes:

If no error log is configured (with ERROR_LOG), then all output is redirected to the stderr supplied to Quixote for this request by your web server. At least for CGI/FastCGI scripts under Apache, this winds up in Apache's error log.

Having stdout redirected to the error log is useful for debugging. You can just sprinkle print statements into your application and the output will wind up in the error log.

Application code

Finally, we reach the most complicated part of a Quixote application. However, thanks to Quixote's design, everything you've ever learned about designing and writing Python code is applicable, so there are no new hoops to jump through. You may, optionally, wish to use PTL, which is simply Python with a novel way of generating function return values -- see PTL.txt for details.

Quixote's Publisher constructs a request, splits the path into a list of components, and calls the root directory's _q_traverse() method, giving the component list as an argument. The _q_traverse() will either return a value that will become the content of the HTTPResponse, or else it may raise an Exception. Exceptions are caught by the Publisher and handled as needed, depending on configuration variables and whether or not the Exception is an instance of PublisherError.