rhino.mapperThe mapper dispatches incoming requests based on URL templates and also provides a WSGI interface.
The HTTP request's path is matched against a series of patterns in the order they were added. Patterns may be given as strings that must match the request path exactly, or they may be templates.
Groups of matching characters for templates are extracted from the URL and accessible via the routing_args property of rhino.Request.
A template is a string that can contain thee special kinds of markup:
{name} or {name:range}Whatever matches this part of the path will be available in the Request.routing_args dict of named parameters under the key name.
[]Any part enclosed in brackets is optional. Brackets can be nested and contain named parameters. If an optional part contains named parameters and is missing from the request URL, the parameter names contained therein will also be missing from Request.routing_args.
|A vertical bar may only be present at the end of the template, and causes the path to be matched only against the part before the '|'. The path can contain more characters after the match, which will be preserved in environ['PATH_INFO'], where it can be used by nested mappers.
A named parameter can contain an optional named range specifier after a :. which restricts what characters the parameter can match. The default ranges are as follows:
| Range | Regular Expression |
|---|---|
| word | \w+ |
| alpha | [a-zA-Z]+ |
| digits | \d+ |
| alnum | [a-zA-Z0-9]+ |
| segment | [^/]+ |
| unreserved | [a-zA-Z\d\-\.\_\~]+ |
| any | .+ |
If no range is specified a parameter matches segment.
Default ranges can be extended or overwritten by passing a dict mapping range names to regular expressions to the Mapper constructor. The regular expressions should be strings:
# match numbers in engineering format
mapper = Mapper(ranges={'real': r'(\+|-)?[1-9]\.[0-9]*E(\+|-)?[0-9]+'})
mapper.add('/a/b/{n:real}', my_math_app)
The '|' is needed when nesting mappers:
foo_mapper = Mapper()
foo_mapper.add('/bar', bar_resource)
mapper = Mapper()
mapper.add('/', index)
mapper.add('/foo|', foo_mapper)
A request to /foo/bar is now dispatched by mapper to foo_mapper and on to bar_resource.
class MapperClass variables:
None):default_encoding of outgoing Responses. See rhino.Response for details. Does not affect responses returned via exceptions.
None):default_content_type of outgoing Responses. See rhino.Response for details. Does not affect responses returned via exceptions.
True):wrap_wsgi_input property on rhino.request.Request instances created by this mapper.
__init__(ranges=None)Create a new mapper.
The ranges parameter can be used to override or augment the default ranges by passing in a dict mapping range names to regexp patterns.
add(template, resource, name=None)Add a route to a resource.
The optional name assigns a name to this route that can be used when building URLs. The name must be unique within this Mapper instance.
add_ctx_property(name, fn, cached=True)Install a context property.
A context property is a callable that will be called on first access of the property named name on Context instances passing through this mapper. The result will be cached unless cached is False.
If the context property is not callable, it will be installed as-is, otherwise, it will be called with the context instance as first argument.
add_wrapper(wrapper)Install a wrapper.
A wrapper is a piece of middleware not unlike WSGI middelware but working with Request and Response objects instead. The argument to add_wrapper must be a callable that is called with the wrapped app as argument and should return another callable that accepts a Request and Context instance as arguments and returns a Response. The wrapper has full control over the execution. It can call the wrapped app to pass on the request, modify the response, etc.
Wrappers can be nested. This:
app = Mapper()
app.add_wrapper(wrapper1)
app.add_wrapper(wrapper2)
Could also be achieved like this:
app = Mapper()
app = wrapper2(wrapper1(app))
Except that in the first version 'app' still has all methods of Mapper.
Example for a wrapper that adds an X-Powered-By header to outgoing responses:
def add_x_powered_by_wrapper(app):
def wrap(request, ctx):
response = app(request)
response.headers['X-Powered-By'] = 'Unicorns'
return response
return wrap
handle_error(request, exc_info)Log the 'exc_info' tuple in the server log.
path(target, params)Build a URL path fragment for a resource or route.
Possible values for target:
Route instancestart_server(host='localhost', port=9000, app=None)Start a wsgiref.simple_server based server to run this mapper.
wsgi(environ, start_response)Implements the mapper's WSGI interface.
class RouteA Route links a URL template and an optional name to a resource.
__init__(template, resource, ranges=None, name=None)path(params)Builds the URL path fragment for this route.
class Context__init__(request=None)add_callback(phase, fn)Adds a callback to the context.
The phase determines when and if the callback is executed, and which positional arguments are passed in:
Called from rhino.Resource, after a handler for the current request has been resolved, but before the handler is called.
Arguments: request
Called from rhino.Resource, after the handler has returned successfully.
Arguments: request, response
Called from Mapper, before the WSGI response is finalized.
Arguments: request, response
Called from Mapper, before control is passed back to the WSGI layer.
Arguments: -
Called when the WSGI server calls close() on the response iterator.
Arguments: -
add_property(name, fn, cached=True)Adds a lazily initialized property to the Context.
See also Mapper.add_ctx_property, which uses this method to install the properties added on the Mapper level.
class MapperExceptionclass InvalidArgumentErrorclass InvalidTemplateError