Getting Flask to use Python3 (Apache/mod_wsgi)

P i picture P i · Jun 4, 2015 · Viewed 17.5k times · Source

I've got a basic "hello world" Flask app running.

I'm on Ubuntu 14.04, using Apache 2.4. I've installed mod_wsgi.

I've created a ~/web/piFlask/venv/ to hold a virtualenv-created Python2 with flask installed.

However, I wish to have my flaskapp import a Python3.x module I have written.

What do I need to do to make this happen?

I tried creating a ~/web/piFlask/venv3/ and modifying ~/web/piFlask/piFlask.wsgi:

import os, sys

PROJECT_DIR = '/home/pi/web/piFlask'

activate_this = os.path.join(PROJECT_DIR, 'venv3/bin', 'activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
sys.path.insert(0, PROJECT_DIR)

from piFlask import app as application

application.debug = True

But I don't think this is sufficient. This .wsgi is in fact a Python file that will get executed by mod_wsgi, which I'm sure will use a Py2.x interpreter to do the execution.

So if I'm understanding correctly, mod_wsgi fires up the system Python in order to execute this .wsgi, which will in turn fire up my ~/web/piFlask/venv/ interpreter to actually process the request.

I think I could persuade mod_wsgi to use either a system Python3 or my own venv3/... by setting WSGIPythonPath /home/pi/web/piFlask/venv3/lib/python3.4/site-packages in /etc/apache2/mods-available/wsgi.conf

But I found an instruction somewhere saying you have to compile mod_wsgi for Py3, and the bottom quickly falls out to this problem.

Answer

P i picture P i · Jun 5, 2015

Took me awhile, although it was really simple in the end. Unfortunately I've lost my bash history so if you find a mistake, please leave a comment or edit in the correction.

Note that I had already got mod_wsgi working, so I had to remove it:

$ a2dismod wsgi
$ sudo apt-get remove libapache2-mod-wsgi

EDIT: Due to apt-get installing an outdated package (which results in a minor error creeping into Apache's error log) I don't at time of writing recommend this:

$ sudo apt-get install libapache2-mod-wsgi-py3
$ a2enmod wsgi

Instead, first set up your py3 virtual environment, (and might as well in install Flask into it while you're at it)

$ pip install virtualenv

$ cd ~/web/flaskapp
$ virtualenv -p python3 ./venv3
$ source ./venv3/bin/activate     #  enter virtual environment
$ pip install Flask

Now follow Installing mod_wsgi for Python3 on Ubuntu to install mod_wsgi into this venv, and ...

$ deactivate                      #  ... & exit

This was from the original apt-get approach, now it is not relevant:

Now I have to make mod_wsgi use this new Py3:

$ sudo nano /etc/apache2/mods-enabled/wsgi.conf

And do:

#WSGIPythonPath directory|directory-1:directory-2:...
WSGIPythonPath /home/pi/web/flaskapp/venv3/lib/python3.4/site-packages

Finally I need to modify my ~/web/flaskapp/flaskapp.wsgi so that it now supports Python3:

$ cat web/piFlask/piFlask.wsgi

# http://flask.pocoo.org/docs/0.10/deploying/mod_wsgi/#creating-a-wsgi-file
# http://www.enigmeta.com/2012/08/16/starting-flask/

# for Py3:
# http://askubuntu.com/questions/488529/pyvenv-3-4-error-returned-non-zero-exit-status-1

import os, sys

PROJECT_DIR = '/home/pi/web/flaskapp'
sys.path.insert(0, PROJECT_DIR)


def execfile(filename):
    globals = dict( __file__ = filename )
    exec( open(filename).read(), globals )

activate_this = os.path.join( PROJECT_DIR, 'venv3/bin', 'activate_this.py' )
execfile( activate_this )


from piFlask import app as application
application.debug = True

Just a reminder of how Apache uses mod_wsgi to execute this file when the user points their browser to http://myfoo.org/flask:

$ cat /etc/apache2/sites-available/000-default.conf
:
WSGIDaemonProcess flaskProcess user=pi group=pi threads=5
WSGIScriptAlias /flask /home/pi/web/flaskapp/flaskapp.wsgi

<Location /flask>
    WSGIProcessGroup flaskProcess
    WSGIApplicationGroup %{GLOBAL}
    Require all granted
</Location>
:

Discussion: It seems a bit messy that I am installing mod_wsgi module into Apache, but it resides in a venv3 which is inside my flaskapp folder. But this is at least ensuring Apache -> mod_wsgi -> (uses the correct i.e. venv3 Python) -> {to launch my FlaskApp}.

The alternative would be to update the system Python, and use that instead of venv.