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

diva.routing

Mapping of incoming requests to request handler functions.

Routing

URL routing and generation.

>>> def start():
...     print 'Start'
>>> def detail(id):
...     print 'Details for %d' % id
>>> def edit(id):
...     print 'Editor for %d' % id
>>> map = Routing().add('/', start, name='start') \
...                .add('/movies/{id:\d+}', detail, name='view_movie') \
...                .add('/movies/{id:\d+}/edit', edit, name='edit_movie') \
...                .add('/media/{path:.+}', name='media')

Note how the add() method returns the Routing object itself to allow chaining the addition of multiple routes.

>>> func, params = map.match('/')
>>> func(**params)
Start
>>> func, params = map.match('/movies/1')
>>> func(**params)
Details for 1
>>> func, params = map.match('/movies/1/edit')
>>> func(**params)
Editor for 1
>>> map.match('/media/style/layout.css')
(None, None)
>>> print map.generate(start)
/
>>> print map.generate(detail, id=1)
/movies/1
>>> print map.generate('start')
/
>>> print map.generate('view_movie', id=1)
/movies/1
>>> print map.generate('view_movie', id=1, format='rss')
/movies/1?format=rss
>>> print map.generate('media', 'style/layout.css')
/media/style/layout.css

__init__(self, filename=None)

(Not documented)

__repr__(self)

(Not documented)

add(self, path, target=None, name=None, defaults=None)

Add a path to the routing.

param path:the path pattern to match
param target:the target function, either a string of the form package.module:func, or a function object
param name:the name of the route
param defaults:a dictionary of default parameters to provide when calling the function

generate(self, target, **args, *kwargs)

Generate a URL for the given route.

param target:the name or target function of the route
param args:any positional arguments
param kwargs:any keyword arguments

match(self, path, **kwargs)

Find the route matching the given path.

param path:the requested path
param kwargs:any keyword arguments that should be passed to the target function
return:a tuple of the form (function, params)

load(cls, file)

Load routes from the given file.

param file:the file to load from, either a path or a file-like object

mount(self, routing, prefix='')

Mount an other routing, optionally under a specific prefix.

Path matching and URL generation is recursively delegated to all mounted routing objects when the top routing contains no matching route.

param routing:filename or Routing object
param prefix:optional path prefix

override(self, routing)

Override the current routing with an other one.

Any overlapping routes defined in the new routing will take preference over the equivalent routes in the current routing.

param routing:filename or Routing object

reroute(self, target, func)

Intercept URL generation requests for the specified route and use the result of calling the given function, instead of the path the route was configured with.

This can be used for shifting all generated URLs to a different host. For example, you can set up a static media route to point to one or more domains that should actually serve the static files.

param target:the name or target function of the route
param func:the function to delegate to for URL generation; this function should expect the route variables as keyword arguments and return the corresponding URL as a string

abs_url(path, scheme=None, host=None)

Turn a relative path into an absolute URL, taking the URL scheme and the host name used for the request into account.

param path:the relative URL
param scheme:optional URL scheme (such as http or https) to use instead of the current scheme
param host:optional host (name and port) to use instead of the current host
return:an absolute URL
rtype:basestring

path_to(target, **args, *kwargs)

Generate a URL to the given target.

The target is identified either by the name of the route (as a string), or by the handler function.

Any additional arguments are substited into the route path. Remaining keyword arguments are added as query string parameters.

param target:the name or target function of the route
param args:any positional arguments
param kwargs:any keyword arguments

redirect_to(target, **args, *kwargs)

Send a redirect to the specified target URL.

The exact behavior of this function depends on how the target is specified:

If the target parameter is a string, and that string is an absolute URL (including scheme and host name), it will will be used as-is. If the URL is relative (i.e. it doesn't start with http:// or https://) but it does start with a slash, it is made absolute by adding scheme and host name. In both cases any additional positional arguments are ignored.

If target is not a string, or a string that does not start with a slash, it is first processed by the path_to function, which in turn delegates to Routing.generate.

In all cases, any keyword arguments are added to the final target URL as query string parameters.

This function raises an HTTP redirection exception, meaning that it will immediately break out from the code calling it and send the redirection response to the client.

param target:the target to redirect to, which can be either an absolute or a server relative URL, the name of a route, or the function that handles a route
param args:only for routing-based targets, additional positional arguments are added to the target URL as path segments
param kwargs:any keyword arguments are added to the target URL as query string parameters

redirect(request, response, target)

Request handler that redirects to a specific URL.

param request:the Request object
param response:the Response object
param target:the target to redirect to, same as the target parameter of the redirect_to function.

delegate(request, response, application, path='', environ=None)

Request handler that can delegate request handling to a given WSGI application.

param request:the Request object
param response:the Response object
param application:
 a callable object or a string of the form package.module:attrname that defines where to import the application from
param path:the part of the URL that should be considered the PATH_INFO of the target application
param environ:a dictionary containing variables that should be set for the WSGI environ of the application, potentially overwriting already existing values