tornado.routing — Basic routing implementation

Basic routing implementation.

Tornado routes HTTP requests to appropriate handlers using Router class implementations.

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)
  1. 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()
  1. 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.

class tornado.routing.Router[source]

Abstract router interface.

find_handler(request, **kwargs)[source]

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[source]

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

reverse_url(name, *args)[source]

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)[source]

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)[source]

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)[source]

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)[source]

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:
class tornado.routing.ReversibleRuleRouter(rules=None)[source]

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)[source]

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[source]

Represents a matcher for request features.

match(request)[source]

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)[source]

Reconstructs full url from matcher instance and additional arguments.

class tornado.routing.AnyMatches[source]

Matches any request.

class tornado.routing.HostMatches(host_pattern)[source]

Matches requests from hosts specified by host_pattern regex.

class tornado.routing.DefaultHostMatches(application, host_pattern)[source]

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)[source]

Matches requests with paths specified by path_pattern regex.

class tornado.routing.URLSpec(pattern, handler, kwargs=None, name=None)[source]

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 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.