summaryrefslogtreecommitdiff
path: root/docs/narr/hooks.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@plope.com>2013-12-05 12:36:37 -0500
committerChris McDonough <chrism@plope.com>2013-12-05 12:36:37 -0500
commitb13969deeb80dd9aa5130d16ea712b323ac3bafe (patch)
treeb4f446fb193f9e8401e9425ca39b90feea8eea65 /docs/narr/hooks.rst
parent4065081434a455a61377c770705375e085be8f16 (diff)
parent3a950cb42ee450a02d567b25bcb2847f586eabfa (diff)
downloadpyramid-b13969deeb80dd9aa5130d16ea712b323ac3bafe.tar.gz
pyramid-b13969deeb80dd9aa5130d16ea712b323ac3bafe.tar.bz2
pyramid-b13969deeb80dd9aa5130d16ea712b323ac3bafe.zip
Merge branch 'master' of github.com:Pylons/pyramid
Diffstat (limited to 'docs/narr/hooks.rst')
-rw-r--r--docs/narr/hooks.rst104
1 files changed, 77 insertions, 27 deletions
diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst
index 0c450fad7..f2542f1d7 100644
--- a/docs/narr/hooks.rst
+++ b/docs/narr/hooks.rst
@@ -363,7 +363,7 @@ and modify the set of :term:`renderer globals` before they are passed to a
that can be used for this purpose. For example:
.. code-block:: python
- :linenos:
+ :linenos:
from pyramid.events import subscriber
from pyramid.events import BeforeRender
@@ -963,8 +963,8 @@ For full details, please read the `Venusian documentation
.. _registering_tweens:
-Registering "Tweens"
---------------------
+Registering Tweens
+------------------
.. versionadded:: 1.2
Tweens
@@ -976,26 +976,80 @@ 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:
+ :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 simple_tween
+
+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:
# in a module named myapp.tweens
@@ -1022,12 +1076,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``
@@ -1053,7 +1101,7 @@ Here's an example of registering a tween factory as an "implicit" tween in a
Pyramid application:
.. code-block:: python
- :linenos:
+ :linenos:
from pyramid.config import Configurator
config = Configurator()
@@ -1087,7 +1135,7 @@ chain (the tween generated by the very last tween factory added) as its
request handler function. For example:
.. code-block:: python
- :linenos:
+ :linenos:
from pyramid.config import Configurator
@@ -1132,8 +1180,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
@@ -1329,7 +1379,7 @@ route predicate factory is most often a class with a constructor
method. For example:
.. code-block:: python
- :linenos:
+ :linenos:
class ContentTypePredicate(object):
def __init__(self, val, config):
@@ -1392,7 +1442,7 @@ with a subscriber that subscribes to the :class:`pyramid.events.NewRequest`
event type.
.. code-block:: python
- :linenos:
+ :linenos:
class RequestPathStartsWith(object):
def __init__(self, val, config):
@@ -1421,7 +1471,7 @@ previously registered ``request_path_startswith`` predicate in a call to
:meth:`~pyramid.config.Configurator.add_subscriber`:
.. code-block:: python
- :linenos:
+ :linenos:
# define a subscriber in your code
@@ -1437,7 +1487,7 @@ Here's the same subscriber/predicate/event-type combination used via
:class:`~pyramid.events.subscriber`.
.. code-block:: python
- :linenos:
+ :linenos:
from pyramid.events import subscriber