Python egg以交互方式发现,但不是fastcgi

时间:2009-09-06 02:10:28

标签: python fastcgi egg

同意this question, and its answer。我添加了鸡蛋的路径并且它起作用了。但是,当我以交互方式运行python并导入flup时,它没有任何问题或其他路径规范。区别在哪里?

编辑:在执行fastcgi时,似乎没有解析.pth文件,但这只是猜测。需要更多官方声明。

4 个答案:

答案 0 :(得分:2)

经过一些更彻底的分析后,我想我明白这里发生了什么。

当Python启动时,它会设置sys.path(所有这些都是初始化解释器的一部分)。

此时,环境用于确定在哪里找到.pth文件。如果此时未定义PYTHONPATH,则它将找不到安装到sys.prefix的模块。此外,由于easy-install.pth可能已安装到您的自定义前缀目录,因此它不会找到要解析的.pth文件。

在解释器初始化之后将环境变量添加到os.environ或sys.path不会导致再次解析.pth文件。这就是为什么你发现自己被迫手动做你希望Python自然做的事情。

我认为正确的解决方案是确保在解释器启动时(在执行mysite.fcgi之前)Python解释器可以使用自定义路径。

我查找了向mod_fastcgi添加PYTHONPATH环境变量的选项,但我看不到这样的选项。也许这是一个普通的Apache选项,因此没有在mod_fastcgi中记录,或者也许不可能在mod_fastcgi配置中设置静态变量。

鉴于此,我相信您可以通过以下方式制定解决方法:

  1. 创建一个包装脚本(一个shell脚本或另一个Python脚本),它将成为您的新FastCGI处理程序。
  2. 在此包装器脚本中,将PYTHONPATH环境变量设置为前缀路径(就像您在用户环境中设置的那样)。
  3. 让包装器脚本为改变环境的原始fastcgi处理程序(mysite.fcgi)启动Python进程。
  4. 虽然我没有一个好的环境可供测试,但我认为包装shell脚本看起来像:

    #!/bin/sh
    export PYTHONPATH=/your/local/python/path
    /path/to/python /path/to/your/fastcgi/handler  # this line should be similar to what was supplied to mod_fastcgi originally
    

    可能需要考虑其他解决方法。

    • 从mysite.fgci,使Python基于新的,改变的环境重新处理sys.path。我不知道如何做到这一点,但这可能比使用包装器脚本更清晰。
    • 找到一个Apache / mod_fastcgi选项,允许为fastcgi进程指定环境变量(PYTHONPATH)。

答案 1 :(得分:0)

与交互使用的程序相比,在Web服务器中运行的程序或在Web服务器中运行的代码具有受限制的环境。最有可能的是,差异源于您的交互式环境与FastCGI环境之间的差异。我不能告诉你的是在这种情况下哪个区别至关重要。

答案 2 :(得分:0)

我在IIS(Windows)下运行我的Python应用程序时遇到了类似的问题。我发现在ISAPI下运行时,鸡蛋是不可读的,因为setuptools会对压缩的鸡蛋授予权限,并且因为ISAPI应用程序在有限的权限帐户下运行。

您可能在FastCGI中遇到相同的情况。如果FastCGI过程无权阅读鸡蛋或根据需要扩大鸡蛋,则可能会出现问题。此外,我发现将PYTHON_EGG_CACHE环境变量设置为进程可写的目录对于某些蛋(特别是具有二进制/扩展模块的蛋或必须作为文件访问的资源)也是必需的。

答案 3 :(得分:0)

我同意,即使定义了PYTHONPATH环境变量,当python在FastCGI环境中启动时,也不会解释.pth文件。我现在不知道为什么会这样,但我确实有一个解决方法的建议。

使用site.addsitedir。它将解释.pth文件,允许您只需按名称导入鸡蛋,而无需为每个文件添加完整路径。

#!/user/bin/python2.6

import site

# adds a directory to sys.path and processes its .pth files
site.addsitedir('/home/mhanney/.local/lib/python2.6/site-packages/')

# avoids permissions error writing to system egg-cache
os.environ['PYTHON_EGG_CACHE'] = '/home/mhanney/.local/egg-cache'

没有必要使用虚拟环境。在我的共享托管服务提供商处,我只需使用

在〜/ .local中安装鸡蛋
python setup.py install --prefix=~/.local

以下是关于转换环境变量,路径和模块的flup'Hello World'示例的变体,对调试FastCGI非常有用。

#!/usr/bin/python2.6
import sys, os, site, StringIO
from pprint import pprint as p

# adds a directory to sys.path and processes its .pth files
site.addsitedir('/home/mhanney/.local/lib/python2.6/site-packages/')

# avoids permissions error writing to system egg-cache
os.environ['PYTHON_EGG_CACHE'] = '/home/mhanney/.local/egg-cache'

def test_app(environ, start_response):
    output = StringIO.StringIO()
    output.write("Environment:\n")
    for param in os.environ.keys():
        output.write("%s %s\n" % (param,os.environ[param]))
    output.write("\n\nsys.path:\n")
    p(sys.path, output)
    output.write("\n\nsys.modules:\n")
    p(sys.modules, output)
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield output.getvalue()

if __name__ == '__main__':
    from flup.server.fcgi import WSGIServer
    WSGIServer(test_app).run()