A (very) short intro. to mod_wsgi


Vincent Férotin, 2013-03-01
UPR76, CNRS
for the ARTFL project & PhiloLogic

Content

Preliminaries

Outline:
  1. a bit of context on serving Python web applications
  2. some mod_wsgi configuration options
  3. current state with PhiloLogic4
Disclaimer:

Note

I only use gunicorn for development, and a monolithic mod_wsgi configuration for prod. that “works for me”!

Serving a Python web app.

There are several ways to serve a Python web application:

Most tools require that you application conforms to the WSGI interface.

WSGI

System-wide VS virtualenv


_images/sys-venv.png

Default relations numbers are 1.

Serving a WSGI app.

Given a WSGI application, it is possible to serve it in multiple ways:

Apache httpd and Python

There are several ways to run some Python web application on a Apache web server:

mod_wsgi

=> http://code.google.com/p/modwsgi/

Configuration (1)

Configuration (2)

Configuration (3)

Configuration (4)

Configuration (5)

Full example

WSGIDaemonProcess mydomain-tld-myapp \
    processes=2 threads=5 \
    python-path=/path/to/myappvenv/lib/python2.7/site-packages \
    user=work group=www-data \
    maximum-requests=1000 \
    display-name=%{GROUP}

<Directory /path/to/my/app>
    WSGIProcessGroup mydomain-tld-myapp
    WSGIApplicationGroup %{GLOBAL}
    Order deny,allow
    Allow from all
</Directory>

WSGIScriptAlias /myapp /path/to/my/app/application.wsgi

Addendum

There should be some tricky additional steps, such as:

RTFantasticMaintainer’s

PhiloLogic4 and mod_wsgi

Quick test (0) WSGI file

Given the following WSGI module, put into /var/www/philologic/mydb/app.py, next dispatcher.py and its friends (data/, templates/, etc.):

import sys

sys.path.append('/var/www/philologic/mydb')
from dispatcher import philo_dispatcher as application

and its following link app.wsgi:

/var/www/philologic/mydb $ ln -s app.py app.wsgi

Quick test (1) gunicorn (app.py)

/var/www/philologic/mydb $ gunicorn app
(...)
[ERROR] Error handling request
Traceback (most recent call last):
File "/var/www/philologic/mydb/dispatcher.py", line 20, in philo_dispatcher
    yield getattr(reports, report or "navigation")(environ,start_response)
File "/var/www/philologic/mydb/reports/navigation.py", line 17, in navigation
    db, dbname, path_components, q = wsgi_response(environ,start_response)
File "/var/www/philologic/mydb/functions/wsgi_handler.py", line 18, in wsgi_response
    myname = environ["SCRIPT_FILENAME"]
KeyError: 'SCRIPT_FILENAME'

Quick test (2) mod_wsgi (app.wsgi)

Internal Server Error

/var/log/apache2 $ tail error.log
(...)
mod_wsgi: Exception occurred processing WSGI script '/var/www/philologic/mydb/app.wsgi'.
Traceback (most recent call last):
  File "/var/www/philologic/mydb/dispatcher.py", line 24, in philo_dispatcher
    yield reports.form(environ,start_response)
  File "/var/www/philologic/mydb/reports/form.py", line 11, in form
    return render_template(db=db,dbname=dbname,form=True, template_name='form.mako')
  File "/var/www/philologic/mydb/reports/render_template.py", line 12, in render_template
    template = Template(filename="templates/%s" % data['template_name'], lookup=templates)
  (...)
IOError: [Errno 2] No such file or directory: 'templates/form.mako'

virtualenv installation test

Given virtualenvwrapper installed:

$ mkvirtualenv philologic
$ # virtualenv 'philologic' activated
$ # install libphilo
$ cd libphilo
$ make install exec_prefix=/path/to/virtualenvs/philologic
$ # install python bindings
$ cd ../python
$ python setup.py install
$ # install web application
$ cd ../www
$ pip install Mako BeautifulSoup

But… how pip install philologic-webapp?

ToDo?

  1. make PhiloLogic4 runnable under mod_wsi, and let web app. closed to a specific database, which probably only needs:
    • fix environment variables and paths
  2. and/or create an installable package for web app.
    • create a true Python package namespace (e.g. philologic.web), and use this namespace anywhere, instead of tweaking sys.path
    • write a dedicated setup.py, or merge into already existing philologic