代码之家  ›  专栏  ›  技术社区  ›  Stefano Borini

python egg以交互方式找到,但不在fastcgi中找到

  •  1
  • Stefano Borini  · 技术社区  · 16 年前

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

    编辑 :似乎在执行fastcgi操作时,不会解析.pth文件,但这只是一个猜测。需要更多的官方声明。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Jason R. Coombs    16 年前

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

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

    此时,环境用于确定在何处查找.pth文件。如果此时没有定义pythonpath,那么它将找不到安装到sys.prefix的模块。此外,由于easy-install.pth可能安装到自定义前缀目录中,因此它找不到要分析的.pth文件。

    在解释器初始化后向os.environ或sys.path添加环境变量不会导致再次分析.pth文件。这就是为什么您发现自己被迫手动执行希望Python自然执行的操作。

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

    我寻找将pythonpath环境变量添加到mod fastcgi的选项,但没有看到这样的选项。也许这是一个通用的Apache选项,所以没有在mod\fastcgi中记录,或者可能无法在mod\fastcgi配置中设置静态变量。

    考虑到这一点,我相信您可以使用以下方法来解决问题:

    1. 创建一个包装脚本(一个shell脚本或另一个python脚本),它将成为新的fastcgi处理程序。
    2. 在这个包装脚本中,将pythonpath环境变量设置为前缀路径(就像您在工作的用户环境中设置的那样)。
    3. 让包装脚本在改变的环境中为您的原始fastcgi处理程序(mysite.fcgi)启动python进程。

    虽然我没有一个好的环境来测试,但我认为包装外壳脚本应该是这样的:

    #!/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。我不知道该怎么做,但这可能比使用包装器脚本更干净。
    • 查找允许将环境变量(pythonpath)指定给fastcgi进程的apache/mod \fastcgi选项。
        2
  •  0
  •   Jonathan Leffler    16 年前

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

        3
  •  0
  •   Jason R. Coombs    16 年前

    在IIS(Windows)下运行Python应用程序时,我遇到了类似的问题。我发现在isapi下运行时,鸡蛋是不可读的,因为安装工具会忽略压缩鸡蛋的权限,并且isapi应用程序在有限的权限帐户下运行。

    您可能在FastCGI中遇到同样的情况。如果fastcgi进程没有必要读取鸡蛋或扩展鸡蛋的权限,您可能会遇到问题。此外,我还发现,对于某些鸡蛋(尤其是具有二进制/扩展模块或必须作为文件访问的资源的鸡蛋),将python_egg_cache环境变量设置为进程可写的目录也是必要的。

        4
  •  0
  •   mhanney    15 年前

    我同意,即使定义了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'
    

    不需要使用虚拟环境。在我的共享主机提供商,我只需在~/.本地使用

    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()