我想要做的是根据请求域加载不同的应用程序(webapp2.WSGIApplication)。
例如www.domain_1.com应该在app1.main.application中加载应用程序,而www.domain_2.com应该加载app2.main.appplication。
当然我在相同的GAE appid上,我使用命名空间来分隔应用数据。
这对'threadsafe:false'和一个runner.py文件非常有用,其中函数确定要返回的应用程序
似乎'threadafe:true'第一个请求将wsgiapplication加载到实例中,并且进一步请求不再执行'application dispatching'逻辑,以便请求从错误的应用程序获得响应。
即时通讯使用python2.7和webapp2
这样做的最佳方式是什么?
修改
我的runner.py的简化版本
def main():
if domain == 'www.mydomain_1.com':
from app_1 import application
namespace = 'app_1'
elif domain == 'www.domain_2.com':
from app_2 import application
namespace = 'app_2'
namespace_manager.set_namespace(namespace)
return wsgiref.handlers.CGIHandler().run(application)
if __name__ == '__main__':
main()
和app.yaml
- url: /.*
script: app-runner.py
答案 0 :(得分:0)
您的跑步者脚本是CGI脚本。没有记录启用多线程的CGI脚本的完整行为,以及编写文档的方式我猜测这将不会得到完全支持。相反,文档说当你打开多线程时,你必须直接从app.yaml
引用WSGI应用程序对象,使用包含该对象的全局变量的模块路径。 (CGI脚本在Python 2.7中保留了旧的行为,并关闭了多线程。)
您看到的行为可以通过使用导入来解释。在单个实例中,每个import语句仅在第一次遇到时生效。之后,假定导入模块,并且import语句对后续请求没有影响。您可以将这两个值导入单独的名称,然后使用适当的值调用run()
。
但是如果你想启用多线程(这是一个好主意),你的调度程序应该是一个WSGI应用程序本身,存储在app.yaml
引用的模块全局中。我不知道如何从WSGI应用程序中向另一个WSGI应用程序发送请求,但这可能是一件合理的事情。或者,您可以考虑使用或构建WSGI上方的层来执行此调度。
答案 1 :(得分:0)
通过继承webapp2.WSGIApplication并覆盖在调度到RequestHandler之前调用的__call__()
来实现。
为路由添加前缀(并删除处理程序初始化中的前缀)和子结构配置以便能够使用实例内存。
class CustomWSGIApplication(webapp2.WSGIApplication):
def __call__(self, environ, start_response):
routes, settings, ns = get_app(environ)
namespace_manager.set_namespace(ns)
environ['PATH_INFO'] = '/%s%s' %(ns, environ.get('PATH_INFO'))
for route in routes:
r, h = route # returns a tuple with mapping and handler
newroute = ('/%s%s'%(ns, r), h,)
self.router.add(newroute)
if settings:
self.config[ns] = settings
self.debug = debug
with self.request_context_class(self, environ) as (request, response):
try:
if request.method not in self.allowed_methods:
# 501 Not Implemented.
raise exc.HTTPNotImplemented()
rv = self.router.dispatch(request, response)
if rv is not None:
response = rv
except Exception, e:
try:
# Try to handle it with a custom error handler.
rv = self.handle_exception(request, response, e)
if rv is not None:
response = rv
except HTTPException, e:
# Use the HTTP exception as response.
response = e
except Exception, e:
# Error wasn't handled so we have nothing else to do.
response = self._internal_error(e)
try:
return response(environ, start_response)
except Exception, e:
return self._internal_error(e)(environ, start_response)