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.
Apache will use WSGI file to access our Flask application, so the WSGI file allows Apache to interact with Python as if it is native.
Although Flask has a built-in web server, as we all know, it's not suitable for production and needs to be put behind a real web server able to communicate with Flask through a WSGI protocol. A common choice for that is Gunicorn—a Python WSGI HTTP server.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With