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

Version 14 (modified by anonymous, 9 years ago) (diff)

--

Turbogears 0.9-prerelease mod_python integration

The SVN version of TG uses cherrypy-2.2.0-beta which, AFAIK, is not compatible with the mpcp script described at the other mod_python integration page.

I've managed to get it running using Robert Brewer's modpython_gateway.py. It has been tested on a Debian Sarge box, Apache 2.0.54 (worker MPM) and a backported libapache2-mod-python2.4 package from Ubuntu (the package didn't install cleanly and some black drudgery had to be done in order to get it working by hand so I will not post it here yet, if there's some demand I might try to build a better backport).

However, provided you can run your TG app with python2.3, you should be fine with Sarge's stock modpython2.3. (I'm a big fan of 2.4's syntax sugar so I couldn't resist :)

Quick recipe

  • Install wsigiref, sudo easy_install wsgiref should get you going. Since changeset (39) on Feb 9, 2006, modpython_gateway.py no longer depends upon wsgiref.
  • Download Robert's  script and place it in site-packages, or somewhere else on your Python path.
  • You'll need to write a script to start your TG app as start-yourapp.py will not work. It should be something like:
import pkg_resources
pkg_resources.require("TurboGears")

import cherrypy
import turbogears

turbogears.update_config(modulename="yourapp.config")
turbogears.update_config(configfile="/home/alberto/yourapp/prodcfg.py")

from yourapp.controllers import Root

cherrypy.root = Root()
cherrypy.server.start(initOnly=True, serverClass=None)                                                 

Make sure you don't make any reference to sys.argv (as modpython doesn't have a command line) and you use full paths (as Apache's working directory is /, like any well behaved unix daemon...). Don't forget to fix your paths and application name!.

Place this script in your application's package (where controllers.py lives), let's say you call it myapp_modpython.py.

  • Now you should sudo python setup.py install your app, you can get away by sudo python setup.py develop it. But then you should make your application's directory writable by your Apache user (normally www-data) which you should by no means do on a production box (if you can't guess why, then you should not be running a production box ;)
  • Now you should configure your Apache virtual host, something like:
    NameVirtualHost 10.0.0.100:80
    <VirtualHost 10.0.0.100:80>
        ServerName www.example.com
        ServerAdmin webmaster@example.com
        ServerSignature Off
        AddDefaultCharset utf-8
    
        <Location />
            SetHandler python-program
            PythonHandler wsgiref.modpython_gateway::handler
            PythonOption wsgi.application cherrypy._cpwsgi::wsgiApp
            # PythonOption import myapp_modpython # does not work
            PythonFixupHandler myapp.myapp_modpython # works! tested with TG0.9 alpha
    
            # Switch it off when everything is working fine.
            PythonDebug on
    
            # This section can be skipped if you have no mod_deflate or don't want compression
            # Recipe stolen somewhere around the httpd.apache.org realms.
            <IfModule mod_deflate.c>
                 # Insert filter
                 SetOutputFilter DEFLATE
    
                 # Netscape 4.x has some problems...
                 BrowserMatch ^Mozilla/4 gzip-only-text/html
    
                 # Netscape 4.06-4.08 have some more problems
                 BrowserMatch ^Mozilla/4\.0[678] no-gzip
    
                 # MSIE masquerades as Netscape, but it is fine
                 # BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    
                 # NOTE: Due to a bug in mod_setenvif up to Apache 2.0.48
                 # the above regex won't work. You can use the following
                 # workaround to get the desired effect:
                 BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    
                 # Don't compress images
                 SetEnvIfNoCase Request_URI \
                 \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary
    
                 # Make sure proxies don't deliver the wrong content
                <IfModule mod_headers.c>
                    Header append Vary User-Agent env=!dont-vary
                </IfModule>
            </IfModule>
        </Location>
    
        # For a little speed boost, you can let Apache serve (some of) your static files directly:
        Alias /static /home/alberto/yourapp/static
        Alias /favicon.ico /home/alberto/yourapp/static/images/favicon.ico
        <Location /static>
            SetHandler None
        </Location>
    
        <Directory /home/alberto/yourapp/static>
            AllowOverride None
            # FollowSymLinks is set for max. performance. For max security turn them off.
            # However, if someone can make symlink in your server, this is your least motive for concern :)
            Options -ExecCGI -Indexes -Multiviews +FollowSymLinks
            Order allow,deny
            allow from all
        </Directory>
    </VirtualHost>
    

Should get you going. Most of the configuration options don't add much to the understanding of this topic, The important stuff are the Python* directives.

Important things to consider

  • CherryPy?'s server logfile should be writable by www-data (if someone has a better solution please edit this page!, maybe dumping to stderr and let PythonDebug catch it?)
  • Use absolute paths or compute them at runtime, Apache lives at /
  • Your app will be running under the Apache user (www-data on Debian), take this into account when setting permissions and ownership...
  • You should install all you're eggs unzipped, that is, with easy_install -Z <package_name>. If you don't, Apache will try to create a .python-eggs directory in it's home dir to store an unzipped, compiled version to use. That really sucks as you'll need to give Apache permission on this directory and the idea is that the Apache user is not able to write into any executable file.

Please, if you have any suggestions on how to improve this set-up you should edit this page. If you have any suggestions on how to improve my english, do so as well :)