Note
I only use gunicorn for development, and a monolithic mod_wsgi configuration for prod. that “works for me”!
There are several ways to serve a Python web application:
Most tools require that you application conforms to the WSGI interface.
Default relations numbers are 1
.
Given a WSGI application, it is possible to serve it in multiple ways:
There are several ways to run some Python web application on a Apache web server:
WSGIScriptAlias, to link an URL to a WSGI app.
WSGIScriptAlias /myapp /path/to/my/app/application.wsgi
should offers access to app. from http://my.domain.tld/myapp
(probably needs) access to WSGI file:
<Directory /path/to/my/app>
Order deny,allow
Allow from all
</Directory>
WSGIDaemonProcess, to run app. in its own process:
WSGIDaemonProcess mydomain-tld-myapp (...)
Note
recommended by G.D. instead of default embedded mode
Some of its options:
processes
& threads
:
WSGIDaemonProcess (...) processes=2 threads=5 (...)
(WSGIDaemonProcess continued)
user
& group
:
WSGIDaemonProcess (...) user=work group=www-data (...)
maximum-requests
:
WSGIDaemonProcess (...) maximum-requests=1000 (...)
(WSGIDaemonProcess continued)
python-path
:
WSGIDaemonProcess (...) \
python-path=/usr/lib/python2.7,/usr/local/lib/python2.7/dist-packages,(...)
which allows using a virtualenv!
Given a fresh virtualenv (e.g. called myappvenv
),
it is possible to set python-path
to its path value:
WSGIDaemonProcess (...) \
python-path=/path/to/myappvenv/lib/python2.7/site-packages
link process group to WSGI parent dir. by its name:
WSGIDaemonProcess mydomain-tld-myapp (...)
<Directory /path/to/my/app>
WSGIProcessGroup mydomain-tld-myapp
WSGIApplicationGroup %{GLOBAL}
(...)
</Directory>
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
There should be some tricky additional steps, such as:
/var/www/philologic/mydb/
,
and trying to serve it either by gunicorn or mod_wsgi…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
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'
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'
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
?
philologic.web
),
and use this namespace anywhere, instead of tweaking sys.path
setup.py
, or merge into already existing
philologic