Repository URL to install this package:
|
Version:
3.0.4 ▾
|
from pyramid.decorator import reify
from pyramid.i18n import get_localizer
from pyramid.renderers import render
from pyramid.threadlocal import get_current_request
class DebugPanel(object):
"""
Base class for debug panels. A new instance of this class is created
for every request.
A panel is notified of events throughout the request lifecycle. It
is then persisted and used later by the toolbar to render its results
as a tab on the interface. The lifecycle hooks are available in the
following order:
- :meth:`.__init__`
- :meth:`.wrap_handler`
- :meth:`.process_beforerender`
- :meth:`.process_response`
Each of these hooks is overridable by a subclass to gleen information
from the request and other events for later display.
The panel is later used to render its results. This is done on-demand
and in the lifecycle of a request to the debug toolbar by invoking
:meth:`.render_content`. Any data stored within :attr:`.data` is
injected into the template prior to rendering and is thus a common
location to store the contents of previous events.
"""
#: A unique identifier for the name of the panel. This **must** be
#: defined by a subclass and be a valid Python variable name
#: (something like ``[a-zA-Z0-9_-]+``).
name = NotImplemented
#: If ``False`` then the panel's tab will be disabled and
#: :meth:`.render_content` will not be invoked. Most subclasses will
#: want to set this to ``True``.
has_content = False
#: If the client is able to activate/de-activate the panel then this
#: should be ``True``.
user_activate = False
#: This property will be set by the toolbar, indicating the user's
#: decision to activate or deactivate the panel. If ``user_activate``
#: is ``False`` then ``is_active`` will always be set to ``True``.
is_active = False
#: Must be overridden by subclasses that are using the default
#: implementation of ``render_content``. This is an
#: :term:`asset specification` pointing at the template to be rendered
#: for the panel. Usually of the format
#: ``'mylib:templates/panel.dbtmako'``.
template = NotImplemented
#: Title showing in toolbar. Must be overridden.
nav_title = NotImplemented
#: Subtitle showing until title in toolbar.
nav_subtitle = ''
#: Title showing in panel. Must be overridden.
title = NotImplemented
#: The URL invoked when the panel's tab is cliked. May be overridden to
#: define an arbitrary URL for the panel or do some other custom action
#: when the user clicks on the panel's tab in the toolbar.
url = ''
@reify
def data(self):
"""A dictionary of data, updated during the request lifecycle, and
later used to render the panel's HTML."""
return {}
# Panel methods
def __init__(self, request):
"""Configure the panel for a request.
:param request: The instance of :class:`pyramid.request.Request` that
this object is wrapping.
"""
pass
def render_content(self, request):
"""Return a string containing the HTML to be rendered for the panel.
By default this will render the template defined by the
:attr:`.template` attribute with a rendering context defined by
:attr:`.data` combined with the ``dict`` returned from
:meth:`.render_vars`.
The ``request`` here is the active request in the toolbar. Not the
original request that this panel represents.
"""
data = self.data.copy()
data.update(self.render_vars(request))
return render(self.template, data, request=request)
@property
def dom_id(self):
"""The ``id`` tag of the panel's tab. May be used by CSS and
Javascript to implement custom styles and actions.
By default, the :attr:`.dom_id` for a panel with a :attr:`.name` of
``'performance'`` will be ``'pDebugPanel-performance'``.
"""
return 'pDebugPanel-%s' % self.name
def pluralize(self, singular, plural, n, domain=None, mapping=None):
request = get_current_request()
localizer = get_localizer(request)
return localizer.pluralize(singular, plural, n, domain=domain,
mapping=mapping)
# Standard middleware methods
def process_response(self, response):
"""Receives the response generated by the request.
Override this method to track properties of the response."""
pass
def process_beforerender(self, event):
"""Receives every :class:`pyramid.events.BeforeRender`
event invoked during the request/response lifecycle of the request.
Override this method to track properties of the rendering events.
"""
pass
def wrap_handler(self, handler):
"""May be overridden to monitor the entire lifecycle of the request.
A handler receives a request and returns a response. An example
implementation may be:
.. code-block:: python
def wrap_handler(self, handler):
def wrapper(request):
start_time = time.time()
response = handler(request)
end_time = time.time()
self.data['duration'] = end_time - start_time
return response
return wrapper
"""
return handler
def render_vars(self, request):
"""Invoked by the default implementation of :meth:`.render_content`
and should return a ``dict`` of values to use when rendering the
panel's HTML content. This value is usually injected into templates
as the rendering context.
The ``request`` here is the active request in the toolbar. Not the
original request that this panel represents.
"""
return {}