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.
- 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)
- 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()
- 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[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.
- request (
httputil.HTTPServerRequest
) – current HTTP request. - kwargs – additional keyword arguments passed by routing implementation.
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.
- name (
str
) – route name. - args – url parameters.
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.
add_rules(rules)[source]
Appends new rules to the router.
process_rule(rule)[source]
Override this method for additional preprocessing of each rule.
Rule
) – a rule to be processed.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.
- 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)[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.
- matcher (
Matcher
) – aMatcher
instance used for determining whether the rule should be considered a match for a specific request. - target – a Rule’s target (typically a
RequestHandler
orHTTPServerConnectionDelegate
subclass or even a nestedRouter
, 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 aRequestHandler
subclass). They end up intarget_params['target_kwargs']
ofRuleRouter.get_target_delegate
method. - name (
str
) – the name of the rule that can be used to find it inReversibleRouter.reverse_url
implementation.
class tornado.routing.Matcher[source]
Represents a matcher for request features.
match(request)[source]
Matches current instance against the request.
httputil.HTTPServerRequest
) – current HTTP requesthandler_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 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 byreverse_url
.