Django / Apache / mod_wsgi没有使用virtualenv的Python二进制文件

时间:2022-09-17 07:56:54

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.

我在/ opt / webapps / ff /上有一个virtualenv,它有自己的Python安装。我在我的Apache配置文件中将WSGIPythonHome设置为/ opt / webapps / ff(这肯定会在某些容量中使用,因为如果我将它设置为稍微不同的现有目录并重新启动Apache,我会得到504)。但是如果我在某个视图中断言False以显示Django调试页面,我看到settings.PYTHON_BIN是/ usr / bin而不是/ 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.

如何让Apache / mod_wsgi使用我的虚拟环境的Python二进制文件?我认为设置WSGIPythonHome是这样做的方法,但它似乎只影响使用哪个site-packages目录,而不是使用哪个二进制文件。谢谢。

4 个解决方案

#1


8  

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 bit different to simply adding the directory to 'sys.path' as the function will open up any '.pth' files located in the directory and process them. This is necessary to ensure that any special directories related to Python eggs are automatically added to 'sys.path'.

使用'site.addsitedir()'与简单地将目录添加到'sys.path'有点不同,因为该函数将打开位于目录中的任何'.pth'文件并处理它们。这是确保将与Python egg相关的任何特殊目录自动添加到“sys.path”所必需的。

Note that although virtualenv includes the script 'activate_this.py', which the virtualenv documentation claims should be invoked using 'execfile()' in the context of mod_wsgi, you may want to be cautious using it. This is because the script modifies 'sys.prefix' which may actually cause problems with the operation of mod_wsgi or Python modules already loaded into the Python interpreter, if the code is dependent on the value of 'sys.prefix' not changing. The WSGIPythonHome directive already described should instead be used if wanting to associate Python as a whole with the virtual environment.

请注意,虽然virtualenv包含脚本'activate_this.py',virtualenv文档声称应该在mod_wsgi的上下文中使用'execfile()'调用,但您可能需要谨慎使用它。这是因为脚本修改了'sys.prefix',如果代码依赖于'sys.prefix'的值没有改变,它实际上可能导致mod_wsgi或已经加载到Python解释器中的Python模块的操作出现问题。如果想要将Python作为一个整体与虚拟环境相关联,则应该使用已经描述的WSGIPythonHome指令。

Despite that, the 'activate_this.py' script is an attempt to resolve an issue with how 'site.addsitedir()' works. That is that any new directories which are added to 'sys.path' by 'site.addsitedir()' are actually appended to the end. The problem with this in the context of mod_wsgi is that if WSGIPythonHome was not used to associate mod_wsgi with a virgin baseline environment, then any packages/modules in the main Python installation will still take precedence over those in the virtual environment.

尽管如此,'activate_this.py'脚本试图解决'site.addsitedir()'如何工作的问题。也就是说,'site.addsitedir()'添加到'sys.path'的任何新目录实际上都附加到了结尾。在mod_wsgi的上下文中,这个问题是如果WSGIPythonHome没有用于将mod_wsgi与原始基线环境相关联,那么主Python安装中的任何包/模块仍然优先于虚拟环境中的那些。

To work around this problem, what 'activate_this.py' does is invoke 'site.addsitedir()' but then also reorders 'sys.path' so any newly added directories are shifted to the front of 'sys.path'. This will then ensure that where there are different versions of packages in the virtual environment that they take precedence over those in the main Python installation.

要解决这个问题,'activate_this.py'所做的是调用'site.addsitedir()',然后重新排序'sys.path',这样任何新添加的目录都会转移到'sys.path'的前面。这将确保在虚拟环境中存在不同版本的软件包时,它们优先于主Python安装中的软件包。

As explained, because 'activate_this.py' is doing other things which may not be appropriate in the context of mod_wsgi, if unable to set WSGIPythonHome to point mod_wsgi at a virgin baseline environment, instead of just calling 'site.addsitedir()' you should use the code:

正如所解释的那样,因为'activate_this.py'在mod_wsgi的上下文中执行其他可能不合适的事情,如果无法将WSGIPythonHome设置为在原始基线环境中指向mod_wsgi,而不是仅仅调用'site.addsitedir()'你应该使用代码:

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 the activation script from virtualenv, then use:

如果您仍想使用virtualenv中的激活脚本,请使用:

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 been modified doesn't give an issue, then great. If you see subtle unexplained problems that may be linked to the change to 'sys.prefix', then use the more long handed approach above whereby 'site.addsitedir()' is used directly and 'sys.path' reorderd subsequently.

如果'sys.prefix'被修改的事实没有给出问题,那么很好。如果你看到可能与'sys.prefix'的更改有关的细微的无法解释的问题,那么使用上面更长的方法,直接使用'site.addsitedir()',然后重新排序'sys.path'。

Here is a discussion about this issue as well

以下是对此问题的讨论

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

#2


2  

If you're using a virtualenv, you need to be sure to activate it within the WSGI script.

如果您使用的是virtualenv,则需要确保在WSGI脚本中激活它。

