Robin's Blog

How to: Fix Flask WSGI webapp hanging when importing a module (such as numpy or matplotlib)

I’ve spent a long time over the last few days struggling with a problem with a Flask webapp that I’ve been developing. The app worked fine on my local computer, but when I tried to deploy it to my web server and run it via WSGI it seemed to ‘just hang’.

That is – when I visited the URL my browser said Waiting…, but there was nothing in the Apache error log or access log, it didn’t seem to have even registered that I was trying to visit the page. I had no idea what was going on, and after a long period of debugging, I found that removing some of the module imports stopped it hanging. In this case, it was removing the import for Py6S (my Python interface to the 6S Radiative Transfer Model) and matplotlib.

I had no idea why this fixed the problem, and after a lot of searching I found that it was all caused by my Apache WSGI configuration. Documenting this here will hopefully help others with the problem – and also remind me what to do next time that I want to deploy a WSGI app.

Basically, if you’ve got a directory structure like this:

/usr/local/www/wsgi-scripts

  • Web6S
    • static
      • custom.css
    • templates
      • index.html
    • web6s.py
    • web6s.wsgi

That is, a folder for the app (Web6S in this example), with the main file for the app given the same name (web6s.py), and a similarly-named WSGI file (web6s.wsgi).

The WSGI file has the following contents:

import sys
sys.path.insert(0, '/usr/local/www/wsgi-scripts/Web6S')
from web6s import app as application

which alters the Python path to add the directory that the app is in, and then imports the app object, calling it application (which is what WSGI requires).

That’s fairly simple – the harder bit is the Apache configuration. I’d suggest creating a virtualhost for this, to keep the configuration separate from your other bits of Apache configuration. My configuration is:

### WSGI for Web6S app
WSGIDaemonProcess flaskapp threads=5
WSGIScriptAlias /web6s /usr/local/www/wsgi-scripts/Web6S/web6s.wsgi process-group=flaskapp application-group=%{GLOBAL}
<Directory /usr/local/www/wsgi-scripts/Web6S>
    AllowOverride None
    Require all granted
</Directory>

Probably these bits aren’t all essential, but this is what seems to work for me. I didn’t have bits like the WSGIDaemonProcess line before, but adding them fixed it (I can’t guarantee that this is correct, but it works for me).

So, adding those lines into the correct files and restarting Apache should make it work – Good Luck!


If you found this post useful, please consider buying me a coffee.
This post originally appeared on Robin's Blog.


Categorised as: How To, Python


11 Comments

  1. The specific solution is forcing use of the main interpreter by setting the application group to %{GLOBAL}. It is documented in http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Python_Simplified_GIL_State_API

  2. Jan S says:

    Thank you so much for this! I’ve spent two days on this hanging issue too. The application-group parameter solved it. I’m just wondering, why doesn’t mod_wsgi simply run by default on the first Python interpreter? I imagine many people must have run into this issue (e.g. using Flask+scipy library like me) and it’s really difficult to find the solution. If this is not possible for some reason, they should at least include this directive in tutorials for Python frameworks that are commonly used with mod_wsgi.

  3. Jack Polo says:

    Very useful information, you saved me bro!
    I also spent several days trying solve this issue.

  4. vedanshu says:

    The application-group parameter solved it.

  5. Sarabjeet says:

    Thank you so much. You saved me đŸ™‚

  6. Gautam Ethiraj says:

    This is brilliant! This is the most important piece of information needed for mod_wsgi and its really really appalling that this is not clearly visible in the official documentation. I suspect such things drive people away from mod_wsgi. I wasted days trying to figure this out and was just about to go to gunicorn + nginx or something “more modern”. You’re an absolute hero for posting this! Thanks a ton!

  7. rohit pandey says:

    Thank you so much bro i has resolved my issue. You saved me i spend lots of time in it

  8. I struggled with the same issue recently on EC2 aws instance. Flask on Apache Server was working locally, and worked sometimes externally from curl. Thanks for sharing this solution, this works :D.

Leave a Reply

Your email address will not be published. Required fields are marked *