Django/Apache/mod_wsgi not using virtualenvs Python binary

2024/11/13 7:58:32

I have a virtualenv at /opt/webapps/ff/ with its own Python installation. I have WSGIPythonHome set to /opt/webapps/ff in my Apache config file (and this is definitely getting used in some capacity, because if I set it to a slightly different existing directory and restart Apache I get a 504). But if I e.g. assert False in a view somewhere to bring up the Django debug page, I see that settings.PYTHON_BIN is /usr/bin rather than /opt/webapps/ff/bin.

How do I get Apache/mod_wsgi to use my virtual environment's Python binary? I thought setting WSGIPythonHome was the way to do this, but it only seems to affect which site-packages dir is used, not which binary is used. Thanks.

Answer

These are the instructions I used which seem to be working well.

http://code.google.com/p/modwsgi/wiki/VirtualEnvironments

Using 'site.addsitedir()' is a bitdifferent to simply adding thedirectory to 'sys.path' as thefunction will open up any '.pth' fileslocated in the directory and processthem. This is necessary to ensure thatany special directories related toPython eggs are automatically added to'sys.path'.

Note that although virtualenv includesthe script 'activate_this.py', whichthe virtualenv documentation claimsshould be invoked using 'execfile()'in the context of mod_wsgi, you maywant to be cautious using it. This isbecause the script modifies'sys.prefix' which may actually causeproblems with the operation ofmod_wsgi or Python modules alreadyloaded into the Python interpreter, ifthe code is dependent on the value of'sys.prefix' not changing. TheWSGIPythonHome directive alreadydescribed should instead be used ifwanting to associate Python as a wholewith the virtual environment.

Despite that, the 'activate_this.py'script is an attempt to resolve anissue with how 'site.addsitedir()'works. That is that any newdirectories which are added to'sys.path' by 'site.addsitedir()' areactually appended to the end. Theproblem with this in the context ofmod_wsgi is that if WSGIPythonHome wasnot used to associate mod_wsgi with avirgin baseline environment, then anypackages/modules in the main Pythoninstallation will still takeprecedence over those in the virtualenvironment.

To work around this problem, what'activate_this.py' does is invoke'site.addsitedir()' but then alsoreorders 'sys.path' so any newly addeddirectories are shifted to the frontof 'sys.path'. This will then ensurethat where there are differentversions of packages in the virtualenvironment that they take precedenceover those in the main Pythoninstallation.

As explained, because'activate_this.py' is doing otherthings which may not be appropriate inthe context of mod_wsgi, if unable toset WSGIPythonHome to point mod_wsgiat a virgin baseline environment,instead of just calling'site.addsitedir()' you should use thecode:

ALLDIRS = ['usr/local/pythonenv/PYLONS-1/lib/python2.5/site-packages']import sys 
import site # Remember original sys.path.
prev_sys_path = list(sys.path) # Add each new site-packages directory.
for directory in ALLDIRS:site.addsitedir(directory)# Reorder sys.path so new directories at the front.
new_sys_path = [] 
for item in list(sys.path): if item not in prev_sys_path: new_sys_path.append(item) sys.path.remove(item) 
sys.path[:0] = new_sys_path 

If you still want to use theactivation script from virtualenv,then use:

activate_this = '/usr/local/pythonenv/PYLONS-1/bin/activate_this.py' 
execfile(activate_this, dict(__file__=activate_this))

If the fact that 'sys.prefix' has beenmodified doesn't give an issue, thengreat. If you see subtle unexplainedproblems that may be linked to thechange to 'sys.prefix', then use themore long handed approach abovewhereby 'site.addsitedir()' is useddirectly and 'sys.path' reorderdsubsequently.

Here is a discussion about this issue as well

http://groups.google.com/group/modwsgi/browse_thread/thread/466823f087070b5f?pli=1

https://en.xdnf.cn/q/72201.html

Related Q&A

How to open the users preferred mail application on Linux?

I wrote a simple native GUI script with python-gtk. Now I want to give the user a button to send an email with an attachment.The script runs on Linux desktops. Is there a way to open the users preferr…

finding a set of ranges that a number fall in

I have a 200k lines list of number ranges like start_position,stop position. The list includes all kinds of overlaps in addition to nonoverlapping ones.the list looks like this[3,5] [10,30] [15,25] [5…

Python Tornado Websocket Connections still open after being closed

I have a Tornado Websocket Server and I want to time out after 30 minutes of inactivity. I use self.close() to close the connection after 30 minutes of inactivity. But it seems that some connections st…

Vertical Print String - Python3.2

Im writing a script that will take as user inputed string, and print it vertically, like so:input = "John walked to the store"output = J w t t so a o h th l e on k re edIve written …

How to remove small particle background noise from an image?

Im trying to remove gradient background noise from the images I have. Ive tried many ways with cv2 without success.Converting the image to grayscale at first to make it lose some gradients that may hel…

Running commands from within python that need root access

I have been playing around with subprocess lately. As I do more and more; I find myself needing root access. I was wondering if there is an easy way to enter the root password for a command that needs …

How not to plot missing periods

Im trying to plot a time series data, where for certain periods there is no data. Data is loaded into dataframe and Im plotting it using df.plot(). The problem is that the missing periods get connected…

Disabling std. and file I/O in Python sandbox implementation

Im trying to set up a Python sandbox and want to forbid access to standard and file I/O. I am running the sandbox inside of a running Python server.Ive already looked at modules like RestrictedPython a…

Extract edge and communities from list of nodes

I have dataset which has more than 50k nodes and I am trying to extract possible edges and communities from them. I did try using some graph tools like gephi, cytoscape, socnet, nodexl and so on to v…

Why is this usage of python F-string interpolation wrapping with quotes?

Code in question:a = test# 1) print(f{a}) # test# 2) print(f{ {a} }) # {test}# 3) print(f{{ {a} }}) # {test}My question is, why does case two print those quotes?I didnt find anything explicitly in the…