阅读(4176) (0)

Tornado 基本路由使用

2022-03-08 15:05:07 更新

灵活的路由实现

Tornado 使用 ​Router类实现将 HTTP 请求路由到适当的处理程序。tornado.web.Application类是一个路由器实现,可以直接使用,也可以使用此模块中的类来增加灵活性。 ​RuleRouter类可以匹配比 ​Application更多的条件,或者可以对 ​Router接口进行子类化以实现最大程度的定制。

Router接口扩展了 ​HTTPServerConnectionDelegate以提供额外的路由功能。 这也意味着任何 Router 实现都可以直接用作 ​HTTPServer构造函数的 ​request_callback​。

路由器子类必须实现一个 ​find_handler方法来提供一个合适的 ​HTTPMessageDelegate实例来处理请求:

class CustomRouter(Router):
    def find_handler(self, request, **kwargs):
        # some routing logic providing a suitable HTTPMessageDelegate instance
        return MessageDelegate(request.connection)

class MessageDelegate(HTTPMessageDelegate):
    def __init__(self, connection):
        self.connection = connection

    def finish(self):
        self.connection.write_headers(
            ResponseStartLine("HTTP/1.1", 200, "OK"),
            HTTPHeaders({"Content-Length": "2"}),
            b"OK")
        self.connection.finish()

router = CustomRouter()
server = HTTPServer(router)

Router实现的主要职责是提供从请求到处理该请求的 ​HTTPMessageDelegate实例的映射。 在上面的示例中,我们可以看到即使没有实例化应用程序也可以进行路由。

为了路由到​RequestHandler​实现,我们需要一个​Application​实例。 ​get_handler_delegate ​提供了一种方便的方法来为给定的请求和 ​RequestHandler创建 ​HTTPMessageDelegate

这是一个简单的示例,说明我们如何通过 HTTP 方法路由到 ​RequestHandler子类:

resources = {}

class GetResource(RequestHandler):
    def get(self, path):
        if path not in resources:
            raise HTTPError(404)

        self.finish(resources[path])

class PostResource(RequestHandler):
    def post(self, path):
        resources[path] = self.request.body

class HTTPMethodRouter(Router):
    def __init__(self, app):
        self.app = app

    def find_handler(self, request, **kwargs):
        handler = GetResource if request.method == "GET" else PostResource
        return self.app.get_handler_delegate(request, handler, path_args=[request.path])

router = HTTPMethodRouter(Application())
server = HTTPServer(router)

ReversibleRouter接口增加了区分路由并使用路由名称和附加参数将它们反转为原始 url 的能力。 ​Application本身是 ​ReversibleRouter​类的实现。

RuleRouter和 ​ReversibleRuleRouter是 ​Router和 ​ReversibleRouter接口的实现,可用于创建基于规则的路由配置。

Rules是​Rule​类的实例。 它们包含一个 ​Matcher​,它提供了用于确定规则是否与特定请求和目标匹配的逻辑,可以是以下之一:

1、​HTTPServerConnectionDelegate的一个实例:

router = RuleRouter([
    Rule(PathMatches("/handler"), ConnectionDelegate()),
    # ... more rules
])

class ConnectionDelegate(HTTPServerConnectionDelegate):
    def start_request(self, server_conn, request_conn):
        return MessageDelegate(request_conn)

2、接受 ​HTTPServerRequest类型的单个参数的可调用对象

router = RuleRouter([
    Rule(PathMatches("/callable"), request_callable)
])

def request_callable(request):
    request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
    request.finish()

3、另一个​Router​实例:

router = RuleRouter([
    Rule(PathMatches("/router.*"), CustomRouter())
])

这其中当然允许嵌套 RuleRouter 或 Application:

router = RuleRouter([
    Rule(HostMatches("example.com"), RuleRouter([
        Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)])),
    ]))
])

server = HTTPServer(router)

在下面的示例中RuleRouter用于在应用程序之间进行路由:

app1 = Application([
    (r"/app1/handler", Handler1),
    # other handlers ...
])

app2 = Application([
    (r"/app2/handler", Handler2),
    # other handlers ...
])

router = RuleRouter([
    Rule(PathMatches("/app1.*"), app1),
    Rule(PathMatches("/app2.*"), app2)
])

server = HTTPServer(router)

class tornado.routing.Router

抽象路由器接口

find_handler(request: tornado.httputil.HTTPServerRequest, **kwargs) → Optional[tornado.httputil.HTTPMessageDelegate]

必须实现以返回可以为请求提供服务的适当的 ​HTTPMessageDelegate实例。 路由实现可能会传递额外的 kwargs 来扩展路由逻辑。

参数:

  • request(httputil.HTTPServerRequest) – 当前的 HTTP 请求。
  • kwargs– 路由实现传递的附加关键字参数。

返回:

一个用于处理请求的 ​HTTPMessageDelegate实例。

class tornado.routing.ReversibleRouter

抽象路由器接口,用于路由器,可处理命名路由,并支持将其反转为原始URL。

reverse_url(name: str, *args) → Optional[str]

返回给定路由名称和参数的 url 字符串,如果未找到匹配项,则返回 None。

参数:

  • name(str) - 路由名称。
  • args- 网址参数。

返回:

给定路由名称(或无)的参数化 url 字符串。

