3.3 So what Exactly does Mod-python do?

Let's pretend we have the following configuration:

  <Directory /mywebdir>
      AddHandler mod_python .py
      PythonHandler myscript
      PythonDebug On

NB: /mywebdir is an absolute physical path.

And let's say that we have a python program (Windows users: substitute forward slashes for backslashes) /mywedir/myscript.py that looks like this:

from mod_python import apache

def handler(req):

    req.content_type = "text/plain"
    req.write("Hello World!")

    return apache.OK

Here is what's going to happen: The AddHandler directive tells Apache that any request for any file ending with .py in the /mywebdir directory or a subdirectory thereof needs to be processed by mod_python. The "PythonHandler myscript" directive tells mod_python to process the generic handler using the myscript script. The "PythonDebug On" directive instructs mod_python in case of an Python error to send error output to the client (in addition to the logs), very useful during development.

When a request comes in, Apache starts stepping through its request processing phases calling handlers in mod_python. The mod_python handlers check whether a directive for that handler was specified in the configuration. (Remember, it acts as a dispatcher.) In our example, no action will be taken by mod_python for all handlers except for the generic handler. When we get to the generic handler, mod_python will notice "PythonHandler myscript" directive and do the following:

  1. If not already done, prepend the directory in which the PythonHandler directive was found to sys.path.

  2. Attempt to import a module by name myscript. (Note that if myscript was in a subdirectory of the directory where PythonHandler was specified, then the import would not work because said subdirectory would not be in the sys.path. One way around this is to use package notation, e.g. "PythonHandler subdir.myscript".)

  3. Look for a function called handler in myscript.

  4. Call the function, passing it a request object. (More on what a request object is later)

  5. At this point we're inside the script:

Some food for thought: If you were paying attention, you noticed that the text above didn't specify that in order for the handler code to be executed, the URL needs to refer to myscript.py. The only requirement was that it refers to a .py file. In fact the name of the file doesn't matter, and the file referred to in the URL doesn't have to exist. So, given the above configuration, "http://myserver/mywebdir/myscript.py" and "http://myserver/mywebdir/montypython.py" would give the exact same result. The important thing to understand here is that a handler augments the server behaviour when processing a specific type of file, not an individual file.

At this point, if you didn't understand the above paragraph, go back and read it again, until you do.