diff options
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/narr/events.rst | 156 |
1 files changed, 73 insertions, 83 deletions
diff --git a/docs/narr/events.rst b/docs/narr/events.rst index 09caac898..c10d4cc47 100644 --- a/docs/narr/events.rst +++ b/docs/narr/events.rst @@ -9,18 +9,18 @@ .. _events_chapter: Using Events -============= +============ -An *event* is an object broadcast by the :app:`Pyramid` framework -at interesting points during the lifetime of an application. You -don't need to use events in order to create most :app:`Pyramid` -applications, but they can be useful when you want to perform slightly -advanced operations. For example, subscribing to an event can allow -you to run some code as the result of every new request. +An *event* is an object broadcast by the :app:`Pyramid` framework at +interesting points during the lifetime of an application. You don't need to +use events in order to create most :app:`Pyramid` applications, but they can be +useful when you want to perform slightly advanced operations. For example, +subscribing to an event can allow you to run some code as the result of every +new request. -Events in :app:`Pyramid` are always broadcast by the framework. -However, they only become useful when you register a *subscriber*. A -subscriber is a function that accepts a single argument named `event`: +Events in :app:`Pyramid` are always broadcast by the framework. However, they +only become useful when you register a *subscriber*. A subscriber is a +function that accepts a single argument named `event`: .. code-block:: python :linenos: @@ -28,23 +28,20 @@ subscriber is a function that accepts a single argument named `event`: def mysubscriber(event): print(event) -The above is a subscriber that simply prints the event to the console -when it's called. +The above is a subscriber that simply prints the event to the console when it's +called. The mere existence of a subscriber function, however, is not sufficient to arrange for it to be called. To arrange for the subscriber to be called, -you'll need to use the -:meth:`pyramid.config.Configurator.add_subscriber` method or you'll -need to use the :func:`pyramid.events.subscriber` decorator to decorate a -function found via a :term:`scan`. +you'll need to use the :meth:`pyramid.config.Configurator.add_subscriber` +method or you'll need to use the :func:`pyramid.events.subscriber` decorator to +decorate a function found via a :term:`scan`. Configuring an Event Listener Imperatively ------------------------------------------ -You can imperatively configure a subscriber function to be called -for some event type via the -:meth:`~pyramid.config.Configurator.add_subscriber` -method: +You can imperatively configure a subscriber function to be called for some +event type via the :meth:`~pyramid.config.Configurator.add_subscriber` method: .. code-block:: python :linenos: @@ -58,10 +55,9 @@ method: config.add_subscriber(mysubscriber, NewRequest) -The first argument to -:meth:`~pyramid.config.Configurator.add_subscriber` is the -subscriber function (or a :term:`dotted Python name` which refers -to a subscriber callable); the second argument is the event type. +The first argument to :meth:`~pyramid.config.Configurator.add_subscriber` is +the subscriber function (or a :term:`dotted Python name` which refers to a +subscriber callable); the second argument is the event type. .. seealso:: @@ -70,8 +66,8 @@ to a subscriber callable); the second argument is the event type. Configuring an Event Listener Using a Decorator ----------------------------------------------- -You can configure a subscriber function to be called for some event -type via the :func:`pyramid.events.subscriber` function. +You can configure a subscriber function to be called for some event type via +the :func:`pyramid.events.subscriber` function. .. code-block:: python :linenos: @@ -83,9 +79,9 @@ type via the :func:`pyramid.events.subscriber` function. def mysubscriber(event): event.request.foo = 1 -When the :func:`~pyramid.events.subscriber` decorator is used a -:term:`scan` must be performed against the package containing the -decorated function for the decorator to have any effect. +When the :func:`~pyramid.events.subscriber` decorator is used, a :term:`scan` +must be performed against the package containing the decorated function for the +decorator to have any effect. Either of the above registration examples implies that every time the :app:`Pyramid` framework emits an event object that supplies an @@ -96,13 +92,12 @@ As you can see, a subscription is made in terms of a *class* (such as :class:`pyramid.events.NewResponse`). The event object sent to a subscriber will always be an object that possesses an :term:`interface`. For :class:`pyramid.events.NewResponse`, that interface is -:class:`pyramid.interfaces.INewResponse`. The interface documentation -provides information about available attributes and methods of the event -objects. +:class:`pyramid.interfaces.INewResponse`. The interface documentation provides +information about available attributes and methods of the event objects. -The return value of a subscriber function is ignored. Subscribers to -the same event type are not guaranteed to be called in any particular -order relative to each other. +The return value of a subscriber function is ignored. Subscribers to the same +event type are not guaranteed to be called in any particular order relative to +each other. All the concrete :app:`Pyramid` event types are documented in the :ref:`events_module` API documentation. @@ -110,8 +105,8 @@ All the concrete :app:`Pyramid` event types are documented in the An Example ---------- -If you create event listener functions in a ``subscribers.py`` file in -your application like so: +If you create event listener functions in a ``subscribers.py`` file in your +application like so: .. code-block:: python :linenos: @@ -122,9 +117,8 @@ your application like so: def handle_new_response(event): print('response', event.response) -You may configure these functions to be called at the appropriate -times by adding the following code to your application's -configuration startup: +You may configure these functions to be called at the appropriate times by +adding the following code to your application's configuration startup: .. code-block:: python :linenos: @@ -136,22 +130,21 @@ configuration startup: config.add_subscriber('myproject.subscribers.handle_new_response', 'pyramid.events.NewResponse') -Either mechanism causes the functions in ``subscribers.py`` to be -registered as event subscribers. Under this configuration, when the -application is run, each time a new request or response is detected, a -message will be printed to the console. +Either mechanism causes the functions in ``subscribers.py`` to be registered as +event subscribers. Under this configuration, when the application is run, each +time a new request or response is detected, a message will be printed to the +console. -Each of our subscriber functions accepts an ``event`` object and -prints an attribute of the event object. This begs the question: how -can we know which attributes a particular event has? +Each of our subscriber functions accepts an ``event`` object and prints an +attribute of the event object. This begs the question: how can we know which +attributes a particular event has? We know that :class:`pyramid.events.NewRequest` event objects have a -``request`` attribute, which is a :term:`request` object, because the -interface defined at :class:`pyramid.interfaces.INewRequest` says it must. -Likewise, we know that :class:`pyramid.interfaces.NewResponse` events have a -``response`` attribute, which is a response object constructed by your -application, because the interface defined at -:class:`pyramid.interfaces.INewResponse` says it must +``request`` attribute, which is a :term:`request` object, because the interface +defined at :class:`pyramid.interfaces.INewRequest` says it must. Likewise, we +know that :class:`pyramid.interfaces.NewResponse` events have a ``response`` +attribute, which is a response object constructed by your application, because +the interface defined at :class:`pyramid.interfaces.INewResponse` says it must (:class:`pyramid.events.NewResponse` objects also have a ``request``). .. _custom_events: @@ -159,21 +152,20 @@ application, because the interface defined at Creating Your Own Events ------------------------ -In addition to using the events that the Pyramid framework creates, -you can create your own events for use in your application. This can -be useful to decouple parts of your application. +In addition to using the events that the Pyramid framework creates, you can +create your own events for use in your application. This can be useful to +decouple parts of your application. -For example, suppose your application has to do many things when a new -document is created. Rather than putting all this logic in the view -that creates the document, you can create the document in your view -and then fire a custom event. Subscribers to the custom event can take -other actions, such as indexing the document, sending email, or -sending a message to a remote system. +For example, suppose your application has to do many things when a new document +is created. Rather than putting all this logic in the view that creates the +document, you can create the document in your view and then fire a custom +event. Subscribers to the custom event can take other actions, such as indexing +the document, sending email, or sending a message to a remote system. -An event is simply an object. There are no required attributes or -method for your custom events. In general, your events should keep -track of the information that subscribers will need. Here are some -example custom event classes: +An event is simply an object. There are no required attributes or method for +your custom events. In general, your events should keep track of the +information that subscribers will need. Here are some example custom event +classes: .. code-block:: python :linenos: @@ -193,11 +185,10 @@ example custom event classes: Some Pyramid applications choose to define custom events classes in an ``events`` module. -You can subscribe to custom events in the same way that you subscribe -to Pyramid events -- either imperatively or with a decorator. You can -also use custom events with :ref:`subscriber predicates -<subscriber_predicates>`. Here's an example of subscribing to a custom -event with a decorator: +You can subscribe to custom events in the same way that you subscribe to +Pyramid events—either imperatively or with a decorator. You can also use custom +events with :ref:`subscriber predicates <subscriber_predicates>`. Here's an +example of subscribing to a custom event with a decorator: .. code-block:: python :linenos: @@ -211,12 +202,12 @@ event with a decorator: # index the document using our application's index_doc function index_doc(event.doc, event.request) -The above example assumes that the application defines a -``DocCreated`` event class and an ``index_doc`` function. +The above example assumes that the application defines a ``DocCreated`` event +class and an ``index_doc`` function. -To fire your custom events use the -:meth:`pyramid.registry.Registry.notify` method, which is most often -accessed as ``request.registry.notify``. For example: +To fire your custom events use the :meth:`pyramid.registry.Registry.notify` +method, which is most often accessed as ``request.registry.notify``. For +example: .. code-block:: python :linenos: @@ -229,11 +220,10 @@ accessed as ``request.registry.notify``. For example: request.registry.notify(event) return {'document': doc} -This example view will notify all subscribers to the custom -``DocCreated`` event. +This example view will notify all subscribers to the custom ``DocCreated`` +event. -Note that when you fire an event, all subscribers are run -synchronously so it's generally not a good idea -to create event handlers that may take a long time to run. Although -event handlers could be used as a central place to spawn tasks on your -own message queues. +Note that when you fire an event, all subscribers are run synchronously so it's +generally not a good idea to create event handlers that may take a long time to +run. Although event handlers could be used as a central place to spawn tasks on +your own message queues. |
