wiki:ModPythonIntegration
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Note

The information on this page is obsolete, incomplete or incorrect and left here only for reference and has not been ported to the new documentation wiki.

Please refer to the TurboGears documentation wiki for up-to-date documentation.

Integrating mod_python with TurboGears .8a1

NOTE: For TG 0.9-prerelease integration check out this one

Thanks to Jamie's wonderful mpcp script, this could not have been easier. As always, this is what worked for me. YMMV. And $TG_MP = [your turbogears project directory].

Go grab the mpcp.py from  http://www.jamwt.com/ and put it into $TG_MP. Or, if you use setuptools/easy_install, you can do 'easy_install -Z mpcp'; make sure to include the '-Z'.

Put an .htaccess file in $TG_MP with the following:

SetHandler mod_python
PythonHandler mpcp
PythonDebug On
PythonOption cherrysetup $NAME_OF_YOUR_START_SCRIPT::mp_setup

$NAME_OF_YOUR_START_SCRIPT should be the filename minus the .py extension, since a dot will attempt to load a module named 'py' from that file.

Warning! The start script is usually MyAppName?-start.py, and the dash will screw up the PythonOption. Ergo, lose the dash and there shouldn't be any problems.

Now, in your (newly renamed) MyAppName_start.py make the following changes:

1) move cherrypy.server.start() so it only starts if name == "main".

if __name__ == "__main__":
   cherrypy.server.start()

2) create a new no-op method, called mp_setup(). As such:

def mp_setup():
   pass

This method is supposed to have cherrypy production config stuff, but our prod.cfg file handles that, so make it a no-op. The better solution would be to remove the line in mpcp that looks for cherrysetup, but that's something I'll worry about when a push to production is near.

Note: Previously, there were some instructions on how to get mpcp.py working with the new thread handling in CherryPy?. Jamie seems to have updated mpcp to work with the new setup, so the instructions have been removed. I recommend getting the newest version to work with (version 1.2), instead of hacking up your local copy.

Good luck!

Note for windows users: If your templates are not on the C:\ drive then you should add a line to configure the kid.path to include your project's directory (or you can simply include the relevant harddrive, see kid's  issue 110 and  issue 111 for details of why):

if __name__!="__main__":
    #ie imported this from apache
    import kid 
    kid.path.insert(dirname(__file__))
    #or:
    #kid.path.insert("D:\\") # or whatever

Note for Linux users: To get this running on a Linux machine a little more work is required to correctly map file paths. Here is my working start script:

import pkg_resources
pkg_resources.require("TurboGears")

import cherrypy
from os.path import *
import sys

def mp_setup():
    pass

if exists(join(dirname(__file__), "setup.py")):
    cherrypy.config.update(file=join(dirname(__file__),"dev.cfg"))
else:
    cherrypy.config.update(file=join(dirname(__file__),"prod.cfg"))

from pylucenetest.controllers import Root

cherrypy.root = Root()

If you get a 500 error and a long, ugly traceback ending with something like:

[Sat Dec 10 16:22:51 2005] [error] [client 127.0.0.1] PythonHandler mpcp:   File "/usr/lib/python2.4/os.py", line 159, in makedirs\n    mkdir(name, mode)
[Sat Dec 10 16:22:51 2005] [error] [client 127.0.0.1] PythonHandler mpcp: OSError: [Errno 13] Permission denied: '/home/httpd'

the problem is probably that one (or more) eggs that your application (or turbogears) wants to use are zipped. You will need to figure out which one(s) are problematic and reinstall them using 'easy_install -Z' (or just go into your site-packages directory and manually unzip them to the right places). Another alternative is to add

SetEnv PYTHON_EGG_CACHE /path/to/dir

into your apache config at the right level, and make sure that /path/to/dir is writable by your apache user (often "nobody" or "www"). (See also  :relevant discussion or another system)

Note: If you get an error saying:

AttributeError?: 'module' object has no attribute 'argv'

It is likely because turbogears created the startup script to check for a .cfg filename from the command line. It seems that not all versions of turbogears created the script like this, and running the script via mod_python means there are no command line arguments. So, to fix just remove or comment the line checking command line args, such as:

if len(sys.argv) > 1:
    cherrypy.config.update(file=sys.argv[1])
elif exists(join(dirname(__file__), "setup.py")):
    cherrypy.config.update(file="dev.cfg")
else:
    cherrypy.config.update(file="prod.cfg")

to

#if len(sys.argv) > 1:
#    cherrypy.config.update(file=sys.argv[1])
if exists(join(dirname(__file__), "setup.py")):
    cherrypy.config.update(file="dev.cfg")
else:
    cherrypy.config.update(file="prod.cfg")

Also, you may have to put the full pathname for the .cfg filename in order for turbogears to find it.

Note about cookies:

As of MPCP ver 1.2, sending multiple cookies does not work. This is becuase MPCP doesn't send duplicate headers, but is easy to fix. To allow duplicate headers, change lines 122 and 123 to read:

		elif tv is str:
			req.headers_out.add(header,value)