routes_wsgi.py

Send to Kindle
home » snippets » appengine » hello_world2 » routes_wsgi.py


import routes
from routes.middleware import RoutesMiddleware
import webob
import webob.exc

class WsgiToWebobMiddleware(object):
  def __init__(self, webob_app):
    self.webob_app = webob_app

  def __call__(self, environ, start_response):
    request = webob.Request(environ)
    response = self.webob_app(request)
    return response(environ, start_response)


class WsgiToRoutesWebobMiddleware(object):
  def __init__(self, webob_app):
    self.webob_app = webob_app

  def __call__(self, environ, start_response):
    request = webob.Request(environ)
    url, match_dict = environ["wsgiorg.routing_args"]
    response = self.webob_app(request, **match_dict)
    return response(environ, start_response)


class RoutesDispatcher(object):
  def __init__(self, controller_map, mapper, http_error_controller_map=None):
    self.controller_map = controller_map
    self.mapper = mapper
    if http_error_controller_map is None:
      http_error_controller_map = {}
    self.http_error_controller_map = http_error_controller_map

  def PageNotFound(self, environ, start_response):
    error_controller = self.http_error_controller_map.get(404)
    if error_controller:
      return error_controller(environ, start_response)
    else:
      return webob.exc.HTTPNotFound()(environ, start_response)

  def WsgiApp(self, environ, start_response):
    url, match_dict = environ["wsgiorg.routing_args"]
    try:
      controller = self.controller_map[match_dict.pop("controller")]
    except KeyError:
      return self.PageNotFound(environ, start_response)
    try:
      return controller(environ, start_response)
    except StopIteration:
      raise



class DispatchRule(object):
  def __init__(self, name, url, controller, **kwargs):
    self.name = name
    self.url = url
    self.controller = controller
    self.kwargs = kwargs


class DispatchRuleFactory(object):
  def __init__(self, middleware):
    self.middleware = middleware

  def __call__(self, name, url, controller, **kwargs):
    controller = self.middleware(controller)
    return DispatchRule(name, url, controller, **kwargs)


WebobDispatchRule = DispatchRuleFactory(middleware=WsgiToRoutesWebobMiddleware)


def get_middleware_app(dispatch_rules, http_error_controller_map=None):
  controller_map = {}
  mapper = routes.Mapper()
  for rule in dispatch_rules:
    controller_id = str(id(rule.controller))
    controller_map[controller_id] = rule.controller
    mapper.connect(rule.name, rule.url, controller=controller_id, **rule.kwargs)
  mapper.create_regs(controller_map.keys())
  routes_dispatcher = RoutesDispatcher(
      controller_map, mapper, http_error_controller_map)
  return RoutesMiddleware(
      routes_dispatcher.WsgiApp,
      mapper,
      use_method_override=False)