0

I am developing a Flask app that runs using uwsgi. I'm running into the following error ImportError: No module named google.oauth2.credentials.

When I run the Flask app using Flask's builtin dev server, the application runs without issues.

The problem seems to stem from how the google-auth module is installed. There's no __init__.py file in the google namespace folder in site-packages. The full path being /usr/local/lib/python2.7/site-packages/google.

I'm aware that python3.3 has implicit namespace packaging via PEP-420.

What I'm confused about is how the implicit namespace packaging works in python2.7. Does the installation process via pip do something special?

I'm also confused about what is different when running python2.7 via uwsgi.


Relevant versions


I've also included the following barebones test to reproduce the error.

test.ini

[uwsgi]
socket = 0.0.0.0:5001
plugins-dir = /usr/lib/uwsgi/
plugins = python
protocol = uwsgi
pythonpath = /usr/local/lib/python2.7/site-packages
callable = app
max-requests = 1000
master = True
lazy-apps = True
processes = 1

test.py

import google.oauth2.credentials

working command

python test.py

failing command

uwsgi --ini test.ini --wsgi-file test.py

failing result

When I run the above command, the program will fail due to the following ImportError.

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    import google.oauth2.credentials
ImportError: No module named google.oauth2.credentials

Current workaround

My current workaround is to manually add an __init__.py file with the following (which is what is basically what is found in the google-auth repository, but for some reason is removed when installing via pip):

try:
    import pkg_resources
    pkg_resources.declare_namespace(__name__)
except ImportError:
    import pkgutil
    __path__ = pkgutil.extend_path(__path__, __name__)

Workaround 2

Another way I got the import working was by doing this:

import site
site.addsitedir('/usr/local/lib/python2.7/site-packages')

import google.oauth2.credentials

This seems to imply that uwsgi is not fully initialization python at least on initial start up.

I got the hint to try site.addistedir from this answer: https://stackoverflow.com/a/15209116/177646

Gohn67
  • 10,608
  • 2
  • 29
  • 35

1 Answers1

0

Turns out the problem was a uWSGI configuration error on my part. Since I'm not using virtualenv, I needed to set PYTHONHOME to the correct value, which is /usr/local in my case. In the uwsgi configuration, this can be specified via the home parameter. Once this is set, then python seems to work normally.

Once the PYTHONHOME is correctly set, this allows the google_auth-1.4.1-py3.6-nspkg.pth file to be found.

This also explains why I had to always import /usr/local/lib/python2.7/site-packages in my PYTHONPATH. Once the PYTHONHOME is set, then I no longer needed to add site-packages to my PYTHONPATH.

Example:

[uwsgi]
socket = 0.0.0.0:5001
plugins-dir = /usr/lib/uwsgi/
plugins = python
protocol = uwsgi
home = /usr/local
callable = app
max-requests = 1000
master = True
lazy-apps = True
processes = 1
Gohn67
  • 10,608
  • 2
  • 29
  • 35