From 844e98b01c5c6aa1585a76ac77f92bb8c1ef9d90 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 5 Sep 2010 04:58:23 +0000 Subject: Documentation ------------- - Add an API chapter for the ``repoze.bfg.request`` module, which includes documentation for the ``repoze.bfg.request.Request`` class (the "request object"). - Modify the "Request and Response" narrative chapter to reference the new ``repoze.bfg.request`` API chapter. Some content was moved from this chapter into the API documentation itself. Features -------- - A new ``repoze.bfg.request.Request.add_response_callback`` API has been added. This method is documented in the new ``repoze.bfg.request`` API chapter. It can be used to influence response values before a concrete response object has been created. Internal -------- - The (internal) feature which made it possible to attach a ``global_response_headers`` attribute to the request (which was assumed to contain a sequence of header key/value pairs which would later be added to the response by the router), has been removed. The functionality of ``repoze.bfg.request.Request.add_response_callback`` takes its place. --- repoze/bfg/request.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 3 deletions(-) (limited to 'repoze/bfg/request.py') diff --git a/repoze/bfg/request.py b/repoze/bfg/request.py index 8939e7b88..c9422e24d 100644 --- a/repoze/bfg/request.py +++ b/repoze/bfg/request.py @@ -16,9 +16,74 @@ def make_request_ascii(event): request.default_charset = None class Request(WebobRequest): + """ + A subclass of the :term:`WebOb` Request class. An instance of + this class is created by the :term:`router` and is provided to a + view callable (and to other subsystems) as the ``request`` + argument. + + The documentation below (save for the ``add_response_callback`` + method, which is defined in this subclass itself, and the + attributes ``context``, ``registry``, ``root``, ``subpath``, + ``traversed``, ``view_name``, ``virtual_root`` , and + ``virtual_root_path``, each of which is added to the request at by + the :term:`router` at request ingress time) are autogenerated from + the WebOb source code used when this documentation was generated. + + Due to technical constraints, we can't yet display the WebOb + version number from which this documentation is autogenerated, but + it will be the 'prevailing WebOb version' at the time of the + release of this :mod:`repoze.bfg` version. See + `http://http://pythonpaste.org/webob/ + `_ for further information. + """ implements(IRequest) + response_callbacks = () default_charset = 'utf-8' + def add_response_callback(self, callback): + """ + Add a callback to the set of callbacks to be called by the + :term:`router` at a point after a :term:`response` object is + successfully created. :mod:`repoze.bfg` does not have a + global response object: this functionality allows an + application to register an action to be performed against the + response once one is created. + + A 'callback' is a callable which accepts two positional + parameters: ``request`` and ``response``. For example: + + .. code-block:: python + :linenos: + + def cache_callback(request, response): + 'Set the cache_control max_age for the response' + response.cache_control.max_age = 360 + request.add_response_callback(cache_callback) + + Response callbacks are called in the order they're added + (first-to-most-recently-added). No response callback is + called if an exception happens in application code, or if the + response object returned by :term:`view` code is invalid. + + All response callbacks are called *before* the + :class:`repoze.bfg.interfaces.INewResponse` event is sent. + + Errors raised by callbacks are not handled specially. They + will be propagated to the caller of the :mod:`repoze.bfg` + router application. """ + + callbacks = self.response_callbacks + if not callbacks: + callbacks = [] + callbacks.append(callback) + self.response_callbacks = callbacks + + def _process_response_callbacks(self, response): + for callback in self.response_callbacks: + callback(self, response) + self.response_callbacks = () + # override default WebOb "environ['adhoc_attr']" mutation behavior __getattr__ = object.__getattribute__ __setattr__ = object.__setattr__ @@ -87,9 +152,10 @@ def route_request_iface(name, bases=()): return iface def add_global_response_headers(request, headerlist): - attrs = request.__dict__ - response_headers = attrs.setdefault('global_response_headers', []) - response_headers.extend(headerlist) + def add_headers(request, response): + for k, v in headerlist: + response.headers.add(k, v) + request.add_response_callback(add_headers) from repoze.bfg.threadlocal import get_current_request as get_request # b/c -- cgit v1.2.3