2012-04-02 61 views
2

我試圖更改os.environ字典來模擬Google App Engine上的登錄用戶,如https://stackoverflow.com/a/6230083/1241454所述。Google App Engine os.environ更改需要模塊重新加載

from google.appengine.api import users 
import webapp2 
import os 

class TestPage(webapp2.RequestHandler): 
    def get(self): 
     os.environ['USER_EMAIL'] = '[email protected]' 
     user = users.get_current_user() 
     self.response.out.write(user.email()) 

這是行不通的。在上面的例子中,get_current_user()對我而言至少在開發服務器上運行時返回無。當使用testbed.setup_env()而不是直接編輯os.environ時,我會得到相同的結果。但是,下面的確實工作:

from google.appengine.api import users 
import webapp2 
import os 

class TestPage(webapp2.RequestHandler): 
    def get(self): 
     os.environ['USER_EMAIL'] = '[email protected]' 
     reload(users) 
     user = users.get_current_user() 
     self.response.out.write(user.email()) 

唯一的變化正在改變os.environ後重裝的用戶模塊。這是預期的行爲,還是我的App Engine設置有問題?我的理解是,Python/App Engine應該只加載一個加載到系統中的os模塊副本,而不是兩個。

任何想法?這對我來說非常混亂。

+0

貌似問題是,我運行上面的代碼關閉dev_appserver.py的。衛生署。 – 2012-04-06 07:35:02

回答

1

爲了澄清,os.environ是WSGI環境(或CGI的Python 2.5)正在傳遞到您的WSGI兼容的框架(在你的情況,webapp2的)爲您處理請求 - 所以每個請求只有一個環境。

您可以通過訪問http://foo-shop.appspot.com查看所有WSGI值的示例 - 這是一個簡單的Python 2.7 WSGI應用程序,顯示所有WSGI值。所有USER_ *值似乎都是使用Google帳戶進行身份驗證的具體情況。在http://www.wsgi.org/en/latest/definitions.html沒有提及它們。

https://developers.google.com/appengine/docs/python/tools/localunittesting#Changing_the_Default_Environment_Variables,文檔建議使用self.setup_env()更改專門用於測試的environ變量......並且我認爲僅測試。這不是應用程序在非測試環境中應該做的事情。

+0

是的,這可能是怎麼回事。我試圖直接從實際的開發服務器上運行測試代碼,但我想沙箱會限制修改環境。 – 2012-04-06 06:34:40

+0

爲了進一步說明問題,您的應用程序(如app.yaml中指定的)是符合WSGI標準的服務器(GAE)運行的WSGI兼容應用程序。爲了讓您的應用根據請求的環境做出決定,os.environ是傳遞環境信息的方法。運行dev_appserver.py(或生產)時,更改os.environ沒有任何意義。我希望這有助於:-) – timbo 2012-04-06 07:00:59

+0

..儘管可以想象,爲了某種中間件目的,您可能想要攔截/更改環境,但我不認爲您在此嘗試實現的目標。 – timbo 2012-04-06 07:08:49

4

你快到了。你需要的是通過overwrite=Truetestbed.setup_env()

我通常會創建一個「助手」方法,例如, login_user,這樣的事情:

def login_user(self, email, user_id, is_admin=False): 
    self.testbed.setup_env(user_email=email or '', overwrite=True) 
    self.testbed.setup_env(user_id=str(user_id) or '', overwrite=True) 
    self.testbed.setup_env(user_is_admin='1' if is_admin else '0', overwrite=True) 

def logout_user(self): 
    self.login_user(None, None) 

對OAuth的也可以(如果你需要一個太):

def login_user(self, email, user_id, is_admin=False): 
    self.testbed.setup_env(oauth_error_code='', overwrite=True) 
    self.testbed.setup_env(oauth_email=email, overwrite=True) 
    self.testbed.setup_env(oauth_user_id=str(user_id) or '', overwrite=True) 
    self.testbed.setup_env(oauth_auth_domain='example.com', overwrite=True) 
    self.testbed.setup_env(oauth_is_admin='1' if is_admin else '0', overwrite=True) 
+0

overwrite = True的好處。但即使發生這種變化,我仍然需要重新加載模塊才能生效。 – 2012-04-06 06:28:36

+0

Andrew,你在哪裏檢查get_current_user()?我的意思是,你的應用在哪個狀態。上面的代碼適用於單元測試應用程序,而不適用於dev_appserver.py – alex 2012-04-06 06:32:40

+0

我正在運行dev_appserver.py。我想這是問題的根源。 – 2012-04-06 07:35:35

相關問題