1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
import venusian
from zope.interface import implements
from repoze.bfg.interfaces import IAfterTraversal
from repoze.bfg.interfaces import INewRequest
from repoze.bfg.interfaces import INewResponse
from repoze.bfg.interfaces import IWSGIApplicationCreatedEvent
class subscriber(object):
""" Decorator activated via a :term:`scan` which treats the
function being decorated as an event subscriber for the set of
interfaces passed as ``*ifaces`` to the decorator constructor.
For example:
.. code-block:: python
from repoze.bfg.interfaces import INewRequest
from repoze.bfg.events import subscriber
@subscriber(INewRequest)
def mysubscriber(event):
event.request.foo = 1
More than one event type can be passed as a construtor argument:
.. code-block:: python
from repoze.bfg.interfaces import INewRequest
from repoze.bfg.events import subscriber
@subscriber(INewRequest, INewResponse)
def mysubscriber(event):
print event
When the ``subscriber`` decorator is used without passing an arguments,
the function it decorates is called for every event sent:
.. code-block:: python
from repoze.bfg.interfaces import INewRequest
from repoze.bfg.events import subscriber
@subscriber()
def mysubscriber(event):
print event
This method will have no effect until a :term:`scan` is performed
against the package or module which contains it, ala:
.. code-block:: python
from repoze.bfg.configuration import Configurator
config = Configurator()
config.scan('somepackage_containing_subscribers')
"""
venusian = venusian # for unit testing
def __init__(self, *ifaces):
self.ifaces = ifaces
def register(self, scanner, name, wrapped):
config = scanner.config
config.add_subscriber(wrapped, self.ifaces)
def __call__(self, wrapped):
self.venusian.attach(wrapped, self.register, category='bfg')
return wrapped
class NewRequest(object):
""" An instance of this class is emitted as an :term:`event`
whenever :mod:`repoze.bfg` begins to process a new request. The
instance has an attribute, ``request``, which is a :term:`request`
object. This class implements the
:class:`repoze.bfg.interfaces.INewRequest` interface."""
implements(INewRequest)
def __init__(self, request):
self.request = request
class NewResponse(object):
""" An instance of this class is emitted as an :term:`event`
whenever any :mod:`repoze.bfg` view returns a :term:`response`.
The instance has an attribute, ``response``, which is the response
object returned by the view. This class implements the
:class:`repoze.bfg.interfaces.INewResponse` interface.
.. note::
Postprocessing a response is usually better handled in a WSGI
:term:`middleware` component than in subscriber code that is
called by a :class:`repoze.bfg.interfaces.INewResponse` event.
The :class:`repoze.bfg.interfaces.INewResponse` event exists
almost purely for symmetry with the
:class:`repoze.bfg.interfaces.INewRequest` event.
"""
implements(INewResponse)
def __init__(self, response):
self.response = response
class AfterTraversal(object):
implements(IAfterTraversal)
""" An instance of this class is emitted as an :term:`event` after
the :mod:`repoze.bfg` :term:`router` performs traversal but before
any view code is executed. The instance has an attribute,
``request``, which is the request object generated by
:mod:`repoze.bfg`. Notably, the request object will have an
attribute named ``context``, which is the context that will be
provided to the view which will eventually be called, as well as
other attributes defined by the traverser. This class implements
the :class:`repoze.bfg.interfaces.IAfterTraversal` interface."""
def __init__(self, request):
self.request = request
class WSGIApplicationCreatedEvent(object):
""" An instance of this class is emitted as an :term:`event` when
the :meth:`repoze.bfg.configuration.Configurator.make_wsgi_app` is
called. The instance has an attribute, ``app``, which is an
instance of the :term:`router` that will handle WSGI requests.
This class implements the
:class:`repoze.bfg.interfaces.IWSGIApplicationCreatedEvent`
interface."""
implements(IWSGIApplicationCreatedEvent)
def __init__(self, app):
self.app = app
self.object = app
|