0%

Fix uWSGI "no python application found" on Python 3 and CentOS 7

I have been moving one of my projects from Python 2 to Python 3. Since the production environment still depends on CentOS 7, I installed Python 3 there and pointed both python and pip at the Python 3 versions. Everything looked fine at first.

The problem only showed up when I tried to start a Django service with uWSGI. The service appeared to start, but every request returned 500, and the uWSGI log showed this:

no python application found

At first the configuration looked perfectly normal:

1
2
3
4
5
6
[uwsgi]
socket = 127.0.0.1:3031
chdir = /opt/testproj/
wsgi-file = testproj/wsgi.py
processes = 4
threads = 2

So I looked more carefully at the earlier log output and found the real error:

1
2
3
4
5
6
7
*** Operational MODE: preforking+threaded ***
Traceback (most recent call last):
File "testproj/wsgi.py", line 12, in <module>
from django.core.wsgi import get_wsgi_application
ModuleNotFoundError: No module named 'django'
unable to load app 0 (mountpoint='') (callable not found or import error)
*** no app loaded. going in full dynamic mode ***

The key point is that Django was not found. So the successful startup was only an illusion: uWSGI was running, but it was not loading the actual app, which is why every request failed with 500.

Why could it not find Django if both uWSGI and Django had been installed with Python 3’s pip?

After more searching, I found that uWSGI can be tricky on systems where Python 2 and Python 3 coexist. In this case, uWSGI was starting with the Python 2 environment, so it could not see the Django installation from Python 3. The fix was to explicitly tell uWSGI where the Python 3 packages were installed.

You can find Django’s install location with:

1
pip show django | grep -i location

Example output:

1
Location: /usr/local/lib64/python3.6/site-packages

I also checked the path for pytz:

1
pip show pytz | grep -i location

Example output:

1
Location: /usr/local/lib/python3.6/site-packages

Then add both paths with pythonpath in the uWSGI configuration:

1
2
3
4
5
6
7
8
[uwsgi]
socket = 127.0.0.1:3031
chdir = /opt/testproj/
wsgi-file = testproj/wsgi.py
processes = 4
threads = 2
pythonpath = /usr/local/lib64/python3.6/site-packages
pythonpath = /usr/local/lib/python3.6/site-packages

Start it again:

1
uwsgi --ini uwsgi.ini

After that, everything worked normally.

This was a good reminder that a system with both Python 2 and Python 3 can still cause subtle problems. Even if Docker helps isolate an environment, using venv is still the cleaner long-term solution.

如果我的文字帮到了您,那么可不可以请我喝罐可乐?