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
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: HTTPServerRequest, **kwargs: Any) Optional[HTTPMessageDelegate] [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.
- 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)[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 nestedRouter
instance, an instance ofHTTPServerConnectionDelegate
or an old-style callable, accepting a request argument.- 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 [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: 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: Any, request: HTTPServerRequest, **target_params: Any) Optional[HTTPMessageDelegate] [source]¶
Returns an instance of
HTTPMessageDelegate
for a Rule’s target. This method is called byfind_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: 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)[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 (seeMatcher.reverse
).
- class tornado.routing.Rule(matcher: Matcher, target: Any, target_kwargs: Optional[Dict[str, Any]] = None, name: Optional[str] = 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
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 in
ReversibleRouter.reverse_url
implementation.
- class tornado.routing.Matcher[source]¶
Represents a matcher for request features.
- match(request: HTTPServerRequest) Optional[Dict[str, Any]] [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 properRequestHandler
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.
- class tornado.routing.HostMatches(host_pattern: Union[str, Pattern])[source]¶
Matches requests from hosts specified by
host_pattern
regex.
- class tornado.routing.DefaultHostMatches(application: Any, host_pattern: 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: Union[str, Pattern])[source]¶
Matches requests with paths specified by
path_pattern
regex.
- class tornado.routing.URLSpec(pattern: Union[str, Pattern], handler: Any, kwargs: Optional[Dict[str, Any]] = None, name: Optional[str] = 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
.