URL Routing and Generation
The diva.routing module provides dispatching of requests to request handlers based on the requested path, as well as the generation of concrete URLs based on the routing.
Routing Configuration File
While routes can of course be set up programatically, a simple configuration file format is also supported.
A simple example:
home: / -> geddit.controllers:index feed: /feed -> geddit.controllers:feed info: /info/{id} -> geddit.controllers:info comment: /info/{id}/comment -> geddit.controllers:comment submit: /submit -> geddit.controllers:submit media: /media/{filename:.+} -> diva.static:directory path = "%(here)s/static/"
Every route is on a single line, with three different parts:
- the name of the route (optional)
- the path pattern with variable parts enclosed in curly braces, and
- the target function that should handle requests matching that pattern (optional).
Variable parts in the path pattern consist of the variable name and an optional regular expression that needs to be matched, separated by a colon. If no regular expression is specified, the default is [^/]+, meaning that the part will match a single URL segment until the next slash.
Additional indented lines can be provided below any route to set default values for parameters that get passed on to the request handler. The value of these parameters can be any Python expression. String values are interpolated, with the special %(here)s placeholder being substituted by the absolute path to the directory containing the routing configuration file, and any other placeholders being replaced by the value of a corresponding configuration option.
If no name is specified for a route, URLs for that route can not be generated by name, but only based on the function object. If no target is specified, the route is only used for generating links, not for dispatching requests.
Generating URLs
The diva.routing modules provides a number of ways to generate URLs based on the routing.
The central function is path_to(target, *args, **kwargs). Here, target is either the name of the route, or the function handling the route. Additional arguments are substituted for variables in the path of the route. Any remaining keyword arguments are added as query string parameters:
>>> from diva.routing import path_to >>> path_to('info', id=42) /info/42 >>> path_to('info', id=42, page=2) /info/42?page=2
Use the abs_url function to turn such relative URLs into absolute ones including scheme and host:
>>> from diva.routing import abs_url, path_to >>> abs_url(path_to('info', id=42)) http://localhost:8080/info/42
Finally, the redirect_to(target, *args, **kwargs) function is a shortcut for redirecting to the absolutized result of path_to(). It will raise an HTTP exception, and thus immediately break out of the current code.
Rerouting Generated URLs
The routing can be configured to reroute certain routes to different URLs for URL generation. For example, you could set up a static resources route to be rerouted to one or more different host names:
app.routing.reroute('media', lambda filename=None: 'http://static.example.com/%s' % filename )
This only has effect on URL generation. If the route is setup to also handle incoming requests, they will still be matched and processed as before.
Delegating to Other WSGI Applications
You can mount other WSGI-based applications into the URI namespace of the Diva application using the delegate request handler in the diva.routing module.
For example, the following routing configuration would mount Trac under the /trac prefix:
trac: /trac{path:.*} -> diva.routing:delegate application = "trac.web.main:dispatch_request" environ = {"trac.env_path": "/var/trac/teo"}
The application parameter is needed to determine which WSGI application is delegated to. The environ parameter can be used to specify a dictionary of variables that should be added to the WSGI environ, which may be needed by the target app. Finally, a delegating route should use a path URL part that will be used as the PATH_INFO for the target application.
API Documentation