login
v2
v1

jmoiron.net

mod_python & mod_php

posted February24th, 2006 @ 23:56:51

- tags: development , python

- comments: 1

I finally understand apache, and what really happens internally when a request is made. I wasn't able to understand mod_python until today. Until the limitations of the server page model are ground against in such a way that you actually wonder, "There has to be a better way!" you aren't really ready to write your own Apache request handler. Even if it's totally fucking easy.

PHP has to deal with novices by design. These profiteering entrepeneurs are going to make it big with their bulletin board software if they could just figure out loops, and they just need a little help stepping over this barrier. Apache's mod_php was built to "do the right thing" in an easy to understand way (server pages), and although I have my beef with the language I feel that the module writers were largely successful. But what you don't know as a PHP developer is that the entire PHP environment is but one solution to how you could treat page requests.

When I wanted to write my page in Python, I wished that I could just "write the page" and be done with it. For simple stuff, PHP and the server page paradigm work flawlessly. I read the mod_python documentation in with no lack of dread, wondering why they were asking me to code something that wasn't even part of my page. Getting over that hump took a while; it takes grinding up against the limitations of being confined to a server page paradigm. Without getting into dogma and holy war too much, lets just look at something neat you can do by writing your own handler.

When Apache gets a request, you can essentially hook into it and do what you like with it. With mod_python's PSP handler, you can get a decent server page style environment to write quick scripts with. But mod_python also lets you write your own handler, which can essentially be only a slightly customized version of any of the default handlers (and most likely usually is). Let me provide an example:

from mod_python import apache, psp

l = ['a complex', 'object', 1]
vars = {
    'sitename' : 'jmoiron.net',
    'baseurl'  : l,
}
def handler(req):
    global vars
    req.content_type = "text/html"
    template = psp.PSP(req)
    template.run(vars)
    return apache.OK

I won't explain this too much, because I feel a lot of it is self-evident. I'm defining a handler function that will handle incoming requests for "*.py" (this option is set in a .htaccess file). When a request for "index.py" is received, mod_python will call my handler with a request object. The python server page module (psp) is then used to build a template from the request (which has the filename in it), and then the template is "run". The "template.run(vars)" line is really the only one of any importance. It "runs" the python code in the template, and passes in the vars (that i created) as global variables. So, suppose that the psp file that we have requested is this:

<%
sys.stdout = req

...
# lets pretend we have printed out the HTML tags

print "%s, %s" % (sitename, baseurl)
%>

This will print out "jmoiron.net, [ 'a complex', 'object', 1 ]". Once you realize that mod_python is a python interpreter that is resident within apache, and thus always running (and with a somewhat constant environment), it's easy to see the usefulness of such a simple peice of code as the handler above. Since you can pass arbitrary objects, it should be possible to pass things like database handles and other things that you might desire to be persistent.

comments

from Jerumu on Wednesday Aug 30th, '06 @ 10:26#1

In hindsight, I suppose I should have read this months ago.

sigh