On Aug 24, 2006, at 12:36 AM, uuellbee wrote:

> After reading the wiki page about mod_python, threads in this group,
> and the Django documentation, I finally got a mod_python setup working.
> In the end, it's pretty simple, but figuring it out wasn't much fun. I
> added an example to the bottom of the wiki page. I did that instead of
> posting it here because I figure that is the first place most people
> will look.

I agree, I switched the PylonsHQ site over yesterday, and there were 
some quirks getting it to run at the site root.

> The example there doesn't run at the site root. I figured out that you
> can run a project at the site root by removing all the DocumentRoot
> stuff (leaving it in was causing infinite redirection) and just having
> something like this in the top-level of the VirtualHost container:

Here's what my eventual setup looked like. This setup assumes you have 
Apache 2.0+ and mod_python.

First, the mod_python.wsgi script the Wiki points to needs a minor 
change. This is because it doesn't properly handle the case when 
SCRIPT_NAME isn't set in your mod_python config. The following lines 
need to be added to the file around line 110 so that the section 
dealing with SCRIPT_NAME looks like this:

     111         if 'SCRIPT_NAME' not in options:
     112             options['SCRIPT_NAME'] = ''
     113
     114         if 'SCRIPT_NAME' in options:
     115             # Override SCRIPT_NAME and PATH_INFO if requested.
     116             env['SCRIPT_NAME'] = options['SCRIPT_NAME']
     117             env['PATH_INFO'] = 
req.uri[len(options['SCRIPT_NAME']):]
     118
     119         env['wsgi.input'] = InputWrapper(req)

This way the script will properly deal with being at the root. I 
decided to avoid the .htaccess thing, so this is what the full 
VirtualHost looks like for PylonsHQ. Keep in mind I'm also serving 
non-Pylons content, which you might want to do as well (svn, trac, 
etc):

<VirtualHost *:80>
     ServerAdmin EMAIL_ADDRESS
     ServerName pylonshq.com
     DocumentRoot /home/pylonshq/pylonshq   # ROOT OF THE PYLONSHQ 
PROJECT
     CustomLog "/var/log/httpd/pylonshq.com/access_log" clf
     ErrorLog "/var/log/httpd/pylonshq.com/error_log"

     Alias /WebHelpers "/usr/local/www/pylonshq/WebHelpers"
     Alias /trac "/usr/local/share/trac/htdocs"
     Alias /files "/usr/local/www/pylonshq/files"
     Alias /project/pylonshq 
/usr/local/share/trac/cgi-bin/trac.fcgi/pylonshq
     Alias /project /usr/local/share/trac/cgi-bin/trac.fcgi/pylonshq

     # REMOVE THIS IF YOU ARENT USING mod_cache + mod_disk_cache
     CacheRoot /tmp/apachecache
     CacheSize 51200
     CacheEnable disk /style
     CacheEnable disk /img
     CacheEnable disk /scripts
     CacheEnable disk /trac/js
     CacheEnable disk /trac/css

     <Location />
         SetHandler mod_python
         PythonHandler mod_python.wsgi
         PythonPath 
"['/home/pylonshq/pylonshq','/home/pylonshq/lib/python2.4/'] + 
sys.path"
         PythonAutoReload Off
         PythonOption wsgi.application startup::app

          # Insert filter, REMOVE THIS IF YOU ARENT USING mod_deflate
         SetOutputFilter DEFLATE
         BrowserMatch ^Mozilla/4 gzip-only-text/html
         BrowserMatch ^Mozilla/4\.0[678] no-gzip
         BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
         SetEnvIfNoCase Request_URI \
         \.(?:gif|jpe?g|png)$ no-gzip dont-vary
         Header append Vary User-Agent env=!dont-vary
     </Location>

     <LocationMatch /(trac|WebHelpers|RailsHelpers|files).*>
         # HERE, WE TURN OFF PYLONS FOR THE OTHER LOCATIONS
         SetHandler None
     </LocationMatch>

     <LocationMatch /project>
         # TRAC IS RUNNING THROUGH FASTCGI
         SetHandler fastcgi-script
         Options +ExecCGI
     </LocationMatch>

     <Location "/project/pylonshq/login">
         # TRAC's LOGIN FILE
         AuthType Digest
         AuthName "PylonsHQ"
         AuthDigestFile /somewhere.htpasswd
         Require valid-user
     </Location>

     <Location /svn>
         DAV svn
         SVNPath /home/svn/pylons
         AuthType Digest
         AuthName Pylons
         AuthDigestFile /somewhere_else.htpasswd
         <LimitExcept GET PROPFIND OPTIONS REPORT>
             Require valid-user
         </LimitExcept>
     </Location>
</VirtualHost>

And the startup.py script that is inside /home/pylonshq/pylonshq:

from paste.deploy import loadapp
import os
import site
site.addsitedir('/home/pylonshq/lib/python2.4/site-packages/')

heredir = os.path.dirname(__file__)
app = loadapp("config:%s" % os.path.join(heredir, 'pylonshq.ini'))


So, things to note.

I'm not having Apache serve the projects public files (static media) 
directly. This is because having Pylons serve static content is rather 
powerful, and it can load static content from multiple paths at once, 
capabilities HTTP servers like Apache and Lighttpd do not have. To 
compensate for performance, I have mod_cache/mod_disk_cache caching the 
content under the URL's (/img, /styles, etc) so that it significantly 
lowers the load on the Python app and I get rather nice speed out of 
it. (Note, the release version of Paste does not set Last-Modified 
headers, upgrade to Paste==dev if you're using mod_cache so that the 
Last-Modified headers are set)

I have the SetHandler for the root in a Location block. This is to 
ensure that when Apache checks priorities on how to serve content under 
various URL's, I can disable Pylons for the URL root's that I want Trac 
to handle. You can add additional Location blocks for other URL spaces 
that you'd like handled differently as well, and it makes it pretty 
clean in my opinion.

The /home/pylonshq is a user by the name of 'pylonshq'. Sorry if that 
caused some confusion. This user has a virtual Python setup, thus the 
'import site, and site.addsitedir' lines in the startup.py. If you're 
not using a virtual Python setup, those lines are not needed.

I'm using a virtual user to run the site so that I can test out updates 
and such without worrying about whats system installed. If you have 
multiple virtual hosted sites running with multiple virtual Python 
package installs, you *should* use the PythonInterpreter option to have 
each virtual host use a different Python interpreter. That way you can 
avoid having Python path conflicts loading un-intended versions of a 
module. (Note that this is also suggested for multiple Django sites as 
Django though for a different reason).

I will be turning this into a doc, and likely the *recommended* 
deployment method for Pylons (and probably Paste apps in general). I 
also plan on updating the WSGI script so that the startup.py file is 
not needed. Maybe a wsgi_paste script that lets you set the ini file in 
the Apache config.

Any thoughts, questions?

Cheers,
Ben


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss
-~----------~----~----~----~------~----~------~--~---

Reply via email to