class tornado.routing.RuleRouter(rules: Optional[List[Union[Rule, List[Any], Tuple[Union[str, Matcher], Any], Tuple[Union[str, Matcher], Any, Dict[str, Any]], Tuple[Union[str, Matcher], Any, Dict[str, Any], str]]]] = None)

基于规则的路由器实现。

从规则的有序列表构造一个路由器:

RuleRouter([
    Rule(PathMatches("/handler"), Target),
    # ... more rules
])

您还可以省略显式Rule构造函数并使用参数元组:

RuleRouter([
    (PathMatches("/handler"), Target),
])

PathMatches是一个默认匹配器,所以上面的例子可以简化:

RuleRouter([
    ("/handler", Target),
])

在上面的示例中,​Target可以是嵌套的 ​Router实例、​HTTPServerConnectionDelegate的实例或旧式可调用对象,并接受请求参数。

参数: rules – ​Rule实例列表或 ​Rule构造函数参数的元组。

add_rules(rules: List[Union[Rule, List[Any], Tuple[Union[str, Matcher], Any], Tuple[Union[str, Matcher], Any, Dict[str, Any]], Tuple[Union[str, Matcher], Any, Dict[str, Any], str]]]) → None

将新规则附加到路由器。

参数:rules – ​Rule实例列表(或参数元组,传递给 ​Rule构造函数)。

process_rule(rule: tornado.routing.Rule) → tornado.routing.Rule

覆盖此方法以对每个规则进行额外的预处理。

参数:rule(​Rule​)——要处理的规则。

返回:相同或修改的规则实例。

get_target_delegate(target: Any, request: tornado.httputil.HTTPServerRequest, **target_params) → Optional[tornado.httputil.HTTPMessageDelegate]

返回规则目标的 ​HTTPMessageDelegate实例。 此方法由 ​find_handler调用,并且可以扩展以提供其他目标类型。

参数:

  • target​——Rule的目标。
  • request ​(httputil.HTTPServerRequest) – 当前请求。
  • target_params ​– 可用于创建 ​HTTPMessageDelegate的附加参数。

class tornado.routing.ReversibleRuleRouter(rules: Optional[List[Union[Rule, List[Any], Tuple[Union[str, Matcher], Any], Tuple[Union[str, Matcher], Any, Dict[str, Any]], Tuple[Union[str, Matcher], Any, Dict[str, Any], str]]]] = None)

实现 ​reverse_url ​方法的基于规则的路由器。

添加到此路由器的每个规则都可能有一个名称属性,可用于重建原始 ​URI​。 实际的重建发生在规则的匹配器中

class tornado.routing.Rule(matcher: tornado.routing.Matcher, target: Any, target_kwargs: Optional[Dict[str, Any]] = None, name: Optional[str] = None)

路由规则。

构造一个 ​Rule ​实例。

参数:

  • matcher ​(Matcher) – 一个 Matcher 实例,用于确定是否应将规则视为特定请求的匹配项。
  • target ​- Rule的目标(通常是 ​RequestHandler ​或 ​HTTPServerConnectionDelegate ​子类,甚至是嵌套路由器,具体取决于路由实现)。
  • target_kwargs ​(dict) – 在目标实例化时可能有用的参数字典(例如,​RequestHandler子类的 ​status_code​)。 它们最终出现在 ​RuleRouter.get_target_delegate​ 方法的 ​target_params['target_kwargs']​ 中。
  • name ​(str) -- 可用于在 ​ReversibleRouter.reverse_url​ 实现中找到它的规则的名称。

class tornado.routing.Matcher

表示请求功能的匹配器

match(request: tornado.httputil.HTTPServerRequest) → Optional[Dict[str, Any]]

将当前实例与请求匹配

参数:​request(httputil.HTTPServerRequest) – 当前的 HTTP 请求

返回:要传递给目标处理程序的参数字典(例如,可以传递 ​handler_kwargs​、​path_args​、​path_kwargs以进行正确的 ​RequestHandler实例化)。 空 dict 是一个有效的(和常见的)返回值,用于在不使用参数传递功能时指示匹配。 必须返回 None 以指示不匹配。

reverse(*args) → Optional[str]

从匹配器实例和附加参数重建完整的 url

class tornado.routing.AnyMatches

匹配任何请求

class tornado.routing.HostMatches(host_pattern: Union[str, Pattern[AnyStr]])

匹配来自 ​host_pattern正则表达式指定的主机的请求

class tornado.routing.DefaultHostMatches(application: Any, host_pattern: Pattern[AnyStr])

匹配来自等于应用程序 default_host 的主机的请求。 如果存在 ​X-Real-Ip​ 标头,则始终不返回匹配项。

class tornado.routing.PathMatches(path_pattern: Union[str, Pattern[AnyStr]])

将请求与 ​path_pattern ​正则表达式指定的路径匹配。

class tornado.routing.URLSpec(pattern: Union[str, Pattern[AnyStr]], handler: Any, kwargs: Optional[Dict[str, Any]] = None, name: Optional[str] = None)

指定 URL 和处理程序之间的映射。

参数:

  • pattern​:要匹配的正则表达式。 正则表达式中的任何捕获组都将作为参数传递给处理程序的 get/post等方法(如果命名则按关键字,如果未命名则按位置。命名和未命名的捕获组不能在同一规则中混合使用)。
  • handler​:要调用的 ​RequestHandler子类。
  • kwargs​(可选):要传递给处理程序构造函数的附加参数字典。
  • name​(可选):此处理程序的名称。由 ​reverse_url使用。