2011-07-11 54 views
1

我很困惑。AppEngine混淆 - CGI,WSGI兼容?

如果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列爲必須 -be存在的 - 導致wsgiref.util.request_uri()籌集KeyError

我基本上是編寫一些需要工作AppEngine或典型的Apache + modwsgi設置的庫。我認爲只需編寫一個兼容WSGI的應用就足夠了,但似乎AppEngine本身不是?

回答

4

必須包含WSGI特定鍵是傳遞給WSGI應用程序調用,該ENVIRON的environ。 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) 
+0

並注意當App Engine Python運行時獲得併發支持時,os.environ會變得特別不值得信任,因爲它可能包含來自另一線程服務請求的數據。 – geoffspear

+0

作爲一般規則,是關於你在哪裏得到的'environ'很迂腐,PEP-333,使一些選擇,使高度併發的,WSGI服務器可能交織相互作用在同一進程的多個請求(多線程)或即使在同一個線程中(異步),儘管我知道沒有真正的服務器在做第二個,但這一事實避免了許多框架的設計,這在任何方面都不是異步安全的。 – SingleNegationElimination

1

AFAIK pep 333沒有說強制所有的wsgi environ變量變爲os.environ,除非模擬CGI,只是wsgi environ變量應該包含這些東西。

在wsgi應用程序的上下文中,environ字典是傳遞給您的wsgi應用程序函數的部分。在GAE中,您可以通過request.environ訪問wsgi環境字典。因此,我認爲你的代碼應該更像:

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