[mod_python] Apache/mod_python: Registering a request handler dynamically

Graham Dumpleton graham.dumpleton at gmail.com
Sun Dec 28 16:34:21 EST 2008


2008/12/29 Samuel Abels <newsgroups at debain.org>:
> (I also sent this to comp.lang.python before realizing that this list is
> the better place, so apologies if you got this message twice.)
>
> Hi,
>
> Is there a way to dynamically overwrite the request handler from within
> mod_python scripts? Something along those lines:
>
> ---------------
> from mod_python import apache
>
> def myhandler(request):
>    request.content_type = 'text/plain'
>    request.write('Hello world')
>
> apache.set_default_handler(myhandler)
> ---------------
>
> I specifically want to avoid changing the Apache directive, as this code
> is supposed to function regardless of whether the user has access to
> change the Apache directive.
>
> The reason is that I am trying to hide the difference between different
> environments (such as mod_python or CGI) from the developer, such that
> the following is possible:
>
> ---------------
> #!/usr/bin/python
> import os, os.path
> os.chdir(os.path.dirname(__file__))
> from PleaseHideMyEnvironment import RequestHandler
>
> def index(request):
>    # Note that the request argument here is one created by
>    # the PleaseHideMyEnvironment module, not a mod_python one.
>    request.write('Hello World')
>
> RequestHandler(index)
> ---------------
>
> So at the time at which RequestHandler() is created, I need a way to
> make sure that mod_python calls to the RequestHandler instead of the
> normal handler, whenever a new request is made.
>
> Any idea?

Are you saying you want one script to be able to work under either CGI
or mod_python? If you are then I would recommend you use WSGI instead
as WSGI interface is specifically designed to be used across multiple
hosting mechanisms.

For example, presuming I got last bit right, the following would work
with mod_wsgi or CGI as written:

#!/usr/bin/env python

def application(environ, start_response):
    status = '200 OK'
    output = 'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]

if __name__ == "__main__":
    import wsgiref.handlers
    wsgiref.handlers.CGIHandler().run(application)

The CGI handler only gets triggered if script executed. In mod_wsgi it
loads file and then calls direct to 'application'.

The application object could also be plugged into many other WSGI
compliant hosting solutions as well. There are even WSGI adapters out
there for mod_python, although if you go the WSGI way, you are better
off using mod_wsgi instead.

So, go read up about WSGI instead, it is a better long term solution
as not tied to a specific hosting mechanism.

Graham


More information about the Mod_python mailing list