55

I'm currently developing my first real python flask project and am about to set up the build server to deploy the "Latest Build" which is built on every check-in.

I have set up a startup script where I start the application using uwsgi and this part is working fine. I have recently also started using virtualenv and by doing so the packages installed are added to my project under projectname\flask\Lib\site-packages.

I'm using nginx as the web server and the config looks like this:

location / { try_files $uri @graderbuild; }
location @graderbuild {
    include uwsgi_params;
    uwsgi_param UWSGI_CHDIR /usr/local/grader/build;
    uwsgi_param UWSGI_PYHOME /usr/local/grader/build;
    uwsgi_pass 127.0.0.1:3031;
}

I'm starting uwsgi using this:

exec /usr/local/bin/uwsgi --master --socket 127.0.0.1:3031
    --wsgi-file restserver.py --callable app --processes 4 --die-on-term
    --threads 2 >> /var/log/grader-build.log 2>&1

Now to where I know if I'm doing it right... currently I am deploying the entire folder to the build server. I don't want to install global python modules just to get my build to work. Right or wrong?

The error I get currently is:

ImportError: No module named flask_wtf

If I'm right, how do I configure the setup to use the virtualenv site-packages? My preferred location would be in the startup script and not in the nginx config.

Asken
  • 7,679
  • 10
  • 45
  • 77

6 Answers6

70

Use -H to set virtualenv to python path.

uwsgi -H /path/to/your/virtualenv 

http://uwsgi-docs.readthedocs.org/en/latest/Options.html#virtualenv

iMom0
  • 12,493
  • 3
  • 49
  • 61
20

To use the activated virtualenv you can use this config snippet in your uwsgi.ini:

; If VIRTUAL_ENV is set then use its value to specify the virtualenv directory
if-env = VIRTUAL_ENV
virtualenv = %(_)
endif =
ZdaR
  • 22,343
  • 7
  • 66
  • 87
Beau
  • 11,267
  • 8
  • 44
  • 37
  • 3
    This is the best solution if you use virtualenv as it has also the flexibility to work in different environment (production/staging/development) with different venv names! – Alain1405 Dec 09 '15 at 14:10
  • 1
    `pipenv` creates dynamically named virtualenvs, so I suspect this approach will increasingly be more common as adoption of `pipenv` continues. – paperreduction Jan 06 '18 at 05:53
  • Case of command line translates into `uwsgi --virtualenv $VIRTUAL_ENV etc` – m3nda Nov 16 '21 at 00:10
12

As user995394 pointed out, there is a way to tell uWSGI use existing virtual environment. However, when I pass uWSGI option in form virtualenv = /full/path/to/my/virtualenv (it's from INI config) it complains about ImportError: No module named site. The workaround I found is that you launch uWSGI from folder where your virtualenv is and pass just virtualenv = my_virtualenv_name (i.e. path is relative).

I use uWSGI 2.0.

Community
  • 1
  • 1
Palasaty
  • 5,181
  • 1
  • 26
  • 22
  • Could you give a specific example of my_virtualenv-name? I use virtualenvwrapper, and I have tried the path ~/.virtualenvs/a-virtualenv-created-by-virtualenvwrapper/ and the name a-virtualenv-created-by-virtualenvwrapper, it's not work. – attolee Oct 07 '15 at 09:23
  • @attolee, try the path `~/.virtualenvs/` and the option `virtualenv = a-virtualenv-created-by-virtualenvwrapper` – Palasaty Oct 07 '15 at 09:50
  • 1
    it doesn't work. I got the output, `Python version: 2.7.6 (default, Jun 22 2015, 18:01:27) [GCC 4.8.2] Set PythonHome to ~/.virtualenvs/ ImportError: No module named site`, and `Python version: 2.7.6 (default, Jun 22 2015, 18:01:27) [GCC 4.8.2] Set PythonHome to python3.4.3-uwsgi-django1.8-nginx ImportError: No module named site `, by the way, i also use pyenv to manage python version. – attolee Oct 07 '15 at 10:05
  • `~/.virtualenvs/a-virtualenv-created-by-virtualenvwrapper/` works. – attolee Oct 07 '15 at 13:09
  • @attolee Its same with me , best solution is to activate the environment manually. – TheExorcist Dec 25 '17 at 07:36
  • I faced the same problem. In my case, I was using python3. so, installing uwsgi with pip3 instead of pip solved the issue – viswanath Jul 01 '19 at 17:45
7

Others' answers didn't help, and I added path to virtualenv to uwsgi.ini configuration file. The error disappeared.

pythonpath = /path-to-virtualenv/project/lib/python2.7/site-packages
Yaroslav Nikitenko
  • 1,695
  • 2
  • 23
  • 31
  • This helped a little bit. My particular setup was complaining about not being able to import from celery. With this addition I am unable to import from a binary package (specifically psycopg2-binary). At least I have more information. – Árni St. Steinunnarson Jan 10 '23 at 13:53
1

I had this issue a few months back and have a full example of demo configs here including nginx, uwsgi starting automatically with upstart on linux.

https://stackoverflow.com/a/27221427/567606

Community
  • 1
  • 1
tourdownunder
  • 1,779
  • 4
  • 22
  • 34
0

Beau's answer resolved this issue for me.

I never did find a good explanation for uwsgi's ini file directives.

Until Beau's answer I never saw an answer to what explicitly the virtualenv value should be set to - the root of the python tree in the venv, the app's folder under site-packages or the root of the VENV TREE. What if you aren't using a venv, what do you set home to, top of app tree, top of python bin folder, python lib folder or to dist-packages?

I have this app working on another system, so it really shouldn't have been that difficult to run it under a docker container. Now that I have got it working I reviewed that working installation and now see it points to the top of the venv tree. I was using virtualenvwrapper there, so it's a different path than when using only virtualenv.

It makes me wonder if it's possible to run this app without the venv. Since this will run in a docker container there isn't really a good reason to use venvs, but in looking at the python folder structure differences they are quite different between system python and venv python.

System's python3 is split into separate folders and the files are not all under a single hierarchy as they are under a venv. If you install your packages with pip they will end up in /usr/local/lib/python3/dist-packages, and that location does NOT have site.py or encodings folders which is why so many have import errors.

After only a few trials I discovered that to run my app without a venv the uwsgi ini should NOT define either home OR virtualenv settings. If your system path includes both /usr/bin AND /usr/local/bin it should work and find everything, even tho pip installed packages go somewhere else with a different folder hierarchy.

  • What's the purpose of this message on SO? – Denys Kotsur Apr 24 '18 at 20:08
  • Not sure I understand your question of purpose. This answer was directly related to the OP topic, but I have insufficient rep yet to simply comment, so I had to write an answer to provide input. Paragraphs starting with "It makes me wonder" and "System's python3" are the main points of new info I provided in hopes it saves others the time it took me to figure this out. I can comment to your comment but not to any other? Hmmm... – user4830534 Apr 25 '18 at 16:48
  • @user4830532 Try not to use your feelings and opinions, just use facts. [Here](https://stackoverflow.com/help/deleted-answers) you can find explanation why your answer can be downvoted and deleted afterwards. – Denys Kotsur Apr 25 '18 at 16:59
  • OK, point taken Denys Kotsur. I edited my post to remove the emotional baggage. – user4830534 Apr 25 '18 at 17:41