18

I'm very new to working with Flask-

according to http://flask.pocoo.org/docs/0.12/deploying/mod_wsgi/

under the heading "Working with Virtual Environments" I read:

For Python 3 add the following lines to the top of your .wsgi file:

activate_this = '/path/to/env/bin/activate_this.py'
with open(activate_this) as file_:
    exec(file_.read(), dict(__file__=activate_this)) This sets up the load paths according to the settings of the virtual environment.

Keep in mind that the path has to be absolute.

to activate my venv I use the command from linux:

 my_env/bin/activate

I looked in my my_env/bin/ directory and do not see any .py files. Am I suppose to create a .py file that in my_env/bin/ that will be called by the .wsgi file?

Timothy Lombard
  • 917
  • 1
  • 11
  • 31

3 Answers3

12

I was having the same issue, the solution is actually quite simple. You need to install libapache2-mod-wsgi-py3 instead of libapache2-mod-wsgi. The latter is for python 2.

You can then activate your environment by adding the environment's site-packages to the system path. For example, for me (using venv) I can do this by adding the following line to my *.wgsi file.

sys.path.insert(0,"/path/to/venv/lib/python3.8/site-packages")
Aaron de Windt
  • 16,794
  • 13
  • 47
  • 62
7

If you are using mod_wsgi, read the documentation at:

TLDR:

From Documentation - to use a Python virtual environment, all you need to do is add the python-home option to the WSGIDaemonProcess directive resulting in

add this line to your virtual host to enable virtualenv

WSGIDaemonProcess application_name python-home=/path/to/app/venv

okandas
  • 11,570
  • 2
  • 15
  • 17
