Source code for ramverk.routing

from inspect             import getargspec

from venusian            import Scanner, attach
from werkzeug.exceptions import NotFound
from werkzeug.routing    import Map, Submount, Subdomain, EndpointPrefix
from werkzeug.utils      import cached_property, redirect, import_string

from ramverk.utils       import request_property


[docs]def router(generator): """Decorate a callable as a router, i.e. returns an iterable of rules and rule factories.""" def route(scanner, name, ob): rules = ob() if scanner.submount is not None: rules = [Submount(scanner.submount, rules)] if scanner.endpoint_prefix is not None: rules = [EndpointPrefix(scanner.endpoint_prefix, rules)] if scanner.subdomain is not None: rules = [Subdomain(scanner.subdomain, rules)] for rule in rules: scanner.app.route(rule) attach(generator, route, category='ramverk.routing') return generator
[docs]def endpoint(view): """Decorate a callable as a view for the endpoint with the same name.""" def register_endpoint(scanner, name, ob): if scanner.endpoint_prefix is not None: name = scanner.endpoint_prefix + name scanner.app.endpoints[name] = ob attach(view, register_endpoint, category='ramverk.routing') return view
[docs]class RoutingScannerMixin(object): """Add support for scanning for :func:`router` and :func:`endpoint` functions to an application with URL dispatch."""
[docs] def scan(self, package=None, submount=None, endpoint_prefix=None, subdomain=None, categories=('ramverk.routing',)): """Scan `package` (or otherwise the :attr:`~ramverk.application.BaseApplication.module`) for routers and endpoints.""" scanner = Scanner(app=self, submount=submount, endpoint_prefix=endpoint_prefix, subdomain=subdomain) if package is None: package = self.module if isinstance(package, basestring): package = import_string(package) scanner.scan(package, categories)
[docs]class RoutingHelpersMixin(object): """Add some convenient helpers for applications with URL dispatch.""" @cached_property
[docs] def app(self): """Reference to itself, to allow views to access the application.""" return self
[docs] def url(self, endpoint, **values): """Build a URL for a route to `endpoint` with `values`.""" return self.url_adapter.build(endpoint, values, force_external=True)
[docs] def path(self, endpoint, **values): """Like :meth:`url` but as an absolute path.""" return self.url_adapter.build(endpoint, values)
[docs] def redirect(self, endpoint, **values): """Create a response that redirects to the route for `endpoint` with `values`.""" return redirect(self.path(endpoint, **values))
[docs]class URLMapMixin(object): """Add URL dispatch using a :class:`~werkzeug.routing.Map` to an application.""" @cached_property
[docs] def url_map(self): """Map of URLs to :attr:`endpoints`.""" return Map()
[docs] def route(self, rulefactory): """Add a :class:`~werkzeug.routing.Rule` or rule factory to :attr:`url_map`.""" self.url_map.add(rulefactory)
@request_property
[docs] def url_adapter(self): """Adapter for :attr:`url_map` bound to the current request.""" return self.url_map.bind_to_environ(self.local.environ)
@cached_property
[docs] def endpoints(self): """Mapping of endpoints to views.""" return {}
@property
[docs] def route_values(self): """The values that matched the route in the :attr:`url_map`.""" return self.local.route_values
[docs] def call_view(self, view, **kwargs): """Call the `view` callable with `kwargs` using view semantics: the default is to fetch missing arguments in the view's signature, from the attributes of the application.""" wants = getargspec(view).args kwargs.update((name, getattr(self, name)) for name in wants if name not in kwargs) return view(**kwargs)
[docs] def respond(self): """Match the environment to an endpoint and then :meth:`call_view` the corresponding view.""" try: endpoint, values = self.url_adapter.match() except NotFound: return super(URLMapMixin, self).respond() self.local.endpoint = endpoint self.local.route_values = values view = self.endpoints[endpoint] return self.call_view(view)
[docs]class RoutingMixin(RoutingScannerMixin, RoutingHelpersMixin, URLMapMixin): """Add complete URL dispatching to an application."""

Project Versions