Source code for

import venusian

from zope.interface import implements

from pyramid.interfaces import IContextFound
from pyramid.interfaces import INewRequest
from pyramid.interfaces import INewResponse
from pyramid.interfaces import IApplicationCreated
from pyramid.interfaces import IBeforeRender

[docs]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 import NewRequest from import subscriber @subscriber(NewRequest) def mysubscriber(event): = 1 More than one event type can be passed as a construtor argument. The decorated subscriber will be called for each event type. .. code-block:: python from import NewRequest, NewResponse from import subscriber @subscriber(NewRequest, NewResponse) 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 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 pyramid.config 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 for iface in self.ifaces: config.add_subscriber(wrapped, iface) def __call__(self, wrapped): self.venusian.attach(wrapped, self.register, category='pyramid') return wrapped
[docs]class NewRequest(object): """ An instance of this class is emitted as an :term:`event` whenever :app:`Pyramid` begins to process a new request. The even instance has an attribute, ``request``, which is a :term:`request` object. This event class implements the :class:`pyramid.interfaces.INewRequest` interface.""" implements(INewRequest) def __init__(self, request): self.request = request
[docs]class NewResponse(object): """ An instance of this class is emitted as an :term:`event` whenever any :app:`Pyramid` :term:`view` or :term:`exception view` returns a :term:`response`. The instance has two attributes:``request``, which is the request which caused the response, and ``response``, which is the response object returned by a view or renderer. If the ``response`` was generated by an :term:`exception view`, the request will have an attribute named ``exception``, which is the exception object which caused the exception view to be executed. If the response was generated by a 'normal' view, the request will not have this attribute. This event will not be generated if a response cannot be created due to an exception that is not caught by an exception view (no response is created under this circumstace). This class implements the :class:`pyramid.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:`pyramid.interfaces.INewResponse` event. The :class:`pyramid.interfaces.INewResponse` event exists almost purely for symmetry with the :class:`pyramid.interfaces.INewRequest` event. """ implements(INewResponse) def __init__(self, request, response): self.request = request self.response = response
[docs]class ContextFound(object): """ An instance of this class is emitted as an :term:`event` after the :app:`Pyramid` :term:`router` finds a :term:`context` object (after it performs traversal) but before any view code is executed. The instance has an attribute, ``request``, which is the request object generated by :app:`Pyramid`. 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 attached by context-finding code. This class implements the :class:`pyramid.interfaces.IContextFound` interface. .. note:: As of :app:`Pyramid` 1.0, for backwards compatibility purposes, this event may also be imported as :class:``. """ implements(IContextFound) def __init__(self, request): self.request = request
AfterTraversal = ContextFound # b/c as of 1.0
[docs]class ApplicationCreated(object): """ An instance of this class is emitted as an :term:`event` when the :meth:`pyramid.config.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:`pyramid.interfaces.IApplicationCreated` interface. .. note:: For backwards compatibility purposes, this class can also be imported as :class:``. This was the name of the event class before :app:`Pyramid` 1.0. """ implements(IApplicationCreated) def __init__(self, app): = app self.object = app
WSGIApplicationCreatedEvent = ApplicationCreated # b/c (as of 1.0)
[docs]class BeforeRender(dict): implements(IBeforeRender) """ Subscribers to this event may introspect the and modify the set of :term:`renderer globals` before they are passed to a :term:`renderer`. This event object iself has a dictionary-like interface that can be used for this purpose. For example:: from import subscriber from pyramid.interfaces import IBeforeRender @subscriber(IBeforeRender) def add_global(event): event['mykey'] = 'foo' An object of this type is sent as an event just before a :term:`renderer` is invoked (but *after* the -- deprecated -- application-level renderer globals factory added via :class:`pyramid.config.Configurator.set_renderer_globals_factory`, if any, has injected its own keys into the renderer globals dictionary). If a subscriber adds a key via ``__setitem__`` or that already exists in the renderer globals dictionary, it will overwrite an older value that is already in the globals dictionary. This can be problematic because event subscribers to the BeforeRender event do not possess any relative ordering. For maximum interoperability with other third-party subscribers, if you write an event subscriber meant to be used as a BeforeRender subscriber, your subscriber code will need to (using ``.get`` or ``__contains__`` of the event object) ensure no value already exists in the renderer globals dictionary before setting an overriding value.""" def __init__(self, system): self._system = system def __setitem__(self, name, value): """ Set a name/value pair into the dictionary which is passed to a renderer as the renderer globals dictionary.""" self._system[name] = value
[docs] def setdefault(self, name, default=None): """ Return the existing value for ``name`` in the renderers globals dictionary. If no value with ``name`` exists in the dictionary, set the ``default`` value into the renderer globals dictionary under the name passed. If a value already existed in the dictionary, return it. If a value did not exist in the dictionary, return the default""" return self._system.setdefault(name, default)
[docs] def update(self, d): """ Update the renderer globals dictionary with another dictionary ``d``.""" return self._system.update(d)
def __contains__(self, k): """ Return ``True`` if ``k`` exists in the renderer globals dictionary.""" return k in self._system def __getitem__(self, k): """ Return the value for key ``k`` from the renderer globals dictionary.""" return self._system[k]
[docs] def get(self, k, default=None): """ Return the value for key ``k`` from the renderer globals dictionary, or the default if no such value exists.""" return self._system.get(k)