venv_path = "/opt/webapps/ff"
activate_this = os.path.join(venv_path, "bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))

#3


1  

I had the same situation in a Pylons app and ended up using /usr/bin binary plus virtualenv site-packages dir instead.

我在Pylons应用程序中遇到了相同的情况,最后使用/ usr / bin二进制加上virtualenv site-packages目录。

Of course it was the same python version...

当然它是相同的python版本......

#4


0  

I have encountered the same issue when installing modoboa (django based) in virtualenv.

我在virtualenv中安装modoboa(基于django)时遇到了同样的问题。

It took me a lot of time to find a clear answer, so I will post it here.

我花了很多时间找到一个明确的答案,所以我会在这里发布。

All I needed to do was adding two lines to the general apache conf file (/etc/httpd/conf/httpd.conf in CentOS):

我需要做的就是在常规apache conf文件中添加两行(CentOS中的/etc/httpd/conf/httpd.conf):

WSGISocketPrefix /var/run/wsgi ## (location for the PID)
WSGIPythonHome /path/to/virtualenv 

And restart Apache

并重新启动Apache

#1


8  

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 bit different to simply adding the directory to 'sys.path' as the function will open up any '.pth' files located in the directory and process them. This is necessary to ensure that any special directories related to Python eggs are automatically added to 'sys.path'.

使用'site.addsitedir()'与简单地将目录添加到'sys.path'有点不同,因为该函数将打开位于目录中的任何'.pth'文件并处理它们。这是确保将与Python egg相关的任何特殊目录自动添加到“sys.path”所必需的。

Note that although virtualenv includes the script 'activate_this.py', which the virtualenv documentation claims should be invoked using 'execfile()' in the context of mod_wsgi, you may want to be cautious using it. This is because the script modifies 'sys.prefix' which may actually cause problems with the operation of mod_wsgi or Python modules already loaded into the Python interpreter, if the code is dependent on the value of 'sys.prefix' not changing. The WSGIPythonHome directive already described should instead be used if wanting to associate Python as a whole with the virtual environment.

请注意,虽然virtualenv包含脚本'activate_this.py',virtualenv文档声称应该在mod_wsgi的上下文中使用'execfile()'调用,但您可能需要谨慎使用它。这是因为脚本修改了'sys.prefix',如果代码依赖于'sys.prefix'的值没有改变,它实际上可能导致mod_wsgi或已经加载到Python解释器中的Python模块的操作出现问题。如果想要将Python作为一个整体与虚拟环境相关联,则应该使用已经描述的WSGIPythonHome指令。

Despite that, the 'activate_this.py' script is an attempt to resolve an issue with how 'site.addsitedir()' works. That is that any new directories which are added to 'sys.path' by 'site.addsitedir()' are actually appended to the end. The problem with this in the context of mod_wsgi is that if WSGIPythonHome was not used to associate mod_wsgi with a virgin baseline environment, then any packages/modules in the main Python installation will still take precedence over those in the virtual environment.

尽管如此,'activate_this.py'脚本试图解决'site.addsitedir()'如何工作的问题。也就是说,'site.addsitedir()'添加到'sys.path'的任何新目录实际上都附加到了结尾。在mod_wsgi的上下文中,这个问题是如果WSGIPythonHome没有用于将mod_wsgi与原始基线环境相关联,那么主Python安装中的任何包/模块仍然优先于虚拟环境中的那些。

To work around this problem, what 'activate_this.py' does is invoke 'site.addsitedir()' but then also reorders 'sys.path' so any newly added directories are shifted to the front of 'sys.path'. This will then ensure that where there are different versions of packages in the virtual environment that they take precedence over those in the main Python installation.

要解决这个问题,'activate_this.py'所做的是调用'site.addsitedir()',然后重新排序'sys.path',这样任何新添加的目录都会转移到'sys.path'的前面。这将确保在虚拟环境中存在不同版本的软件包时,它们优先于主Python安装中的软件包。

As explained, because 'activate_this.py' is doing other things which may not be appropriate in the context of mod_wsgi, if unable to set WSGIPythonHome to point mod_wsgi at a virgin baseline environment, instead of just calling 'site.addsitedir()' you should use the code:

正如所解释的那样,因为'activate_this.py'在mod_wsgi的上下文中执行其他可能不合适的事情,如果无法将WSGIPythonHome设置为在原始基线环境中指向mod_wsgi,而不是仅仅调用'site.addsitedir()'你应该使用代码:

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 the activation script from virtualenv, then use:

如果您仍想使用virtualenv中的激活脚本,请使用:

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 been modified doesn't give an issue, then great. If you see subtle unexplained problems that may be linked to the change to 'sys.prefix', then use the more long handed approach above whereby 'site.addsitedir()' is used directly and 'sys.path' reorderd subsequently.

如果'sys.prefix'被修改的事实没有给出问题,那么很好。如果你看到可能与'sys.prefix'的更改有关的细微的无法解释的问题,那么使用上面更长的方法,直接使用'site.addsitedir()',然后重新排序'sys.path'。

Here is a discussion about this issue as well

以下是对此问题的讨论

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

#2


2  

If you're using a virtualenv, you need to be sure to activate it within the WSGI script.

如果您使用的是virtualenv,则需要确保在WSGI脚本中激活它。

venv_path = "/opt/webapps/ff"
activate_this = os.path.join(venv_path, "bin/activate_this.py")
execfile(activate_this, dict(__file__=activate_this))

#3


1  

I had the same situation in a Pylons app and ended up using /usr/bin binary plus virtualenv site-packages dir instead.

我在Pylons应用程序中遇到了相同的情况,最后使用/ usr / bin二进制加上virtualenv site-packages目录。

Of course it was the same python version...

当然它是相同的python版本......

#4


0  

I have encountered the same issue when installing modoboa (django based) in virtualenv.

我在virtualenv中安装modoboa(基于django)时遇到了同样的问题。

It took me a lot of time to find a clear answer, so I will post it here.

我花了很多时间找到一个明确的答案,所以我会在这里发布。

All I needed to do was adding two lines to the general apache conf file (/etc/httpd/conf/httpd.conf in CentOS):

我需要做的就是在常规apache conf文件中添加两行(CentOS中的/etc/httpd/conf/httpd.conf):

WSGISocketPrefix /var/run/wsgi ## (location for the PID)
WSGIPythonHome /path/to/virtualenv 

And restart Apache

并重新启动Apache