Repository URL to install this package:
|
Version:
3.0.4 ▾
|
from pprint import saferepr
from pyramid_debugtoolbar.panels import DebugPanel
from pyramid_debugtoolbar.utils import dictrepr
_ = lambda x: x
# extractable_request_attributes allow us to programmatically pull data
# the format is (attr, is_dict)
extractable_request_attributes = (
('accept_charset', False),
('accept_encoding', False),
('accept_language', False),
('application_url', False),
('authorization', False),
('cache_control', False),
('context', False),
('exc_info', False),
('exception', False),
('locale_name', False),
('matchdict', False),
('matched_route', True),
('path', False),
# ('registry', False), # see "Note1"
('root', False),
('subpath', False),
('traversed', False),
('url', False),
('view_name', False),
('virtual_root_path', False),
('virtual_root', False),
)
# Avoid touching these attributes until they are explicitly loaded in the
# request lifecycle. They can have some nasty side-effects otherwise.
lazy_request_attributes = (
('authenticated_userid', False),
('effective_principals', False),
('unauthenticated_userid', False),
)
# Note1: accessed as a 'string', `registry` be the python package name;
# accessed as a dict, will be the contents of the registry
# Note2: only request attributes and properties are supported. all known
# 'read' methods have properties that show the same info
# For example `request.current_url()` is essentially `request.url`
def extract_request_attributes(request):
"""
Extracts useful request attributes from the ``request`` object into a dict.
Data is serialized into a dict so that the original request is no longer
needed.
"""
extracted_attributes = {}
for attr_, is_dict in extractable_request_attributes:
# earlier versions of pyramid may not have newer attrs
# (ie, authenticated_userid)
if not hasattr(request, attr_):
continue
value = None
if is_dict and getattr(request, attr_):
value = getattr(request, attr_).__dict__
else:
value = getattr(request, attr_)
extracted_attributes[attr_] = value
return extracted_attributes
class RequestVarsDebugPanel(DebugPanel):
"""
A panel to display request variables (POST/GET, session, cookies, and
ad-hoc request attributes).
"""
name = 'request_vars'
has_content = True
template = 'pyramid_debugtoolbar.panels:templates/request_vars.dbtmako'
title = _('Request Vars')
nav_title = title
def __init__(self, request):
self.request = request
self.data = data = {}
attrs = request.__dict__.copy()
# environ is displayed separately
del attrs['environ']
if 'response' in attrs:
attrs['response'] = repr(attrs['response'])
if 'session' in attrs:
self.process_session_attr(attrs['session'])
del attrs['session']
else:
# only process the session if it's accessed
wrap_load(
request, 'session',
self.process_session_attr,
reify=True,
)
for attr_, is_dict in lazy_request_attributes:
wrap_load(
request, attr_,
lambda v: self.process_lazy_attr(attr_, is_dict, v),
)
data.update({
'get': [(k, request.GET.getall(k)) for k in request.GET],
'post': [(k, saferepr(v)) for k, v in request.POST.items()],
'cookies': [(k, request.cookies.get(k)) for k in request.cookies],
'environ': dictrepr(request.environ),
'extracted_attributes': {},
'attrs': dictrepr(attrs),
'session': None,
})
def process_session_attr(self, session):
self.data.update({
'session': dictrepr(session),
})
return session
def process_lazy_attr(self, attr, is_dict, val_):
if is_dict:
val = val_.__dict__
else:
val = val_
self.data['extracted_attributes'][attr] = val
return val_
def process_response(self, response):
extracted_attributes = extract_request_attributes(self.request)
self.data['extracted_attributes'].update(extracted_attributes)
# stop hanging onto the request after the response is processed
del self.request
def wrap_load(obj, name, cb, reify=False):
""" Callback when a property is accessed.
This currently only works for reified properties that are called once.
"""
orig_property = getattr(obj.__class__, name, None)
if orig_property is None:
# earlier versions of pyramid may not have newer attrs
# (ie, authenticated_userid)
return
def wrapper(self):
val = orig_property.__get__(obj)
return cb(val)
obj.set_property(wrapper, name=name, reify=reify)