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.
- 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
HTTPServerRequesttype:
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
Routerinstance:
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
HTTPMessageDelegatethat 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
HTTPMessageDelegatethat 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.
-
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
Ruleconstructor and use tuples of arguments:RuleRouter([ (PathMatches("/handler"), Target), ])
PathMatchesis a default matcher, so the example above can be simplified:RuleRouter([ ("/handler", Target), ])
In the examples above,
Targetcan be a nestedRouterinstance, an instance ofHTTPServerConnectionDelegateor an old-style callable, accepting a request argument.Parameters: rules – a list of Ruleinstances or tuples ofRuleconstructor 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
HTTPMessageDelegatefor a Rule’s target. This method is called byfind_handlerand 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
HTTPMessageDelegatecreation.
-
-
class
tornado.routing.ReversibleRuleRouter(rules=None)[source]¶ A rule-based router that implements
reverse_urlmethod.Each rule added to this router may have a
nameattribute that can be used to reconstruct an original uri. The actual reconstruction takes place in a rule’s matcher (seeMatcher.reverse).
-
class
tornado.routing.Rule(matcher, target, target_kwargs=None, name=None)[source]¶ A routing rule.
Constructs a Rule instance.
Parameters: - matcher (Matcher) – a
Matcherinstance used for determining whether the rule should be considered a match for a specific request. - target – a Rule’s target (typically a
RequestHandlerorHTTPServerConnectionDelegatesubclass 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_codefor aRequestHandlersubclass). They end up intarget_params['target_kwargs']ofRuleRouter.get_target_delegatemethod. - name (str) – the name of the rule that can be used to find it
in
ReversibleRouter.reverse_urlimplementation.
- matcher (Matcher) – a
-
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_kwargscan be passed for properRequestHandlerinstantiation). An empty dict is a valid (and common) return value to indicate a match when the argument-passing features are not used.Nonemust be returned to indicate that there is no match.
-
-
class
tornado.routing.HostMatches(host_pattern)[source]¶ Matches requests from hosts specified by
host_patternregex.
-
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-Ipheader is present.
-
class
tornado.routing.PathMatches(path_pattern)[source]¶ Matches requests with paths specified by
path_patternregex.
-
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:RequestHandlersubclass 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.