| | |
| | | |
| | | .. _registering_tweens: |
| | | |
| | | Registering "Tweens" |
| | | -------------------- |
| | | Registering Tweens |
| | | ------------------ |
| | | |
| | | .. versionadded:: 1.2 |
| | | Tweens |
| | |
| | | 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: |
| | |
| | | # 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 |
| | |
| | | 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 |