Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
pyramid.pdf
Скачиваний:
11
Добавлен:
24.03.2015
Размер:
3.82 Mб
Скачать

29. USING HOOKS

29.13 Registering “Tweens”

latex-note.png

Tweens are a feature which were added in Pyramid 1.2. They are not available in any previous version.

A tween (a contraction of the word “between”) is a bit of code that sits between the Pyramid router’s main request handling function and the upstream WSGI component that uses Pyramid as its “app”. This is a 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 WSGI middleware but they have the benefit of running in a context in which they have access to the Pyramid application registry as well as the Pyramid rendering machinery.

29.13.1 Creating a Tween Factory

To make use of tweens, you must construct 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 application registry represented by this Configurator. A tween factory must return a tween when it is called.

A tween is a callable which accepts a request object and returns a response object.

Here’s an example of a tween factory:

1

2

3

4

5

6

7

8

9

# in a module named myapp.tweens

import time

from pyramid.settings import asbool import logging

log = logging.getLogger(__name__)

def timing_tween_factory(handler, registry):

334

29.13. REGISTERING “TWEENS”

10if asbool(registry.settings.get(’do_timing’)):

11# if timing support is enabled, return a wrapper

12def timing_tween(request):

13

start = time.time()

14

try:

15

response = handler(request)

16

finally:

17

end = time.time()

18

log.debug(’The request took %s seconds’ %

19

(end - start))

20

return response

21return timing_tween

22# if timing support is not enabled, return the original

23# handler

24return handler

If you remember, a tween is an object which accepts a request object and which returns a 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 attribute is a handle to the deployment settings provided by the user (usually in an .ini file). In this case, if the user has defined a do_timing setting, and that setting is True, the user has said she wants to do timing, so the tween factory returns the timing tween; it otherwise just returns the handler it has been provided, preventing any timing.

The example timing tween simply records the start time, calls the downstream handler, logs the number of seconds consumed by the downstream handler, and returns the response.

29.13.2 Registering an Implicit Tween Factory

Once you’ve created a tween factory, you can register it into the implicit tween chain using the pyramid.config.Configurator.add_tween() method using its dotted Python name.

Here’s an example of registering the a tween factory as an “implicit” tween in a Pyramid application:

1

2

3

from pyramid.config import Configurator config = Configurator()

config.add_tween(’myapp.tweens.timing_tween_factory’)

335

29. USING HOOKS

Note that you must use a dotted Python name as the first argument to pyramid.config.Configurator.add_tween(); this must point at a tween factory. You cannot pass the tween factory object itself to the method: it must be dotted Python name that points to a globally importable object. In the above example, we assume that a timing_tween_factory tween factory was defined in a module named myapp.tweens, so the tween factory is importable as myapp.tweens.timing_tween_factory.

When you use pyramid.config.Configurator.add_tween(), you’re instructing the system to use your tween factory at startup time unless the user has provided an explicit tween list in his configuration. This is what’s meant by an “implicit” tween. A user can always elect to supply an explicit tween list, reordering or disincluding implicitly added tweens. See Explicit Tween Ordering for more information about explicit tween ordering.

If more than one call to pyramid.config.Configurator.add_tween() is made within a single application configuration, the tweens will be chained together at application startup time. The first tween factory added via add_tween will be called with the Pyramid exception view tween factory as its handler argument, then the tween factory added directly after that one will be called with the result of the first tween factory as its handler argument, and so on, ad infinitum until all tween factories have been called. The Pyramid router will use the outermost tween produced by this chain (the tween generated by the very last tween factory added) as its request handler function. For example:

1

2

3

4

5

from pyramid.config import Configurator

config = Configurator() config.add_tween(’myapp.tween_factory1’) config.add_tween(’myapp.tween_factory2’)

The above example will generate an implicit tween chain that looks like this:

INGRESS (implicit) myapp.tween_factory2 myapp.tween_factory1

pyramid.tweens.excview_tween_factory (implicit) MAIN (implicit)

29.13.3 Suggesting Implicit Tween Ordering

By default, as described above, the ordering of the chain is controlled entirely by the relative ordering of calls to pyramid.config.Configurator.add_tween(). However, the caller of add_tween can provide an optional hint that can influence the implicit tween chain ordering by supplying under or over (or both) arguments to add_tween(). These hints are only used used when an explicit tween

336

29.13. REGISTERING “TWEENS”

ordering is not used. See Explicit Tween Ordering for a description of how to set an explicit tween ordering.

Allowable values for under or over (or both) are:

None (the default).

A dotted Python name to a tween factory: a string representing the predicted dotted name of a tween factory added in a call to add_tween in the same configuration session.

One of the constants pyramid.tweens.MAIN, pyramid.tweens.INGRESS, or pyramid.tweens.EXCVIEW.

An iterable of any combination of the above. This allows the user to specify 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”.

For example, the following call to add_tween() will attempt to place the tween factory represented by myapp.tween_factory directly ‘above’ (in ptweens order) the main Pyramid request handler.

1

2

3

import pyramid.tweens

config.add_tween(’myapp.tween_factory’, over=pyramid.tweens.MAIN)

The above example will generate an implicit tween chain that looks like this:

INGRESS (implicit) pyramid.tweens.excview_tween_factory (implicit) myapp.tween_factory

MAIN (implicit)

Likewise, calling the following call to add_tween() will attempt to place this tween factory ‘above’ the main handler but ‘below’ a separately added tween factory:

1

2

3

4

5

6

7

import pyramid.tweens

config.add_tween(’myapp.tween_factory1’, over=pyramid.tweens.MAIN)

config.add_tween(’myapp.tween_factory2’, over=pyramid.tweens.MAIN, under=’myapp.tween_factory1’)

The above example will generate an implicit tween chain that looks like this:

337

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]