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.
The mod_python gateway depends upon wsgiref. Get wsgiref from svn://svn.eby-sarna.com/svnroot/wsgiref/src/wsgiref.
Since changeset [39] on Feb 9, 2006, this module no longer depends upon wsgiref.
Grab source:modpython_gateway.py from this site and save it in site-packages, or somewhere else on your Python path. Then add the following to your Apache httpd.conf:
<Location /myapp>
SetHandler python-program
PythonHandler modpython_gateway::handler
PythonOption wsgi.startup myapp.cherrypy::startapp
# This is CP 3.0 beta 2 syntax:
PythonOption wsgi.application cherrypy::tree
PythonOption wsgi.cleanup cherrypy::engine.stop
# This is CP 2.2 syntax:
PythonOption wsgi.application cherrypy._cpwsgi::wsgiApp
PythonOption wsgi.cleanup cherrypy::server.stop
AuthType Basic
AuthName "MyApp"
AuthUserFile D:\htdocs\myapp\passwords
Require user admin guest
</Location>
myapp.cherrypy refers to a hypothetical myapp/cherrypy.py module that sets up cherrypy and your application. If you provide a function after the "::" (you don't have to), it will be called. Here's a sample script for CP 3.0 beta 2:
import cherrypy class HelloWorld: def index(self): return "Hello world!" index.exposed = True cherrypy.tree.mount(HelloWorld()) cherrypy.config.update({"environment": "production"}) cherrypy.engine.start(blocking=False)
Here's the equivalent for CP 2.2:
import cherrypy class HelloWorld: def index(self): return "Hello world!" index.exposed = True cherrypy.root = HelloWorld() cherrypy.config.update({"server.environment": "production", "server.protocolVersion": "HTTP/1.1"}) cherrypy.server.start(initOnly=True, serverClass=None)
Notice that, since we are using Apache to serve our requests, we can tell CherryPy to run in full HTTP/1.1 mode. The HTTP server provided in CherryPy 2.2 was not fully HTTP/1.1 compliant.
SCRIPT_NAME and WSGI
Some WSGI implementations require that the SCRIPT_NAME be equal to the "mount point" of the application. If you're using one of them, the SCRIPT_NAME which Apache invents is probably not going to be accurate. You can now (Feb 2006) manually set the SCRIPT_NAME environ value with a PythonOption:
PythonOption SCRIPT_NAME /myapp
This will make all WSGI requests use a SCRIPT_NAME of "/myapp"; PATH_INFO will be set to the remainder of the URL.
Init (startup) functions
You can tell modpython_gateway to call a function on the first request with a PythonOption:
PythonOption wsgi.startup myapp.cherrypy::startapp
Shutdown (cleanup) functions
Recent versions of mod_python include an easy way to declare functions that should be run when Apache exits. You can tell modpython_gateway to run functions at process shutdown with a PythonOption:
PythonOption wsgi.cleanup cherrypy::engine.stop
Note that the function will be called once per process or thread. If you run 10 threads, it will be called 10 times on Apache shutdown.
