2009-09-06 26 views

回答

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. 讓包裝腳本啓動Python進程,爲原始fastcgi處理程序(mysite.fcgi)更改環境。

雖然我沒有在測試一個良好的環境,我覺得一個包裝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。我不知道這將如何完成,但這可能比有包裝腳本更清潔。
  • 查找允許將環境變量(PYTHONPATH)指定給fastcgi進程的Apache/mod_fastcgi選項。
0

與您交互使用的程序相比,由Web服務器運行或運行的程序的環境受限制。最有可能的差異源於您的交互式環境和FastCGI環境之間的差異。我不能告訴你的是,在這種情況下哪個區別至關重要。

0

我在IIS(Windows)下運行我的Python應用程序時遇到過類似的問題。我發現,在ISAPI下運行時,雞蛋不可讀,因爲setuptools會壓縮壓縮雞蛋的權限,並且因爲ISAPI應用程序在有限的特權帳戶下運行。

您可能在FastCGI中遇到同樣的情況。如果FastCGI進程沒有權限讀取雞蛋或根據需要展開雞蛋,則可能會出現問題。另外,我發現將PYTHON_EGG_CACHE環境變量設置爲可由進程寫入的目錄對於某些雞蛋(特別是具有二進制/擴展模塊或必須作爲文件訪問的資源的雞蛋)也是必需的。

+0

事實上雞蛋已經在我的網站包目錄中擴展了。我沒有看到爲什麼它不起作用,除了.pth文件完全被忽略 – 2009-09-06 09:29:41

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' 

這是沒有必要使用虛擬環境。在我的共享託管服務提供商我只是用

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