= Trac and mod_python 2.7 TracModPython setup is for Apache 2, but it may be possible to work with Apache 1.3. == Installing mod_python These instructions below have worked for: * the Apache installation that comes with MacOS 10.4 * Python 2.4.3 installed using [TracOnOsx#InstallingWithFink Fink] * Trac 0.11dev-r6202 First, make sure that the Python in the {{{$PATH}}} is the Python you want to use (you can revert it later): {{{ sudo mv /usr/bin/python /usr/bin/python.back sudo ln -s /sw/bin/python2.4 /usr/bin/python }}} Then download and build the [http://www.modpython.org/ mod_python] 2.7 module. Use the most recent 2.7 version, mine was 2.7.11: {{{ curl http://www.axint.net/apache/httpd/modpython/mod_python-2.7.11.tgz > mod_python-2.7.11.tgz tar -xzf mod_python-2.7.11.tgz cd mod_python-2.7.11 ./configure -with-apxs=/usr/sbin/apxs }}} At this stage, I had to edit the build settings, because once installed, I was getting an warning. So in {{{src/Makefile}}} I changed: {{{ CFLAGS=$(OPT) $(INCLUDES) }}} into: {{{ CFLAGS=$(OPT) $(INCLUDES) -DEAPI }}} Then do the build: {{{ make clean make sudo make install }}} {{{mod_python}}} is now installed. == Configurating and testing mod_python You must add the following lines to your {{{httpd.conf}}}: {{{ LoadModule python_module libexec/mod_python.so }}} The actual path to `mod_python.so` may vary, but make install should report at the very end exactly where `mod_python.so` was placed and how the !LoadModule directive should appear, and {{{ AddModule mod_python.c }}} You can test that everything is OK using the instructions on http://www.modpython.org/live/mod_python-2.7.8/doc-html/inst-testing.html. Then, modify the settings for your Trac instance into: {{{ SetHandler python-program PythonHandler trac.web.modpython_frontend PythonOption TracEnv /var/trac/myproject PythonOption TracUriRoot /projects/myproject }}} Of course, use your own values for {{{/projects/myproject}}} and {{{/var/trac/myproject}}}. {{{TracUriRoot}}} may not be necessary. If you remove it, you will need to modify the patch below. Restart Apache after each configuration change. == Patching Trac At this stage, opening http://localhost/projects/myproject in your browser will likely return an error 500. You can look in the {{{error_log}}} file: it is likely a Python exception, because the {{{trac.web.modpython_frontend}}} code tries to use APIs from mod_python that are different in 3.3. Here's a simple patch for {{{trac/web/modpython_frontend.py}}}. It's just a hack, but it does the job: {{{ --- /sw/lib/python2.4/site-packages/Trac-0.11dev_r6202-py2.4.egg/trac/web/modpython_frontend.py.r6202 2007-11-21 16:11:25.000000000 -0800 +++ /sw/lib/python2.4/site-packages/Trac-0.11dev_r6202-py2.4.egg/trac/web/modpython_frontend.py 2007-12-13 10:44:05.000000000 -0800 @@ -47,25 +47,14 @@ class ModPythonGateway(WSGIGateway): - wsgi_multithread = apache.mpm_query(apache.AP_MPMQ_IS_THREADED) > 0 - wsgi_multiprocess = apache.mpm_query(apache.AP_MPMQ_IS_FORKED) > 0 - def __init__(self, req, options): environ = {} environ.update(apache.build_cgi_env(req)) - if 'TracEnv' in options: - environ['trac.env_path'] = options['TracEnv'] - if 'TracEnvParentDir' in options: - environ['trac.env_parent_dir'] = options['TracEnvParentDir'] - if 'TracEnvIndexTemplate' in options: - environ['trac.env_index_template'] = options['TracEnvIndexTemplate'] - if 'TracTemplateVars' in options: - environ['trac.template_vars'] = options['TracTemplateVars'] - if 'TracLocale' in options: - environ['trac.locale'] = options['TracLocale'] + environ['trac.env_path'] = options['TracEnv'] + - if 'TracUriRoot' in options: + if True: # Special handling of SCRIPT_NAME/PATH_INFO for mod_python, which # tends to get confused for whatever reason root_uri = options['TracUriRoot'].rstrip('/') @@ -76,10 +65,6 @@ environ['SCRIPT_NAME'] = root_uri environ['PATH_INFO'] = urllib.unquote(request_uri[len(root_uri):]) - egg_cache = req.subprocess_env.get('PYTHON_EGG_CACHE') - if egg_cache: - os.environ['PYTHON_EGG_CACHE'] = egg_cache - WSGIGateway.__init__(self, environ, InputWrapper(req), _ErrorsWrapper(lambda x: req.log_error(x))) self.req = req @@ -91,17 +76,11 @@ status, headers = self.headers_sent = self.headers_set self.req.status = int(status[:3]) for name, value in headers: - if name.lower() == 'content-length': - self.req.set_content_length(int(value)) - elif name.lower() == 'content-type': + if name.lower() == 'content-type': self.req.content_type = value else: self.req.headers_out.add(name, value) - def _sendfile(self, fileobj): - self._send_headers() - self.req.sendfile(fileobj.name) - def _write(self, data): self._send_headers() try: }}} == Caveats * The patch removes a few functionalities, such as setting up the PYTHON_EGG_CACHE: if you need them, you will need to modify the patch. * There may be a character set issue: the non-ASCII chars may not be working properly. It is probably easy to fix. * In my setup, the performance was not improved by moving to {{{mod_python}}}, but it is likely an issue with the database access.