QP

QP is a package for defining and running multiple web applications based on Durus for persistence, standard persistent Session and User classes, easy interactive database sessions, qpy for assembling html, and forms and path traversal. QP makes it easier than ever to use these tools together.

QP includes a http/scgi server that dispatches requests to a pool of long-running single-threaded worker processes. With QP your applications can

  1. use the QP http service directly,
  2. use the QP http service through a proxy,
  3. use the QP scgi service through Apache+mod_scgi or lighttpd,
  4. use the QP scgi service through CGI, using the cgi2scgi adapter (DurusWorks/scgi/cgi2scgi.c) and any cgi-capable web server.

QP includes a site-management capability. One command line utility (named "qp") is used for controlling all of the servers for multiple sites. Run qp --help to see the options available for the qp command.

Using QP

To define a new site named, for example, hello, start with a copy of the proto site: cp -r /www/trunk/DurusWorks/proto /www/trunk/hello ln -s /www/trunk/hello/lib /www/pythonlib/hello ln -s /www/trunk/hello/site /www/qp_sites/hello Edit /www/trunk/hello/lib/ui/slash.qpy to configure the service addresses. Edit your apache configuration to provide virtual hosts that connect to the correct port for the SCGI server. Edit /www/trunk/hello/site/slash.py and change the import to this: from hello.ui.slash import SitePublisher, SiteDirectory Use the qp command to check that the hello site runs. Now you can add your customizations to /www/trunk/hello/lib and use the qp command to stop and start the site as needed to check your changes.

The customization options and in particular, the usage of the SiteDirectory, SitePublisher, and Form classes are beyond the scope of this document. To learn more, please study the proto demo and the QP source code.

The SitePublisher class should be a subclass of qp.pub.publish.Publisher, with a configuration class attribute identifying addresses for the servers you want to run.

Note that python will find your site packages as a subpackages of qp.sites, so the slash module of a site named hello, for example, can be imported in python as qp.sites.hello.slash.

The SiteDirectory class should be a subclass of qp.fill.directory.Directory that defines your site's content.

The Modules of QP

Here we will summarize the roles of some of the modules in the QP package.

qp.fill.css
This module contains some utilities for generating css.
qp.fill.form
This module defines the Form class, which provides a framework for rendering HTML forms and dealing with submitted forms.
qp.fill.widget
This module defines a variety of Widget classes for use by the Form class. There are different widgets for different kinds of form inputs.
qp.fill.directory
This module defines Directory. We use instances of this class to define the URL space of every application. Every QP site must define a SiteDirectory class that is a subclass of Directory. The SiteDirectory class defines the entry point for traversing the URL path.
qp.fill.durus_directory
This module provides DurusDirectory, a very specialized subclass of Directory used for browsing directly into a Durus database. This is useful for learning about the database structure.
qp.fill.html
This module defines short functions for generating common HTML structures.
qp.fill.static
This module provides StaticFile and StaticDirectory, which allow applications to deliver static content.
qp.http.request
Provides the HTTPRequest class.
qp.http.response
Provides the HTTPResponse class.
qp.hub.dispatcher
This provides the server dispatcher class used by QP. The dispatcher receives connections and passes them off to a pool of long-running child processes.
qp.hub.passfd
This module, implemented as a C-extension module, provides functions for transmitting file descriptors using a socket. This is used by QP's SCGI server.
qp.hub.web
This provides QP's handlers for SCGI and HTTP protocols.
qp.lib.delegation
This module provides some functions that provide a compact way to say define methods that delegate to other instances.
qp.lib.keep
A common requirement for a Durus database is to maintain a collection of uniquely identified instances of a given type. This module provides the Keep class that makes it easy to get this job done.
qp.lib.profiler
This module provides Profile, a class that can be used to test the QP request/response machinery directly, without involving any HTTP transmissions.
qp.lib.site
This module defines Site, the class that provides the API that QP uses for managing multiple sites.
qp.lib.spec
This module provides a pattern of defining specs, which are callables that are used to verify an argument's type or other qualities. We use the spec pattern to declare and verify the attributes of nearly all instances in the database.
qp.lib.tz
This module provides a way to define time zones for use with Python's datetime class. The method used here provides timezones that are actually Python classes, so they act as singleton instances.
qp.lib.util
This module provides a variety of utilities that did not seem to fit elsewhere.
qp.mail.rfc822_mailbox
This module provides some tools for dealing with email addresses and headers.
qp.mail.send
This module provides a sendmail() function and an Email class that can be used for constructing and sending email.
qp.pub.common
This module provides a set of convenient accessor functions that are used very frequently in QP applications. These functions provide a shorter way to call some methods of the SitePublisher and other instances it references.
qp.pub.hit
This defines the Hit class. An instance of Hit has references to the current HTTPRequest and HTTPResponse instances.
qp.pub.publish
The Publisher base class is defined in this module. Every QP site must define a SitePublisher class that is a subclass of Publisher.
qp.pub.session
The standard Session class is defined here.
qp.pub.user
This module provides the standard User class. It also include the Digester, used behind the scenes to maintain information needed for authenticating users. The TokenSet is used by User to provide a way to prevent forms from being submitted more than once. This module also provides the Permission class, which stores sets of specific tokens signifying permissions that are granted.

HTTPS

QP does not provide ssl service, but your QP applications can have https support by using

  1. QP's scgi server along with a separate server that provides https and scgi (such as the standard, Apache + mod_scgi),
  2. QP's http server along with an ssl-providing http proxy, or
  3. QP's http server along with stunnel.

To use the stunnel method, just install stunnel (available from www.stunnel.org) and configure it to run in server mode and to accept connections on the public ('https_address') interface and forward them to the port on the local ('as_https_address') interface. The host and port of both of these interfaces must be identified in the SitePublisher's configuration dictionary.

QP with lighttpd

The standard installation uses Apache, but the lighttpd HTTP server can be used similarly since it supports SCGI and SSL.

The following are the minimum lighttpd.conf customizations required to enable SCGI and set up a virtual host for http and https:: server.modules = ("mod_access", "mod_scgi", "mod_accesslog") $HTTP["host"] == "www.example.com" { $SERVER["socket"] == "0:443" { ssl.engine = "enable" ssl.pemfile = "/www/ssl/server.pem" ssl.ca-file = "/www/ssl/server.crt" } scgi.server = ( "" => ( "localhost" => ( "host" => "127.0.0.1", "port" => 7003, "check-local" => "disable", # default disable-time is 60 seconds "disable-time" => 5 # seconds ) ) ) }

History

The QP package incorporates the work of the MEMS Exchange software developers going back to approximately late 2000. Other contributors include:
Michael Watkins
David Hess
Maas-Maarten Zeeman
Peter Wilkinson
Mario Ruggier

DurusWorks Documentation