From 04e6bf670e3968864fd858e3d3fa310d601a2420 Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sat, 16 Nov 2013 00:31:48 +0200 Subject: Enhanced the narrative documentation for tweens. --- docs/narr/hooks.rst | 87 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 19 deletions(-) (limited to 'docs/narr/hooks.rst') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 0c450fad7..b26a46272 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -963,8 +963,8 @@ For full details, please read the `Venusian documentation .. _registering_tweens: -Registering "Tweens" --------------------- +Registering Tweens +------------------ .. versionadded:: 1.2 Tweens @@ -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: @@ -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`` @@ -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 -- cgit v1.2.3 From a0ef135f2ad6e4425eec7ffcc0839b605347c346 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sat, 16 Nov 2013 05:06:38 -0500 Subject: 80 chars --- docs/narr/hooks.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/narr/hooks.rst') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index b26a46272..84dd2143c 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1016,7 +1016,8 @@ You can write the tween factory as a simple closure-returning function: return handler -Alternatively, the tween factory can be a class with the ``__call__`` magic method: +Alternatively, the tween factory can be a class with the ``__call__`` magic +method: .. code-block:: python :linenos: -- cgit v1.2.3 From 392a6c7df93b67d6889680133fda0f744970d61f Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 00:11:37 +0200 Subject: Removed extra indentation from some examples (:linenos: should be indented with the same indentation as the rest of the code block) --- docs/narr/hooks.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'docs/narr/hooks.rst') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 84dd2143c..14009a094 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 @@ -998,7 +998,7 @@ downstream Pyramid application. 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 @@ -1020,7 +1020,7 @@ Alternatively, the tween factory can be a class with the ``__call__`` magic method: .. code-block:: python - :linenos: + :linenos: class simple_tween_factory(object): def __init__(handler, registry): @@ -1049,7 +1049,7 @@ Here's a complete example of a tween that logs the time spent processing each request: .. code-block:: python - :linenos: + :linenos: # in a module named myapp.tweens @@ -1101,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() @@ -1135,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 @@ -1379,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): @@ -1442,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): @@ -1471,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 @@ -1487,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 -- cgit v1.2.3 From fab44e1e402efbf37fc58875974e9ae42827446e Mon Sep 17 00:00:00 2001 From: Antti Haapala Date: Sun, 17 Nov 2013 19:08:18 +0200 Subject: Should return the simple_tween here, not the handler. --- docs/narr/hooks.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/narr/hooks.rst') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 14009a094..f2542f1d7 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -1014,7 +1014,7 @@ You can write the tween factory as a simple closure-returning function: return response - return handler + return simple_tween Alternatively, the tween factory can be a class with the ``__call__`` magic method: -- cgit v1.2.3