You are on page 1of 5

A Brief Look at Mod_Python

(2005-04-25) - Contributed by Peyton McCullough

Python's Apache interpreter is available as an Apache module, mod_python. This module reduces the time it takes to
deliver a given page to a client. It is also capable of a great deal more, including interacting with Apache itself in various
powerful ways. This article gives you just a taste of what mod_python can do.

Introduction

You enter in an address, requesting a page from Apache. It's not just any old page, though. It's a CGI script written in
Python. A few moments later, you're staring at the results. However, what exactly does Apache do with your request? As
with all CGI scripts, Apache spawns a new process - in this case, the Python interpreter - and then spits out that process'
output. It works, but it isn't the fastest way, nor is it the most efficient way.

Other languages have presented different solutions to this problem. Languages such as PHP have embedded their
interpreters into Apache. Other languages, such as Perl, offer Apache modules (in Perl's case, mod_perl) that do this.
These "other languages" include Python, though not enough people realize this.

This article deals with Python's own module for Apache, mod_python, and the benefits it provides to both man and
machine.

A Quick Look at Mod_Python

As I stated eariler, mod_python embeds the Python interpreter into Apache. This reduces the time needed to deliver a
given page to a client. Starting the Python interpreter, waiting for it to finish executing, and then catching its output not
only takes time, but it takes up valuable resources as well.

This, however, is not the only benefit provided by mod_python. Mod_python can interact with Apache, giving you
extraordinary power. You can change the way Apache handles tasks and utilize the Apache API.

Languages that can be embedded straight into HTML, such as PHP, are very popular. CGI does not allow this. However,
mod_python does. You've seen Java Server Pages (JSP) and Active Server Pages (ASP); this article will introduce you
to Python Server Pages (PSP).

Interesting? Yes. Let's move on.

{mospagebreak title=Installing Mod_Python}

First, head on over to the mod_python website:

http://modpython.org

Download the latest version for your platform.

To install mod_python on a Unix enviroment, you perform the usual ritual:

http://www.devshed.com - Dev Shed Generated: 8 January, 2007, 02:38


$ ./configure$ make$ su# make install

You may, however, need to help the configure script out a bit by pointing it to apxs (which is included with Apache and is
needed to compile mod_python) or Python itself:

$ ./configure -with apxs=/some/strange/place/apxs -with-python=/some/strange/place/apxs

With Windows, things are easier. Although mod_python's official site no longer offers an easy installation option for
Windows, a gentleman by the name of Nicolas Lehuen provides one on his website:

http://www.lehuen.com/nicolas

You can download it here:

http://www.lehuen.com/nicolas/download

Install it, and you're almost good to go.

You'll then need to configure Apache (on either platform). Load httpd.conf into your favorite text editor. Add this:

LoadModule python_module libexec/mod_python.so

If you used the Windows installer I mentioned, use this instead:

LoadModule python_module modules/mod_python.so

Failing both of those, try searching for the location of mod_python.

We'll have to set mod_python as the handler for Python files. Add this to httpd.conf:

AddHandler python-program .py

Finally, we must give .htaccess a bit of power. Search httpd.conf for the string "AllowOverride" set it to "All." You should
end up with this:

AllowOverride All

{mospagebreak title=Getting Started}

I'm sure many of you are coming from a CGI background and have several CGI scripts sitting around. Fortunately for
http://www.devshed.com - Dev Shed Generated: 8 January, 2007, 02:38
you, mod_python can emulate a CGI enviroment and run your old scripts. Create a directory called pycgi. Create a
.htaccess file and add this to it:

PythonHandler mod_python.cgihandler

We'll now create a simple "CGI" script:

import cgiformData = cgi.FieldStorage()if 'name' in formData: name = formData [ 'name' ].valueelse: name = 'John
Doe'print 'Content-type: text/html'printprint 'Hello, ', name + '.'

You should not, however, rely on this method. It has a few problems, and mod_python offers much more efficient
methods of doings things, as I explained at the beginning of the article. Let's not waste a perfectly good Apache module
on CGI emulation.

Instead, we'll move on to mod_python's publisher handler. The publisher handler allows us to easily deliver Python
powered pages to clients. Instead of having a separate page for everything, mod_python's publisher handler allows us to
have a Python function for everything.

Create a directory named pypublish. We'll use this to play around with the publisher handler. Create a .htaccess file with
this in it:

PythonHandler mod_python.publisher

Now create a file named test.py and fill it with this:

def index(): return "This is only a test."def peyton(): return "Peyton wrote this."

Obviously, it contains two functions. Let's see how those functions relate to the script's output. Open up your Web
browser and head over to the page you just created:

http://server/pypublish/test.py

As you can see, the index function is executed, and the results are delivered to you. Now let's try something different.
Append "/peyton" to the URL:

http://server/pypublish/test.py/peyton

The peyton function is now executed. This interesting feature can be convenient in developing applications.

Now let's make a script that is a bit more complicated. Let's process data from a form - a task vital to functional websites.
We'll create a form that asks for the reader's favorite color, the time he or she woke up and his or her favorite language.
All this will go in the index function. When the form is submitted, the data will be sent to the process function to be made
pretty and displayed. Create a file appropriately named form.py:

def index(): out = "<form method='POST' action='form.py/process'>" out = out + "What is your favorite color?<br>" out =
http://www.devshed.com - Dev Shed Generated: 8 January, 2007, 02:38
out + "<input type='text' name='color'><br>" out = out + "What time did you wake up this morning?<br>" out = out +
"<input type='text' name='waket'><br>" out = out + "What is your favorite language?<br>" out = out + "<select
name='flang'><option>Python</option></select><br>" out = out + "<input type='submit' value='Process'>" out = out +
"</form>" return outdef process ( color, waket, flang ): return "Your favorite color is " + color + ", you woke up at " + waket
+ " and you like " + flang + "."

The index functon contains no suprises. It just displays form data, so I won't bother going into detail there. The process
function, however, is a bit different. As you can see, it takes three arguments. Notice that the three arguments
correspond to the names of the form fields. The way the publisher handler handles this is pretty interesting. Try switching
around the arguments or even taking out a few (just remember to take out the variable in the return statement, too). The
function still executes fine. The publisher handler automatically puts in the correct arguments. Pretty neat, huh?

{mospagebreak title=Creating Handlers and Working with the API}

I stated earlier in the article that it is possible to change the way Apache does things. This is done through handlers.
Apache does its work in steps, or phases. Each of these steps can be performed by a handler. Mod_python registers a
handler for each step, which can be populated by Python instructions.

This feature of mod_python is rather interesting, and we can do things with it that are equally as interesting. Let's say we
want to change the way text documents are viewed, putting the document inside a pretty layout. We can do this by
creating a handler that takes over at the stage where content is gathered and delivered to the user. This might sound a
bit confusing, so it's best for me to show you rather than tell you. Create a directory named pyhandler and drop this
inside its .htaccess file:

AddHandler mod_python .txtPythonHandler headerfooter

This tells Apache that .txt files are to be handled by mod_python. It then tells mod_python that the file headerfooter.py
should be called to handle the .txt files. Create headerfooter.py and add this to it:

from mod_python import apache

def handler ( request ): request.content_type = 'text/html' request.write ( "<html>" ) request.write ( "<head>" )


request.write ( "<title>Text Document</title>" ) request.write ( "</head>" ) request.write ( "<body bgcolor='#D2D2D2'>" )
request.write ( "<table align='center' bgcolor='#000000' cellspacing='1px' cellpadding='5px' width='60%'>" ) request.write
( "<tr><td bgcolor='#FFFFFF' align='center'>" ) request.write ( file ( request.filename ).read().replace( '\n', '<br>' ) )
request.write ( "</td></tr>" ) request.write ( "</table>" ) request.write ( "</body>" ) request.write ( "</html>" ) return
apache.OK

That's quite a mouthful, so let's break it down. The first line imports the module apache. This allows us to interact with
Apache. We then define a method, handler, that accepts one parameter, request. The request object contains
information about (drumroll please) the request.

The next line's function is a bit more obvious. We send out the content type of the page. We then print out a layout using
the write method and print the contents of the text file, whose name is contained in the filename method of the request
object. We then tell Apache that everything went fine.

{mospagebreak title=Python Server Pages}

Now I'll introduce Python Server Pages. Languages like PHP have been made popular due to their ability to be
embedded directly into HTML. Python Server Pages allow Python code to be embedded into HTML pages. Python
Server Pages aren't terribly difficult to understand, and I believe showing you would be a lot better than telling you, so
http://www.devshed.com - Dev Shed Generated: 8 January, 2007, 02:38
we'll jump right in. Create a directory named pypsp, and add this to its .htaccess file:

AddHandler mod_python.pspPythonHandler mod_python.psp

Now let's get into some code. Python code is enclosed between less-than and greater-than signs, postfixed and prefixed
with percent signs. For example:

<% # Python code here %>

You can also print out single items by putting an equal sign in, just as you would with PHP:

<%=variableName%>

Here an example:

<%# Import a Moduleimport math%><html><head><title>Python Server Pages Test</title></head><body>The square


root of 25 is <%=math.sqrt ( 25 )%>. The square root of 50 is <%=math.sqrt ( 50 )%>.</body></html>

Save it as test.psp and point your browser to it. Interesting, eh?

Conclusion

As you've seen throughout this article, mod_python is a very powerful addition to the Apache Web server. It allows
control over even Apache itself through handlers, which are easily created with mod_python. The publisher handle and
the psp handle make Web development in Python a lot easier than it already is, and allow it to better compete with
popular Web development languages such as PHP and ASP.

What this article outlines is definitely not all of mod_python. Mod_python contains much more power than this article can
tell about, but that power is the topic of another article on another day. Until then, good luck.

http://www.devshed.com - Dev Shed Generated: 8 January, 2007, 02:38

You might also like