Antti Haapala
2013-11-15 04e6bf670e3968864fd858e3d3fa310d601a2420
Enhanced the narrative documentation for tweens.
1 files modified
87 ■■■■ changed files
docs/narr/hooks.rst 87 ●●●● patch | view | raw | blame | history
docs/narr/hooks.rst
@@ -963,8 +963,8 @@
.. _registering_tweens:
Registering "Tweens"
--------------------
Registering Tweens
------------------
.. versionadded:: 1.2
   Tweens
@@ -976,23 +976,76 @@
example, Pyramid-specific view timing support bookkeeping code that examines
exceptions before they are returned to the upstream WSGI application.  Tweens
behave a bit like :term:`WSGI` :term:`middleware` but they have the benefit of
running in a context in which they have access to the Pyramid
:term:`application registry` as well as the Pyramid rendering machinery.
running in a context in which they have access to the Pyramid :term:`request`,
:term:`response` and :term:`application registry` as well as the Pyramid
rendering machinery.
Creating a Tween Factory
~~~~~~~~~~~~~~~~~~~~~~~~
Creating a Tween
~~~~~~~~~~~~~~~~
To make use of tweens, you must construct a "tween factory".  A tween factory
To create a tween, you must write a "tween factory".  A tween factory
must be a globally importable callable which accepts two arguments:
``handler`` and ``registry``.  ``handler`` will be the either the main
Pyramid request handling function or another tween.  ``registry`` will be the
Pyramid :term:`application registry` represented by this Configurator.  A
tween factory must return a tween when it is called.
tween factory must return the tween (a callable object) when it is called.
A tween is a callable which accepts a :term:`request` object and returns
a :term:`response` object.
A tween is called with a single argument, ``request``, which is the
:term:`request` created by Pyramid's router when it receives a WSGI request.
A tween should return a :term:`response`, usually the one generated by the
downstream Pyramid application.
Here's an example of a tween factory:
You can write the tween factory as a simple closure-returning function:
.. code-block:: python
   :linenos:
    def simple_tween_factory(handler, registry):
        # one-time configuration code goes here
        def simple_tween(request):
            # code to be executed for each request before
            # the actual application code goes here
            response = handler(request)
            # code to be executed for each request after
            # the actual application code goes here
            return response
        return handler
Alternatively, the tween factory can be a class with the ``__call__`` magic method:
.. code-block:: python
   :linenos:
    class simple_tween_factory(object):
        def __init__(handler, registry):
            self.handler = handler
            self.registry = registry
            # one-time configuration code goes here
        def __call__(self, request):
            # code to be executed for each request before
            # the actual application code goes here
            response = self.handler(request)
            # code to be executed for each request after
            # the actual application code goes here
            return response
The closure style performs slightly better and enables you to conditionally
omit the tween from the request processing pipeline (see the following timing
tween example), whereas the class style makes it easier to have shared mutable
state, and it allows subclassing.
Here's a complete example of a tween that logs the time spent processing each
request:
.. code-block:: python
   :linenos:
@@ -1021,12 +1074,6 @@
        # if timing support is not enabled, return the original
        # handler
        return handler
If you remember, a tween is an object which accepts a :term:`request` object
and which returns a :term:`response` argument.  The ``request`` argument to a
tween will be the request created by Pyramid's router when it receives a WSGI
request.  The response object will be generated by the downstream Pyramid
application and it should be returned by the tween.
In the above example, the tween factory defines a ``timing_tween`` tween and
returns it if ``asbool(registry.settings.get('do_timing'))`` is true.  It
@@ -1132,8 +1179,10 @@
  fallbacks if the desired tween is not included, as well as compatibility
  with multiple other tweens.
Effectively, ``under`` means "closer to the main Pyramid application than",
``over`` means "closer to the request ingress than".
Effectively, ``over`` means "closer to the request ingress than" and
``under`` means "closer to the main Pyramid application than".
You can think of an onion with outer layers over the inner layers,
the application being under all the layers at the center.
For example, the following call to
:meth:`~pyramid.config.Configurator.add_tween` will attempt to place the