diff options
Diffstat (limited to 'pyramid/router.py')
| -rw-r--r-- | pyramid/router.py | 72 |
1 files changed, 63 insertions, 9 deletions
diff --git a/pyramid/router.py b/pyramid/router.py index 0cbe00f3a..0c7f61071 100644 --- a/pyramid/router.py +++ b/pyramid/router.py @@ -53,6 +53,7 @@ class Router(object): tweens = q(ITweens) if tweens is None: tweens = excview_tween_factory + self.orig_handle_request = self.handle_request self.handle_request = tweens(self.handle_request, registry) self.root_policy = self.root_factory # b/w compat self.registry = registry @@ -161,35 +162,75 @@ class Router(object): return response - def __call__(self, environ, start_response): + def invoke_subrequest(self, request, use_tweens=False): """ - Accept ``environ`` and ``start_response``; create a - :term:`request` and route the request to a :app:`Pyramid` - view based on introspection of :term:`view configuration` - within the application registry; call ``start_response`` and - return an iterable. + Obtain a response object from the Pyramid application based on + information in the ``request`` object provided. The ``request`` + object must be an object that implements the Pyramid request + interface (such as a :class:`pyramid.request.Request` instance). If + ``use_tweens`` is ``True``, the request will be sent to the + :term:`tween` in the tween stack closest to the request ingress. If + ``use_tweens`` is ``False``, the request will be sent to the main + router handler, and no tweens will be invoked. This function also: + + - manages the threadlocal stack (so that + :func:`~pyramid.threadlocal.get_current_request` and + :func:`~pyramid.threadlocal.get_current_registry` work during a + request) + + - Adds a ``registry`` attribute and a ``invoke_subrequest`` attribute + (a callable) to the request object it's handed. + + - sets request extensions (such as those added via + :meth:`~pyramid.config.Configurator.add_request_method` or + :meth:`~pyramid.config.Configurator.set_request_property`) on the + request it's passed. + + - causes a :class:`~pyramid.event.NewRequest` event to be sent at the + beginning of request processing. + + - causes a :class:`~pyramid.event.ContextFound` event to be sent + when a context resource is found. + + - causes a :class:`~pyramid.event.NewResponse` event to be sent when + the Pyramid application returns a response. + + - Calls any :term:`response callback` functions defined within the + request's lifetime if a response is obtained from the Pyramid + application. + + - Calls any :term:`finished callback` functions defined within the + request's lifetime. + + See also :ref:`subrequest_chapter`. """ registry = self.registry has_listeners = self.registry.has_listeners notify = self.registry.notify - request = self.request_factory(environ) threadlocals = {'registry':registry, 'request':request} manager = self.threadlocal_manager manager.push(threadlocals) request.registry = registry + request.invoke_subrequest = self.invoke_subrequest + + if use_tweens: + handle_request = self.handle_request + else: + handle_request = self.orig_handle_request + try: try: extensions = self.request_extensions if extensions is not None: request._set_extensions(extensions) - response = self.handle_request(request) + response = handle_request(request) has_listeners and notify(NewResponse(request, response)) if request.response_callbacks: request._process_response_callbacks(response) - return response(request.environ, start_response) + return response finally: if request.finished_callbacks: @@ -197,3 +238,16 @@ class Router(object): finally: manager.pop() + + def __call__(self, environ, start_response): + """ + Accept ``environ`` and ``start_response``; create a + :term:`request` and route the request to a :app:`Pyramid` + view based on introspection of :term:`view configuration` + within the application registry; call ``start_response`` and + return an iterable. + """ + request = self.request_factory(environ) + response = self.invoke_subrequest(request, use_tweens=True) + return response(request.environ, start_response) + |
