Why does `flask_bootstrap` fail to import?

Question:

When running a flask app, Apache2’s error.log shows that the flask_bootstrap module cannot be found:

[wsgi:warn] mod_wsgi: Compiled for Python/2.7.11.
[wsgi:warn] mod_wsgi: Runtime using Python/2.7.12.
[mpm_event:notice] AH00489: Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.12 configured -- resuming normal operations
[core:notice] AH00094: Command line: '/usr/sbin/apache2'
[wsgi:error] mod_wsgi (pid=18587): Target WSGI script '/var/www/myapp/myapp.wsgi' cannot be loaded as Python module.
[wsgi:error] mod_wsgi (pid=18587): Exception occurred processing WSGI script '/var/www/myapp/myapp.wsgi'.
[wsgi:error] Traceback (most recent call last):
[wsgi:error]   File "/var/www/myapp/myapp.wsgi", line 7, in <module>
[wsgi:error]     from myapp import app as application 
[wsgi:error]   File "/var/www/myapp/myapp/__init__.py", line 2, in <module>
[wsgi:error]     from flask_bootstrap import Bootstrap
[wsgi:error] ImportError: No module named flask_bootstrap

I have configured the venv as per myapp.conf

<VirtualHost *:80>
ServerName yourdomain.com
ServerAdmin [email protected]

WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}

WSGIScriptAlias / /var/www/myapp/myapp.wsgi
WSGIDaemonProcess myapp python-home=/var/www/myapp/myapp/venv

<Directory /var/www/myapp/myapp/>
    Order allow,deny
    Allow from all
</Directory>

ErrorLog ${APACHE_LOG_DIR}/error.log
LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

The module is available both system wide and in the venv:

root@host:/var/www/myapp# python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask_bootstrap import Bootstrap
>>> Bootstrap
<class 'flask_bootstrap.Bootstrap'>

And…

root@host:/var/www/myapp# source myapp/venv/bin/activate
(venv) root@host:/var/www/myapp# python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from flask_bootstrap import Bootstrap
>>> Bootstrap
<class 'flask_bootstrap.Bootstrap'>

I note that there is a warning about the 2.7.11 vs 2.7.12 mismatch, but is the minor version really the issue?

Edit 1

As per the docs, added the following to myapp.wsgi

activate_this = '/var/www/myapp/myapp/venv/bin/activate_this.py'
execfile(activate_this, dict(__file__=activate_this))

Didn’t make any difference.

Asked By: Bridgey

||

Answers:

NOTE: This Answer, after being posted, was discovered by @Bridgey to be wrong. See his other Answer.


It turns out that the problem was that the two lines:

WSGIProcessGroup myapp
WSGIApplicationGroup %{GLOBAL}

should have been inside the <Directory>!

So, the myapp.conf now looks like this:

<VirtualHost *:80>
        ServerName yourdomain.com

        WSGIDaemonProcess myapp python-home=/var/www/myapp/myapp/venv
        WSGIScriptAlias / /var/www/myapp/myapp.wsgi

        <Directory /var/www/myapp/myapp>
                WSGIProcessGroup myapp
                WSGIApplicationGroup %{GLOBAL}
                Order deny,allow
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

In fairness, this is as per the example in the docs.

Big thanks to all those who commented 🙂

Answered By: Bridgey

So, after Graham persuading me that my “fix” (moving the two lines into the <Directory> directive) was not really the fix and probably a sign something else was wrong, I decided to dig deeper.

Following the docs, specifically confirming the location of the virtual environment, I was surprised to discover that when activating the virtual environment on my local box (not via the wsgi app):

sys.prefix = '/usr'

when I expected it to be:

sys.prefix = '/var/www/myapp/myapp/venv'

I have no idea how this occurred. Maybe a result of doing all the initial work as root.

However, pleased to say that deleting and remaking the virtual environment, this time as a normal user, everything seems good.

Answered By: Bridgey