AppEngine 混淆 - CGI, WSGI 兼容?

1 投票
2 回答
504 浏览
提问于 2025-04-16 21:16

我有点困惑。

如果AppEngine应该能运行使用WSGI的应用程序……

# somewhere in a webapp.RequestHandler
env = dict(os.environ.items())
for key, value in env.items():
    self.response.out.write(key+': '+value+'<br/>')

req_uri = wsgiref.util.request_uri(env)

……那为什么env里面没有PEP 333列出的那些必须存在的变量呢?这导致wsgiref.util.request_uri()抛出了一个KeyError错误?

我基本上是在写一些库,这些库需要在AppEngine或者普通的Apache + modwsgi环境下都能工作。我以为只要写一个符合WSGI标准的应用就可以了,但似乎AppEngine本身……并不是这样?

2 个回答

1

据我所知,pep 333 并没有说必须把所有的 wsgi 环境变量都放进 os.environ,除非是在模拟 CGI 的情况下。它只是说 wsgi 环境变量应该包含这些内容。

在 wsgi 应用程序中,environ 字典就是传递给你的 wsgi 应用函数的部分。在 GAE(谷歌应用引擎)中,你可以通过 request.environ 来访问 wsgi environ 字典。所以我觉得你的代码应该更像这样:

# somewhere in a webapp.RequestHandler
env = self.request.environ
for key, value in env.iteritems():
    self.response.out.write(key+': '+value+'<br/>')
req_uri = wsgiref.util.request_uri(env)
4

在这里提到的 environ 是一个包含特定于 WSGI 的键的环境变量,它是传递给 WSGI 应用程序的。PEP-333 并没有要求这个值必须是 os.environ。对于 CGI 应用程序来说,很多键会出现在 os.environ 中,因为网关服务器提供了这些信息,而 CGI 到 WSGI 的网关接口(比如 wsgiref.handlers.CGIHandler)只需要在调用 WSGI 应用程序之前添加特定于 WSGI 的键。

为了更清楚地说明,当 PEP-333 提到 environ 时,它并不意味着 os.environ

编辑:google.appengine.ext.webapp.Request 显然是继承自 webob.Request。因此,webapp 处理程序可以像下面这样访问 WSGI 的 environ

class MainPage(webapp.RequestHandler):
    def get(self):
        dosomethingwith(self.request.environ)

撰写回答