deploying a WSGI application on mod_python

1.1k views Asked by At

I wrote a WSGI application which I need to deploy to a server, however I've been given a server that already has mod_python installed.

I am not allowed to remove mod_python since there are some mod_python applications running on it already.

One option I considered was installing mod_wsgi alongside mod_python, however I went through sources and found that was a bad idea. Apparently mod_wsgi and mod_python don't mix well.

Another option I considered was installing mod_fastcgi and deploying it using fastcgi.

I would love to hear if someone has a better idea which doesn't break the current mod_python applications running on the server.

4

There are 4 answers

0
Graham Dumpleton On BEST ANSWER

You can use mod_python and mod_wsgi together so long as same Python version and mod_python not linked against a static Python library.

Run the 'ldd' command on the mod_python.so file:

ldd mod_python.so

to find out if it links to libpythonX.Y.so. Build mod_wsgi to use same Python version, ensuring it is similarly linked against same libpythonX.Y.so.


UPDATE

Version 4.X of mod_wsgi now explicitly refuses to start if mod_python is also loaded. In order for mod_python and mod_wsgi to be used together, certain features of mod_wsgi had to be crippled. As mod_python is now very old, not meaningfully updated, has various problems with it and should not be used for anything new, no longer trying to support them being used together.

0
codeape On

After some googling, I found this:

How to set up mod_python for use as a WSGI server

The following now works using Apache2, with mpm_winnt and prefork! Other versions and MPM's may give radically different results. If you've got a little time and experience, please try this latest version with prefork on Linux, and any other Multi-Processing Modules you favor.

3
Mike Graham On

The best solution might be to use mod_proxy and run the Python web app in a different webserver.

3
codeape On

Here's an idea (that needs fleshing out, and that maybe won't work):

Here's what I would start with:

from mod_python import apache
from wsgiref.handlers import BaseHandler

class MyWSGIHandler(BaseHandler):
    def __init__(self, apachereq):
        BaseHandler.__init__(self)
        self.apachereq = apachereq

    def _write(self, data):
        self.apachereq.write(data)

    # override the other required methods of BaseHandler, see
    # http://docs.python.org/library/wsgiref.html#wsgiref.handlers.BaseHandler

wsgi_app = create_your_wsgi_app()

def handler(req):
    wsgi_handler = MyWSGIHandler(req)
    wsgi_handler.run(wsgi_app)
    return apache.OK

IDEA 2 (pretty hackish):

You could in your handler code also use the werkzeug wsgi testing module to pass a request to the WSGI app, get a werkzeug response back and then write that response to apache.

Something like:

from mod_python import apache
from werkzeug.test import Client
from werkzeug.wrappers import BaseResponse

wsgi_app = create_your_wsgi_app()

def handler(req):
    c = Client(wsgi_app, BaseResponse)
    resp = c.get(somehow_get_the_url_from(req)) # or c.post if it's a POST request
    req.write(resp.data) # ... and find a way to write the headers as well
    return apache.OK