3

我有一个典型的 WSGI 应用程序,如下所示:

app = webapp2.WSGIApplication([
    ('/site/path/one',     'package.module.ClassOne'),
    ('/site/path/two',     'package.module.ClassTwo'),
    ('/site/path/three',   'package.module.ClassThree'),
])

我希望稍后能够在我的应用程序中检索路由列表,例如在 ClassOne 中:

class ClassOne(webapp2.RequestHandler):
    def get(self):
        print ''' list of routes (e.g. '/site/path/one', '/site/path/two', etc.) '''
4

2 回答 2

4

看起来 WSGIApplication 有一个路由器属性

路由器

def __repr__(self):
        routes = self.match_routes + [v for k, v in \
            self.build_routes.iteritems() if v not in self.match_routes]

        return '<Router(%r)>' % routes

您的 wsgiApplication 实例是您的属性webapp2.RequestHandler

所以我认为request.app.router

所以希望有一个更直接的方式,但如果不是上面应该工作?

Webapp2 在http://webapp2.readthedocs.io/en/latest/上提供了非常棒的可搜索源代码

于 2012-10-25T23:48:01.497 回答
2

我刚刚编写了这个函数来提取有关 webapp2 应用程序路由器中所有 URI 路由的有用信息,甚至包括使用 webapp2_extras.routes.PathPrefixRoute 创建的嵌套路由:

def get_route_list(router):
  """
  Get a nested list of all the routes in the app's router
  """
  def get_routes(r):
    """get list of routes from either a router object or a PathPrefixRoute object,
    because they were too stupid to give them the same interface.
    """
    if hasattr(r, 'match_routes'):
      return r.match_routes
    else:
      return list(r.get_routes())

  def get_doc(handler, method):
    """get the doc from the method if there is one,
    otherwise get the doc from the handler class."""
    if method:
      return getattr(handler,method).__doc__
    else:
      return handler.__doc__

  routes=[]
  for i in get_routes(router):
    if hasattr(i, 'handler'):
      # I think this means it's a route, not a path prefix
      cur_template = i.template
      cur_handler  = i.handler
      cur_method   = i.handler_method
      cur_doc      = get_doc(cur_handler,cur_method)
      r={'template':cur_template, 'handler':cur_handler, 'method':cur_method, 'doc':cur_doc}
    else:
      r=get_route_list(i)
    routes.append(r)
  return routes

这将返回一个嵌套的列表列表,但如果您只想要一个平面列表(就像我实际上所做的那样),您可以使用此处的函数将其展平:Flattening a shallow list in python 注意:您可能需要编辑该展平浅列表函数也避免迭代字典。即,在此处添加:“...而不是 isinstance(el, basestring) 而不是 isinstance(el, dict)”

这从查看代码中应该是显而易见的,但是我编写这个的方式,对于每条路由,它都会为您提供来自自定义方法的文档字符串(如果有的话);否则,它会为您提供处理程序类的文档字符串。这个想法是这应该对 OP 的目的有用,这也是我想做的。

于 2014-07-12T18:57:34.807 回答