有没有办法在内部打印龙卷风Web服务器上配置的路由处理程序?

问题描述 投票:0回答:2

给出以下(示例)处理程序(取自此处):

handlers = [
            (r"/", MainHandler),
            (r"/auth/login", AuthLoginHandler),
            (r"/auth/logout", AuthLogoutHandler),
        ]

有没有办法以编程方式在单独的页面上打印处理程序?我在想一些类似的事情:

handlers = [
            (r"/", MainHandler),
            (r"/auth/login", AuthLoginHandler),
            (r"/auth/logout", AuthLogoutHandler),
            (r"/routes", RoutePrinter),
        ]

...

class RoutePrinter(...):
    def get(self):
       self.write(str(self.application.routes))

这给了我

[(<_sre.SRE_Pattern object at 0x216c130>, [, , , , , , , , , , , , , , , , , , , , , , ])]

我尝试了几种不同的访问器,但并没有真正帮助。是否可以生成我的路线列表?

编辑

根据进一步的搜索,我找到了从这些正则表达式对象打印模式/标志的方法。问题是我很难理解如何解除它们的嵌套,因为它不像

self.application.handlers[0][0]
然后
self.application.handlers[1][0]
那么直观。第二个是“超出范围”,尽管它看起来应该是“/auth/login”。

我错过了什么?

python tornado
2个回答
3
投票

这个怎么样?

[handler.regex.pattern for handler in self.application.handlers[0][1]]

如果您还想要处理程序类的名称:

[(handler.regex.pattern, handler.handler_class) for handler in self.application.handlers[0][1]]

0
投票

我遇到了这个问题,所以我写了这个。

适用于

Tornado 6.4.1

def list_routes(tornado_app: tornado.web.Application) -> str:
    def collect_routes(router: tornado.routing.Router) -> list[tuple[str, str] | str]:
        routes: list[tuple[str, str] | str] = []
        if not hasattr(router, 'rules'):
            return routes
        for rule in router.rules:
            if isinstance(rule.target, tornado.routing.Router):
                routes.extend(collect_routes(rule.target))
            elif isinstance(rule.matcher, tornado.routing.PathMatches):
                handler = rule.target
                if isinstance(handler, type):
                    handler_name = handler.__name__
                else:
                    handler_name = str(handler)
                routes.append((rule.matcher.regex.pattern, handler_name))
            else:
                handler = rule.target
                if isinstance(handler, type):
                    handler_name = handler.__name__
                else:
                    handler_name = str(handler)
                routes.append((str(rule.matcher), handler_name))
        return routes

    routes = ["# default:"] + collect_routes(tornado_app.default_router)
    routes += ["# wildcard:"] + collect_routes(tornado_app.wildcard_router)

    result = "[\n"
    result += ",\n".join([f"(r'{route[0]}', {route[1]})" if isinstance(route, tuple) else f"{route}" for route in routes])
    result += "\n]"
    return result

它会为 Streamlit 打印此内容:

[
# default:,
(r'^/_stcore/stream/?$', BrowserWebSocketHandler),
(r'^/(?:healthz|_stcore/health)/?$', HealthHandler),
(r'^/_stcore/message/?$', MessageCacheHandler),
(r'^/(?:st-metrics|_stcore/metrics)/?$', StatsRequestHandler),
(r'^/_stcore/host-config/?$', HostConfigHandler),
(r'^/_stcore/upload_file/(?P<session_id>[^/]+)/(?P<file_id>[^/]+)/?$', UploadFileRequestHandler),
(r'^/media/(.*)/?$', MediaFileHandler),
(r'^/component/(.*)/?$', ComponentRequestHandler),
(r'^/app/static/(.*)/?$', AppStaticFileHandler),
(r'^/(.*)/?$', StaticFileHandler),
(r'^/$', AddSlashHandler),
# wildcard:,
(r'^/_stcore/stream/?$', BrowserWebSocketHandler),
(r'^/(?:healthz|_stcore/health)/?$', HealthHandler),
(r'^/_stcore/message/?$', MessageCacheHandler),
(r'^/(?:st-metrics|_stcore/metrics)/?$', StatsRequestHandler),
(r'^/_stcore/host-config/?$', HostConfigHandler),
(r'^/_stcore/upload_file/(?P<session_id>[^/]+)/(?P<file_id>[^/]+)/?$', UploadFileRequestHandler),
(r'^/media/(.*)/?$', MediaFileHandler),
(r'^/component/(.*)/?$', ComponentRequestHandler),
(r'^/app/static/(.*)/?$', AppStaticFileHandler),
(r'^/(.*)/?$', StaticFileHandler),
(r'^/$', AddSlashHandler)
]
© www.soinside.com 2019 - 2024. All rights reserved.