Skip to content

Commit

Permalink
Enhanced the narrative documentation for tweens.
Browse files Browse the repository at this point in the history
  • Loading branch information
ztane committed Nov 15, 2013
1 parent c3aae1f commit 04e6bf6
Showing 1 changed file with 68 additions and 19 deletions.
87 changes: 68 additions & 19 deletions docs/narr/hooks.rst
Original file line number Diff line number Diff line change
Expand Up @@ -963,8 +963,8 @@ For full details, please read the `Venusian documentation

.. _registering_tweens:

Registering "Tweens"
--------------------
Registering Tweens
------------------

.. versionadded:: 1.2
Tweens
Expand All @@ -976,23 +976,76 @@ feature that may be used by Pyramid framework extensions, to provide, for
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:
Expand Down Expand Up @@ -1022,12 +1075,6 @@ Here's an example of a tween factory:
# 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
otherwise simply returns the handler it was given. The ``registry.settings``
Expand Down Expand Up @@ -1132,8 +1179,10 @@ Allowable values for ``under`` or ``over`` (or both) are:
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
Expand Down

0 comments on commit 04e6bf6

Please sign in to comment.