# `tornado.routing` — Basic routing implementation

Flexible routing implementation.

Tornado routes HTTP requests to appropriate handlers using `Router` class implementations. The `tornado.web.Application` class is a `Router` implementation and may be used directly, or the classes in this module may be used for additional flexibility. The `RuleRouter` class can match on more criteria than `Application`, or the `Router` interface can be subclassed for maximum customization.

`Router` interface extends `HTTPServerConnectionDelegate` to provide additional routing capabilities. This also means that any `Router` implementation can be used directly as a `request_callback` for `HTTPServer` constructor.

`Router` subclass must implement a `find_handler` method to provide a suitable `HTTPMessageDelegate` instance to handle the request:

    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)

The main responsibility of `Router` implementation is to provide a mapping from a request to `HTTPMessageDelegate` instance that will handle this request. In the example above we can see that routing is possible even without instantiating an `Application`.

For routing to `RequestHandler` implementations we need an `Application` instance. `get_handler_delegate` provides a convenient way to create `HTTPMessageDelegate` for a given request and `RequestHandler`.

Here is a simple example of how we can we route to `RequestHandler` subclasses by HTTP method:

    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` interface adds the ability to distinguish between the routes and reverse them to the original urls using route’s name and additional arguments. `Application` is itself an implementation of `ReversibleRouter` class.

`RuleRouter` and `ReversibleRuleRouter` are implementations of `Router` and `ReversibleRouter` interfaces and can be used for creating rule-based routing configurations.

Rules are instances of `Rule` class. They contain a `Matcher`, which provides the logic for determining whether the rule is a match for a particular request and a target, which can be one of the following.

1. An instance of `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. A callable accepting a single argument of `HTTPServerRequest` type:

    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. Another `Router` instance:

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

Of course a nested `RuleRouter` or a `Application` is allowed:

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

    server = HTTPServer(router)

In the example below `RuleRouter` is used to route between applications:

    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)

For more information on application-level routing see docs for `Application`.

New in version 4.5.

class `tornado.routing.``Router`

  Abstract router interface.

  `find_handler`(request, **kwargs)

    Must be implemented to return an appropriate instance of `HTTPMessageDelegate` that can serve the request. Routing implementations may pass additional kwargs to extend the routing logic.

    Parameters:

    - request (httputil.HTTPServerRequest) – current HTTP request.
    - kwargs – additional keyword arguments passed by routing implementation.

    Returns: | an instance of `HTTPMessageDelegate` that will be used to process the request.

class `tornado.routing.``ReversibleRouter`

  Abstract router interface for routers that can handle named routes and support reversing them to original urls.

  `reverse_url`(name, *args)

    Returns url string for a given route name and arguments or `None` if no match is found.

    Parameters:

    - name (str) – route name.
    - args – url parameters.

    Returns: | parametrized url string for a given route name (or `None`).

class `tornado.routing.``RuleRouter`(rules=None)

  Rule-based router implementation.

  Constructs a router from an ordered list of rules:

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

  You can also omit explicit `Rule` constructor and use tuples of arguments:

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

  `PathMatches` is a default matcher, so the example above can be simplified:

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

  In the examples above, `Target` can be a nested `Router` instance, an instance of `HTTPServerConnectionDelegate` or an old-style callable, accepting a request argument.

  Parameters: | rules – a list of `Rule` instances or tuples of `Rule` constructor arguments.

  `add_rules`(rules)

    Appends new rules to the router.

    Parameters: | rules – a list of Rule instances (or tuples of arguments, which are passed to Rule constructor).

  `process_rule`(rule)

    Override this method for additional preprocessing of each rule.

    Parameters: | rule (Rule) – a rule to be processed.
    Returns: | the same or modified Rule instance.

  `get_target_delegate`(target, request, **target_params)

    Returns an instance of `HTTPMessageDelegate` for a Rule’s target. This method is called by `find_handler` and can be extended to provide additional target types.

    Parameters:

    - target – a Rule’s target.
    - request (httputil.HTTPServerRequest) – current request.
    - target_params – additional parameters that can be useful for `HTTPMessageDelegate` creation.

class `tornado.routing.``ReversibleRuleRouter`(rules=None)

  A rule-based router that implements `reverse_url` method.

  Each rule added to this router may have a `name` attribute that can be used to reconstruct an original uri. The actual reconstruction takes place in a rule’s matcher (see `Matcher.reverse`).

class `tornado.routing.``Rule`(matcher, target, target_kwargs=None, name=None)

  A routing rule.

  Constructs a Rule instance.

  Parameters:

  - matcher (Matcher) – a `Matcher` instance used for determining whether the rule should be considered a match for a specific request.
  - target – a Rule’s target (typically a `RequestHandler` or `HTTPServerConnectionDelegate` subclass or even a nested `Router`, depending on routing implementation).
  - target_kwargs (dict) – a dict of parameters that can be useful at the moment of target instantiation (for example, `status_code` for a `RequestHandler` subclass). They end up in `target_params['target_kwargs']` of `RuleRouter.get_target_delegate` method.
  - name (str) – the name of the rule that can be used to find it in `ReversibleRouter.reverse_url` implementation.

class `tornado.routing.``Matcher`

  Represents a matcher for request features.

  `match`(request)

    Matches current instance against the request.

    Parameters: | request (httputil.HTTPServerRequest) – current HTTP request
    Returns: | a dict of parameters to be passed to the target handler (for example, `handler_kwargs`, `path_args`, `path_kwargs` can be passed for proper `RequestHandler` instantiation). An empty dict is a valid (and common) return value to indicate a match when the argument-passing features are not used. `None` must be returned to indicate that there is no match.

  `reverse`(*args)

    Reconstructs full url from matcher instance and additional arguments.

class `tornado.routing.``AnyMatches`

  Matches any request.

class `tornado.routing.``HostMatches`(host_pattern)

  Matches requests from hosts specified by `host_pattern` regex.

class `tornado.routing.``DefaultHostMatches`(application, host_pattern)

  Matches requests from host that is equal to application’s default_host. Always returns no match if `X-Real-Ip` header is present.

class `tornado.routing.``PathMatches`(path_pattern)

  Matches requests with paths specified by `path_pattern` regex.

class `tornado.routing.``URLSpec`(pattern, handler, kwargs=None, name=None)

  Specifies mappings between URLs and handlers.

  Parameters:

  - `pattern`: Regular expression to be matched. Any capturing groups in the regex will be passed in to the handler’s get/post/etc methods as arguments (by keyword if named, by position if unnamed. Named and unnamed capturing groups may not be mixed in the same rule).
  - `handler`: `RequestHandler` subclass to be invoked.
  - `kwargs` (optional): A dictionary of additional arguments to be passed to the handler’s constructor.
  - `name` (optional): A name for this handler. Used by `reverse_url`.