21.3. Other Server-Side Approaches
A CGI script runs as a new process each time a client requests it. Process startup time, interpreter initialization, connection to databases, and script initialization add up to measurable overhead. On fast, modern server platforms, the overhead is bearable for light to moderate loads. On a busy server, CGI may not scale up well. Web servers support many server-specific ways to reduce overhead, running scripts in processes that can serve for several hits rather than starting up a new CGI process per hit.
Microsoft's ASP (Active Server Pages) is a server extension that leverages a lower-level library, ISAPI, and Microsoft's COM technology. Most ASP pages are coded in the VBScript language, but ASP is language-independent. As the reptilian connection suggests, Python and ASP go very well together, as long as Python is installed with the platform-specific win32all extensions, specifically ActiveScripting. Many other server extensions are cross-platform, not tied to specific operating systems.
The popular application server Zope (http://www.zope.org) is a Python application. If you need advanced management features, Zope (and the higher-level content-management system Plone, http://plone.org/, built on top of Zope) should be among the solutions you consider. Zope and Plone are large, powerful systems and need full books of their own to do them justice. I do not cover Zope and Plone further in this book.
FastCGI lets you write scripts similar to CGI scripts, in a variety of languages, using each process to handle multiple hits, either sequentially or simultaneously in separate threads. See http://www.fastcgi.com for FastCGI overviews and details, including pointers about FastCGI support on all kinds of servers as well as Python support for FastCGI. A streamlined variant of FastCGI is SCGI (http://www.mems-exchange.org/software/scgi/).
The Python Web Server Gateway Interface (WSGI) is the emerging standard "middleware" approach that interfaces higher-level Python web development frameworks to underlying web servers, and is documented at http://www.python.org/peps/pep-0333.html. Although not mainly intended for direct use by your application programs (rather, you code your programs using any of several higher-abstraction frameworks, which, in turn, use WSGI to talk to the web server), it's not impossible to use WSGI directly. To ease this task, http://www.owlfish.com/software/wsgiutils/ and http://pythonpaste.org/ offer several modules you may want to explore. Mike Orr has published in the Linux Gazette an excellent article (http://linuxgazette.net/115/orr.html) that explore the state of WSGI. For much interesting information and discussion on how best to integrate WSGI with the fast, lightweight lighttpd server (http://www.lighttpd.org/), see the blog post and comments at http://www.cleverdevil.org/computing/24/python-fastcgi-wsgi-and-lighttpd.
A reference implementation of WSGI, known as wsgiref, may be included in the standard library of Python 2.5 (this was still not fully decided at the time of this writing). In any case, the reference implementation is available at http://svn.eby-sarna.com/wsgiref/ and should work with any release of Python from 2.3 upward.
Apache's architecture is highly modular. Beyond CGI and FastCGI, mod_python (http://www.modpython.org) affords full Python/Apache integration, with Python access to all needed Apache internals, including the ability to write authentication scripts.
21.3.4. Custom Pure Python Servers
In "HTTP Servers" on page 530, we saw that the standard Python library includes modules that implement web servers. You can subclass BaseHTTPServer and implement special-purpose web servers with little effort. Such special-purpose servers are useful in low-volume applications, but may not scale up well to handle moderate to high server loads.
Modules asyncore and asynchat (covered in "The asyncore and asynchat Modules" on page 535) exhibit very different performance characteristics. The event-driven architecture of asynchat-based applications affords high scalability and performance, beating applications that use lower-level languages and traditional architectures (multiprocess or multithreading).
21.3.5. Other Higher-Level-of-Abstraction Frameworks
It has been said that "Python is the language with more web app frameworks than keywords"; the language's power and simplicity conspire to tempt many developers to write their own, unique frameworks. Fortunately, these days, WSGI affords some interoperability. It may be worth your while to examine some of these frameworks, just in case one of them is a perfect match for your needs and desires (it's certainly a better use of your time than developing yet another such framework!). Coverage and discussion of many, many frameworks (including many no longer being actively developed), with URLs to find out more about them and download them, can be found in the essay at http://www.python.org/pycon/papers/framework/web.html and at the Wiki page http://wiki.python.org/moin/WebProgramming.
In my personal opinion, among the most promising frameworks, all under current active development and already rich and stable enough for mission-critical use, are CherryPy (http://www.cherrypy.org/), Django (http://www.djangoproject.com/), Pylons (http://pylonshq.com/), and TurboGears (http://www.turbogears.org/). They adopt very different approaches and philosophies: some integrate and even emphasize templating, or database access, while others focus on the web part and let you access databases or perform templating via separate modules; some require (and exploit) good understanding of HTTP issues, and/or SQL, while others shield you from those layers. Given such differences, each may prove optimal for different programmers and teams. In the rest of this chapter, I single out three frameworks (two mature and still actively developed ones, and one that is "the new kid on the block" and, in my personal opinion, is especially promising and interesting).
Webware for Python (http://www.webwareforpython.org/) is a modular collection of software components for Python server-side web scripting. You can code Python scripts according to different programming models, such as CGI scripts with added-value wrappers, servlets, or Python Server Pages (PSP), and run them all on Webware. Webware, in turn, interfaces to your web server in many ways, including CGI, FastCGI, mod_python, the specialized Apache module mod_webkit, and Python Paste (http://pythonpaste.org/) for WSGI interfacing. Webware offers you a lot of flexibility in architecting, coding, and deploying your server-side Python web scripts.
Among the many ways that Webware offers for you to generate web pages, one that will often be of interest is templating (i.e., automatic insertion of Python-computed values and some control logic in nearly formed HTML scripts). Webware supports templating via PSP, but also, with more power and sharper separation between logic and presentation parts, via the Cheetah package, covered in "The Cheetah Package" on page 586.
Quixote (http://www.mems-exchange.org/software/quixote/) is another framework for Python web applications that can interface to your web server via the usual huge variety of ways, including CGI, FastCGI, WSGI, and mod_python. Quixote defines a new language, the Python Template Language (PTL), and an import hook that lets your Python application directly import PTL-coded modules.
Quixote's PTL is nearly the same as Python, but has a few extras that may be handy in web applications. For example, PTL keyword template defines functions that return string results, automatically called to respond to web requests; within such functions, all expression statements are taken as appending strings to the function's return value. For example, the PTL code:
template hw( ): 'hello' 'world'
is roughly the same as the following Python code:
def hw( ): _result =  _result.append('hello') _result.append('world') return ''.join(_result)
Based on my own skills, needs, and tastes, my current favorite web framework is web.py (http://webpy.org). It's small (web.py itself is currently a single Python module of less than 2,500 lines, including comments), simple, works smoothly with other open source components (such as Cheetah for templating and PostgreSQL or MySQL as a database), and supports WSGI without requiring any such component (your script may also run with CGI, FastCGI, or as a standalone web server, which is particularly useful for ease of testing during development). Canonical "Hello world" example is:
import web urls = '/', 'greet' class greet(object): def GET(self): print 'Hello, web.py world!' if _ _name_ _ == '_ _main_ _': web.run(urls)
The urls list maps regular expressions (matching HTTP paths) to class names, and classes implement methods GET and POST (and possibly others) to serve HTTP requests. Visit http://webpy.org for more information and to download web.py.