[mod_python] transhandler setup?

Graham Dumpleton grahamd at dscpl.com.au
Thu Sep 8 11:38:21 EDT 2005

On 05/09/2005, at 3:08 AM, Dirk van Oosterbosch, IR labs wrote:
> I mixed up two versions of  main.py  I had laying around. (I modified 
> my translate.py so the  req.filename  becomes  main_from_trans.py , 
> but didn't use that name in the  PythonHandler  directive).
> It does strike me as strange however, that I have to use   
> PythonHander python_main_file   in the apache configuration, when I 
> have the transhandler decide that it should use python_main_file.py as 
> filename. That would mean I can't make the transhandler fork its 
> behavior between different python files as the ones that should become 
> the filename and should be handled in the next phase (handler  that 
> is). (Unless I have it fork to different directories and use different 
> <Directory> configurations, of course)
> ...
> I mean something like:
> -----translate.py:
> def transhandler(req):
> 	...
> 	if fork == 1:
> 		req.filename = "/var/www/python/main_alternative_a.py"
> 	else:
> 		req.filename = "/var/www/python/main_alternative_b.py"
> 	return apache.OK
> -----
> wouldn't work because I would have to say

You misunderstand what is happening. What is important in respect of
what req.filename is set to is not the full pathname, but just the
extension to the last component of the filename. Ie., the presence of
the ".py" extension. It is this which triggers the execution of the
handler specified by the PythonHandler directive.

Try setting PythonHandler to "main" and then in your transhandler set
set req.filename to either a or b alternative. The main.py handler
will still be executed. In your main.py handler you could then say:

   def handler(req):
     directory,file = os.path.split(req.filename)
     name = os.path.splitext(file)
     module = apache.import_module(name,path=[directory])
     return module.handler(req)

Ie., your main.py then becomes a simple dispatcher which defers to
what ever req.filename is set to.

> Also I found out that if I add
> req.add_handler("PythonHandler", "main")
> to translate.py it executes the handler from main.py twice (you get a 
> double html file) , but only if it can successfully do the first one 
> (set by  req.filename = "/var/www/python/main.py" .

See the documentation for listing of multiple handlers:


In particular:

   Multiple handlers can be specified on a single line, in which case 
   will be called sequentially, from left to right. Same handler 
   can be specified multiple times as well, with the same result - all
   handlers listed will be executed sequentially, from first to last. If
   any handler in the sequence returns a value other than apache.OK, then
   execution of all subsequent handlers is aborted.

Thus, if your had "main" specified for PythonHandler and then had the
transhandler add it again using req.add_handler(), then yes it will be
executed twice if each returns apache.OK.

If you don't specify it in the PythonHandler directive and use just
req.add_handler() will it work. Note that you will still need to 
specify AddHandler for .py extension. If it doesn't work, might be seen
as a shortcoming in Apache/mod_python.

>> For an internal redirect, you probably want:
>>   req.internal_redirect(req.uri+'/index.html')
>> This will not send a response back to the browser and it will managed 
>> internal
>> to Apache.
> Question I now have: does anybody know how efficient this internal 
> redirect would be in comparison to a database query?
> For the point is, that with option 1, all the static directories 
> (requests for www.myserver.com/folder) will go through apache twice: 
> (It first is handled by handler in main.py which then decides it 
> should be www.myserver.com/folder/index.html anyway.
> How economically inefficient is that performance wise?
> The alternative, option 2, has the downside of two database queries 
> for every dynamic page: First transhandler checks whether the url 
> exists in the database. Then later, handler again queries the database 
> for this url.

At a guess, Apache is going to be quicker at servicing a request than
a database query. This would really depend on your setup though.

> Is one of these alternatives much more performance intensive than the 
> other?
> I know I am comparing apples with pears here. The one is an internal 
> redirect handled between mod_python and apache. The other is a 
> database query handled my MySQL and MySQLdb (which is also dependent 
> to how the database is designed and which field are indexed and so 
> on...). Further more the decision between the two options is also 
> dependent on how many these scenarios occur: do I have a lot of static 
> index.html files which are requested by only their directory, or do I 
> serve mostly dynamic pages.
> So indeed the decision won't be just a matter of comparing 
> performances of the two, but if someone can just give me a "handle"...

You are really just going to have to test each option.


More information about the Mod_python mailing list