Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting Flask to use Python3 (Apache/mod_wsgi)

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.

like image 794
P i Avatar asked Jun 04 '15 11:06

P i


People also ask

Does Flask work with Apache?

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.

Do I need WSGI for Flask?

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.


1 Answers

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.

like image 62
P i Avatar answered Sep 17 '22 00:09

P i