Google App Engine os.environ更改需要重新加载模块

时间:2012-04-02 10:24:26

标签: python google-app-engine testbed

我试图更改os.environ dict以模拟Google App Engine上的登录用户,如https://stackoverflow.com/a/6230083/1241454所述。

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

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

这不起作用。 get_current_user()在上面的示例中为我返回None,至少在开发服务器上运行时是这样。使用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'] = 'a@b.c'
        reload(users)
        user = users.get_current_user()
        self.response.out.write(user.email())

唯一的变化是在更改os.environ后重新加载用户模块。这是预期的行为,还是我的App Engine设置有问题?我的理解是Python / App Engine应该只加载一个加载到系统中的os模块的副本,而不是两个。

有什么想法吗?这让我非常困惑。

2 个答案:

答案 0 :(得分:4)

你快到了。您需要的是将overwrite=True传递给testbed.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)

答案 1 :(得分:1)

为了澄清, os.environ 是传递给WSGI兼容框架的WSGI环境(或Python 2.5的CGI)(在您的情况下, 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()来专门更改环境变量以进行测试......我认为只测试。这不是应用程序在非测试环境中应该做的事情。