magine that you are a PHP programmer. You use PHP, because it’s simple?but powerful enough to provide you with most of the features you need to develop Web-based applications for your customers. You have heard of or perhaps even played with more powerful languages, such as Python. Most of your development involves building Web applications, so you are concerned about performance, scalability, and flexibility.
The answer to this problem is mod_python, an Apache Web server module that embeds the Python interpreter within the Apache server in a manner similar to PHP. The advantages to this are many, but briefly, embedding the Python interpreter into Apache provides a persistent execution stack that eliminates the start-up penalty associated with running CGI scripts. It also lets you store specific information about the environment and visitors to your application?creating a pseudo-state mechanism for your Web site.
What exactly are we talking about, when we say a persistent execution stack that eliminates the start-up penalty associated with running CGI scripts? The best way to understand the difference between running a CGI application and an embedded code interpreter is to run some tests. As a benchmark I’ll use a simple CGI script first, and then run the equivalent script executed within the mod_python environment. I’ve used the Apache application Apache Bench (ab).
The following simple Web form posts a user’s selection from a select list to a simple CGI script. The form sends one value, named “month,” to the server, where the CGI script prints out the month within the year 2005.
A simple "get month" script
A Simple Python CGI Script
On the server, the CGI script extracts the month value from the form data and prints it out.
#!/usr/bin/python # # # A simple script to output a calendar month based off input from a Web form. # # import cgi,calendar print "Content-Type: text/html " print "
CGI vs. mod_python: Performance ResultsA month " print "" form = cgi.FieldStorage() month = form.getvalue("month") try: calendar.prmonth(2005, int(month),2,3) except Exception,e: print "That is not a valid month" print ""
Because other machine operations may influence any single result, you must test the application multiple times, taking the mean value over all the executions to get an accurate value. Executing the CGI version 1000 times using 10 connections:(mean time, across all concurrent requests) Time per request: 77.723 [ms]
Executing an equivalent script within the mod_python environment 1000 times using 10 connections, the execution time drops dramatically:
(mean time, across all concurrent requests) Time per request: 5.808 [ms]
Reviewing the above you can see that the mean time of all concurrent requests for the CGI execution is 77.723 milliseconds; but the mean time of all concurrent requests for the mod_python-enabled script is only 5.8 milliseconds?a huge performance increase.
Installing mod_python
Installing mod_python is simple. You typically don’t have to compile mod_python because most modern Linux and FreeBSD distributions include the module in their package management systems. For example, here’s the command to install mod_python on Ubuntu/Debian:apt-get install libapache-mod-python2.4
It’s just as simple on Redhat / Fedora Core 4:
yum install mod_python
On FreeBSD, the command is:
cd /usr/ports/www/mod_python3; make install clean
After installing mod_python you must configure Apache to use it. The first step is to enable the module in Apache by adding a LoadModule line to your httpd.conf file. You can just append the LoadModule entry to the end of the other LoadModule entries already in the file.
LoadModule python_module modules/mod_python.so
Author’s Note: You may have to change the paths to your particular installation. Ensure that the path you are using is the actual path to the mod_python.so file. |
Now that Apache has been configured to load the module, you need to configure a mod_python handler to work with your scripts. Mod_python uses three standard handlers to work with your application. They are the Publisher, PSP (Python Server Pages), and CGI Handlers.
The Publisher Handler
From the mod_python documentation the Publisher is the suggested handler to use when writing new mod_python applications. To configure a Web-accessible directory for use with the Publisher handler you would do the following. This of course assumes that /var/www/html is your Apache document root.
SetHandler mod_python PythonHandler mod_python.publisher PythonDebug On
The preceding configuration would add the mod_python handler and associate the /var/www/html/python directory to it. This means that all files under the directory will be processed by the mod_python handler. The addition of the PythonHandler means that you now have a single point of entry for Python script processing. The last line enables debugging during development via the PythonDebug On directive.
The Publisher handler requires slightly different code to generate the example getmonth script. You can use the same HTML as in the CGI example, but you must change the action attribute of the