Graham Dumpleton
  • 57,726
  • 6
  • 119
  • 134
  • 1
    Thanks Graham- after a couple of hours of focused reading the docs along with three shots of espresso, confirming that sites .conf and project .wsgi are correct, I may found the issue- the apache2/error.log reports "Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.12 configured " i'm using python3. From within my venv, I pip installed mod_wsgi but get exception: 'missing Apache httpd server packages.' % APXS) RuntimeError: The 'apxs' command appears not to be installed or is not executable. – Timothy Lombard Mar 09 '17 at 00:18
  • 1
    You need to install the 'dev' package for Apache. See system requirements in https://pypi.python.org/pypi/mod_wsgi – Graham Dumpleton Mar 09 '17 at 00:38
  • ok as per the doc, installed apache2-dev and checked it was working using mod_wsgi-express start-server with my python 3 venv- – Timothy Lombard Mar 09 '17 at 01:44
  • I see the whiskey bottle... powerful suggestion to start drinking ;-) after service apache2 restart, I still see "Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.12 configured" on the tail of the log file. – Timothy Lombard Mar 09 '17 at 01:56
  • You need to uninstall any system package for mod_wsgi and after having done ``pip install mod_wsgi`` do the steps mentioned in section 'Connecting into Apache installation' of https://pypi.python.org/pypi/mod_wsgi Have you done that? – Graham Dumpleton Mar 09 '17 at 02:13
  • pip could not find any instance of mod_wsgi in system packages- as per the section you mention: (my_3env) root@pcbevo:/var/www/pcbevo/pcbevo# mod_wsgi-express module-config LoadModule wsgi_module "/var/www/pcbevo/pcbevo/my_3env/lib/python3.5/site-packages/mod_wsgi/server/mod_wsgi-py35.cpython-35m-x86_64-linux-gnu.so" WSGIPythonHome "/var/www/pcbevo/pcbevo/my_3env" (my_3env) root@pcbevo:/var/www/pcbevo/pcbevo# mod_wsgi-express install-module LoadModule wsgi_module "/usr/lib/apache2/modules/mod_wsgi-py35.cpython-35m-x86_64-linux-gnu.so" WSGIPythonHome "/var/www/pcbevo/pcbevo/my_3env" – Timothy Lombard Mar 09 '17 at 05:40
  • error log tail still reports. Apache/2.4.18 (Ubuntu) mod_wsgi/4.3.0 Python/2.7.12 configured – Timothy Lombard Mar 09 '17 at 05:44
  • other snips from error.log tail include- mod_wsgi (pid=8341): Target WSGI script '/var/www/pcbevo/pcbevo.wsgi' cannot be loaded as Python module. mod_wsgi (pid=8341): Exception occurred processing WSGI script '/var/www/pcbevo/pcbevo.wsgi'. – Timothy Lombard Mar 09 '17 at 05:45
  • To uninstall system packages on an Ubuntu system you use ``apt-get``. See https://www.howtoinstall.co/en/ubuntu/trusty/libapache2-mod-wsgi?action=remove – Graham Dumpleton Mar 09 '17 at 06:27
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/137626/discussion-between-timothy-lombard-and-graham-dumpleton). – Timothy Lombard Mar 09 '17 at 06:38
  • Please use the mod_wsgi mailing list if after research you can't work things out. That is what the list is for. SO is not a good place to have any sort of discussion. http://modwsgi.readthedocs.io/en/develop/finding-help.html – Graham Dumpleton Mar 09 '17 at 06:40
  • @GrahamDumpleton I read that entire page along with http://blog.dscpl.com.au/2014/09/python-module-search-path-and-modwsgi.html. Should the value of `home` in `WSGIDaemonProcess example python-home=/path/to/venv home=/path/to/mysite.com` be ... the same as the value for `DocumentRoot`? This is where the main .wsgi file is located, but most of the Python files are located 1 or 2 sub-directories below it. To make sure that all of the modules are loaded properly under `mod_wsgi` (using Python 3.4.x) I wonder if I need to specify every dir involved somewhere in Apache conf, or only the top level. – Leonid Oct 12 '17 at 06:03
  • You should never place any of the Python code for your site under ``DocumentRoot`` as configure your Apache wrongly and people could download your code. So have your project separate from ``DocumentRoot``. – Graham Dumpleton Oct 12 '17 at 06:14
  • The ``home`` option to ``WSGIDaemonProcess`` is usually not required. It would only be necessary if your code doesn't follow best practices and is using relative paths to open files, rather than calculating absolute paths in some way. See http://modwsgi.readthedocs.io/en/develop/user-guides/application-issues.html#application-working-directory – Graham Dumpleton Oct 12 '17 at 06:15
  • The ``python-home`` value if using a Python virtual environment, should be what ``sys.prefix`` is set to when querying that from Python command line interpreter running against the virtual environment. – Graham Dumpleton Oct 12 '17 at 06:15
  • Instead of ``home``, what you would normally set is ``python-path``. This is used to add additional directories to the Python module search path. Ie., same as setting ``PYTHONPATH`` environment variable, or ``sys,path`` from code. If your project code is correctly set up as a package, you only need to list the parent directory of your package. That is, the directory above the directory containing the ``__init__.py`` for the top of your project package. – Graham Dumpleton Oct 12 '17 at 06:18
  • @GrahamDumpleton, thank you. Well, some of my Python scripts do read local setting(s) file(s), so it sounds like `home` is a useful setting. My other question is (I am not fully clear on this) - are `python-path`, `PYTHONPATH` and `sys.path` equivalent? It is possible that there is a precedence if more than one way is used, and there is also a question of timing. For example, is it too late to mess with `sys.path` at the time the .wsgi is being run? This is primarily in the context of making relative imports work. Could I just pre-pend an empty string to `sys.path` inside .wsgi? Thanks again. – Leonid Oct 12 '17 at 19:13
  • Even if they read local settings file, a well designed application would not use a relative path, but calculate the absolute path based on some anchor, like ``os.path.dirname(__file__)`` from code location. This is to avoid problems if any code decides to change the working directory. Similarly, using an empty string in ``sys.path`` is also bad, as it means look up relative to current directory, but if current directory changes, that will break. – Graham Dumpleton Oct 12 '17 at 21:46
  • For Apache, relying in `PYTHONPATH`` is usually a bad idea as you can't easily set it if a system Apache setup. You can update ``sys.path`` as long as done before non stdlib imports in WSGI script file. It is better to avoid change ``sys.path`` in WSGI script file though unless have good need. Use the settings in Apache/mod_wsgi configuration instead. – Graham Dumpleton Oct 12 '17 at 21:48
  • Removing the activate_this related code and adding python-home with WSGIDeamonProcess helped me move ahead. – Sid Apr 18 '21 at 08:20
3

The best and cleanest way I've found without doing some “kind of magic” with obscure scripts is to simply begin the .wsgi with the reference to the python interpreter that lies within the environment. Just start your .wsgi with this, and no need to fiddle after that:

#!/path/to/your/venv/bin/python

I wish I thought about this straightforward solution before unsuccessfully spending hours on this - and wish someone else had mentioned it.

jytou
  • 510
  • 4
  • 7