[Web-SIG] [WSGI] mod_python wrapper: minimal first attempt

Phillip J. Eby pje at telecommunity.com
Thu Oct 14 01:01:31 CEST 2004


At 02:06 PM 10/13/04 -0700, Robert Brewer wrote:
>In order to test my application's WSGI interface, I wrote a quick
>mod_python server interface for WSGI. It's not bulletproof, but the
>parts I use work. Sorry, Phillip, I didn't subclass
>wsgiref.handlers.BaseHandler yet. ;(

That's okay; you've given me several of the pieces I would need to do it 
myself.  :)  Although, I still would want a better way to find out what to 
set the multithread/multiprocess flags to; as some Apache builds are 
multithreaded and some are not, and some are multi-process, and some or 
not.  To be compliant

There are, however, numerous other issues in your code, from a 
WSGI-compliance perspective.  For example, your start_response() doesn't 
support WSGI error handling.

Anyway, a mod_python handler would probably look something like:


     from wsgiref.handlers import BaseCGIHandler

     class ModPyHandler(BaseCGIHandler):

         def __init__(self,req):
             req.add_common_vars()
             BaseCGIHandler.__init__(self,
                 stdin = ModPythonInputWrapper(req),
                 stdout = None,
                 stderr = ModPythonErrorWrapper(req),
                 environ = dict(req.subprocess_env.items()),
                 multiprocess = True,  # XXX
                 multithread  = True,  # XXX
             )
             self.request = req
             self._write = req.write

         def _flush(self):
             pass

         def send_headers(self):
             self.cleanup_headers()
             self.headers_sent = True
             self.request.status = int(self.status[:3])
             for key, val in self.headers.items():
                 self.request.headers_out[key] = val

     def wsgi_handler(req):
         handler = ModPyHandler(req)
         options = req.get_options()
         appmod,appname = options['application'].split('::')
         d = {}
         exec ("from %(appmod)s import %(appname) as application" % 
locals()) in d
         handler.run(d[application])
         from mod_python import apache
         return apache.OK


But note that this is just a draft off the top of my head, and may be 
deficient with respect to how it uses the mod_python API (especially since 
I've never used mod_python even once).  Anyway, to use it, one would 
configure something like:

    PythonHandler somewhere::wsgi_handler
    PythonOption application myapp::wsgi_app_func

In other words, it uses a PythonOption called "application" to indicate the 
application to be run, thus simplifying the launch configuration.

Let me know if this code works for you, and if so I'll add it to the 
wsgiref library.



More information about the Web-SIG mailing list