Skip to content

Commit

Permalink
apply formatting and linting rules (#258)
Browse files Browse the repository at this point in the history
  • Loading branch information
macnewbold authored Apr 30, 2024
2 parents 8799184 + 3573841 commit 691acc1
Show file tree
Hide file tree
Showing 20 changed files with 587 additions and 543 deletions.
3 changes: 2 additions & 1 deletion example/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
app.config["SECRET_KEY"] = "asd"
app.config["SQLALCHEMY_RECORD_QUERIES"] = True
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:////tmp/test.db"
# This is no longer needed for Flask-SQLAlchemy 3.0+, if you're using 2.X you'll want to define this:
# This is no longer needed for Flask-SQLAlchemy 3.0+, if you're using 2.X you'll
# want to define this:
# app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)
Expand Down
161 changes: 93 additions & 68 deletions src/flask_debugtoolbar/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,25 @@
import urllib.parse
import warnings

from flask import Blueprint, current_app, request, g, send_from_directory, url_for
from flask import Blueprint
from flask import current_app
from flask import g
from flask import request
from flask import send_from_directory
from flask import url_for
from flask.globals import request_ctx

from jinja2 import __version__ as __jinja_version__
from jinja2 import Environment, PackageLoader
from jinja2 import Environment
from jinja2 import PackageLoader

from flask_debugtoolbar.toolbar import DebugToolbar
from flask_debugtoolbar.utils import decode_text, gzip_compress, gzip_decompress
from .toolbar import DebugToolbar
from .utils import decode_text
from .utils import gzip_compress
from .utils import gzip_decompress

__version__ = importlib.metadata.version("flask-debugtoolbar")

module = Blueprint('debugtoolbar', __name__)
module = Blueprint("debugtoolbar", __name__)


def replace_insensitive(string, target, replacement):
Expand All @@ -25,8 +32,9 @@ def replace_insensitive(string, target, replacement):
"""
no_case = string.lower()
index = no_case.rfind(target.lower())

if index >= 0:
return string[:index] + replacement + string[index + len(target):]
return string[:index] + replacement + string[index + len(target) :]
else: # no results so return the original string
return string

Expand All @@ -35,13 +43,11 @@ def _printable(value):
try:
return decode_text(repr(value))
except Exception as e:
return '<repr(%s) raised %s: %s>' % (
object.__repr__(value), type(e).__name__, e)
return f"<repr({object.__repr__(value)}) raised {type(e).__name__}: {e}>"


class DebugToolbarExtension(object):
_static_dir = os.path.realpath(
os.path.join(os.path.dirname(__file__), 'static'))
class DebugToolbarExtension:
_static_dir = os.path.realpath(os.path.join(os.path.dirname(__file__), "static"))

_toolbar_codes = [200, 201, 400, 401, 403, 404, 405, 500, 501, 502, 503, 504]
_redirect_codes = [301, 302, 303, 304]
Expand All @@ -50,21 +56,22 @@ def __init__(self, app=None):
self.app = app
# Support threads running `flask.copy_current_request_context` without
# poping toolbar during `teardown_request`
self.debug_toolbars_var = contextvars.ContextVar('debug_toolbars')
jinja_extensions = ['jinja2.ext.i18n']
self.debug_toolbars_var = contextvars.ContextVar("debug_toolbars")
jinja_extensions = ["jinja2.ext.i18n"]

if __jinja_version__[0] == '2':
jinja_extensions.append('jinja2.ext.with_')
if __jinja_version__[0] == "2":
jinja_extensions.append("jinja2.ext.with_")

# Configure jinja for the internal templates and add url rules
# for static data
self.jinja_env = Environment(
autoescape=True,
extensions=jinja_extensions,
loader=PackageLoader(__name__, 'templates'))
self.jinja_env.filters['urlencode'] = urllib.parse.quote_plus
self.jinja_env.filters['printable'] = _printable
self.jinja_env.globals['url_for'] = url_for
loader=PackageLoader(__name__, "templates"),
)
self.jinja_env.filters["urlencode"] = urllib.parse.quote_plus
self.jinja_env.filters["printable"] = _printable
self.jinja_env.globals["url_for"] = url_for

if app is not None:
self.init_app(app)
Expand All @@ -73,13 +80,14 @@ def init_app(self, app):
for k, v in self._default_config(app).items():
app.config.setdefault(k, v)

if not app.config['DEBUG_TB_ENABLED']:
if not app.config["DEBUG_TB_ENABLED"]:
return

if not app.config.get('SECRET_KEY'):
if not app.config.get("SECRET_KEY"):
raise RuntimeError(
"The Flask-DebugToolbar requires the 'SECRET_KEY' config "
"var to be set")
"var to be set"
)

DebugToolbar.load_panels(app)

Expand All @@ -90,30 +98,33 @@ def init_app(self, app):
# Monkey-patch the Flask.dispatch_request method
app.dispatch_request = self.dispatch_request

app.add_url_rule('/_debug_toolbar/static/<path:filename>',
'_debug_toolbar.static', self.send_static_file)
app.add_url_rule(
"/_debug_toolbar/static/<path:filename>",
"_debug_toolbar.static",
self.send_static_file,
)

app.register_blueprint(module, url_prefix='/_debug_toolbar/views')
app.register_blueprint(module, url_prefix="/_debug_toolbar/views")

def _default_config(self, app):
return {
'DEBUG_TB_ENABLED': app.debug,
'DEBUG_TB_HOSTS': (),
'DEBUG_TB_INTERCEPT_REDIRECTS': True,
'DEBUG_TB_PANELS': (
'flask_debugtoolbar.panels.versions.VersionDebugPanel',
'flask_debugtoolbar.panels.timer.TimerDebugPanel',
'flask_debugtoolbar.panels.headers.HeaderDebugPanel',
'flask_debugtoolbar.panels.request_vars.RequestVarsDebugPanel',
'flask_debugtoolbar.panels.config_vars.ConfigVarsDebugPanel',
'flask_debugtoolbar.panels.template.TemplateDebugPanel',
'flask_debugtoolbar.panels.sqlalchemy.SQLAlchemyDebugPanel',
'flask_debugtoolbar.panels.logger.LoggingPanel',
'flask_debugtoolbar.panels.route_list.RouteListDebugPanel',
'flask_debugtoolbar.panels.profiler.ProfilerDebugPanel',
'flask_debugtoolbar.panels.g.GDebugPanel',
"DEBUG_TB_ENABLED": app.debug,
"DEBUG_TB_HOSTS": (),
"DEBUG_TB_INTERCEPT_REDIRECTS": True,
"DEBUG_TB_PANELS": (
"flask_debugtoolbar.panels.versions.VersionDebugPanel",
"flask_debugtoolbar.panels.timer.TimerDebugPanel",
"flask_debugtoolbar.panels.headers.HeaderDebugPanel",
"flask_debugtoolbar.panels.request_vars.RequestVarsDebugPanel",
"flask_debugtoolbar.panels.config_vars.ConfigVarsDebugPanel",
"flask_debugtoolbar.panels.template.TemplateDebugPanel",
"flask_debugtoolbar.panels.sqlalchemy.SQLAlchemyDebugPanel",
"flask_debugtoolbar.panels.logger.LoggingPanel",
"flask_debugtoolbar.panels.route_list.RouteListDebugPanel",
"flask_debugtoolbar.panels.profiler.ProfilerDebugPanel",
"flask_debugtoolbar.panels.g.GDebugPanel",
),
'SQLALCHEMY_RECORD_QUERIES': app.debug,
"SQLALCHEMY_RECORD_QUERIES": app.debug,
}

def dispatch_request(self):
Expand All @@ -128,22 +139,24 @@ def dispatch_request(self):

# if we provide automatic options for this URL and the
# request came with the OPTIONS method, reply automatically
if getattr(rule, 'provide_automatic_options', False) \
and req.method == 'OPTIONS':
if (
getattr(rule, "provide_automatic_options", False)
and req.method == "OPTIONS"
):
return app.make_default_options_response()

# otherwise dispatch to the handler for that endpoint
view_func = app.view_functions[rule.endpoint]
view_func = self.process_view(app, view_func, req.view_args)

return view_func(**req.view_args)

def _show_toolbar(self):
"""Return a boolean to indicate if we need to show the toolbar."""
if request.blueprint == 'debugtoolbar':
if request.blueprint == "debugtoolbar":
return False

hosts = current_app.config['DEBUG_TB_HOSTS']
hosts = current_app.config["DEBUG_TB_HOSTS"]

if hosts and request.remote_addr not in hosts:
return False

Expand All @@ -161,75 +174,85 @@ def process_request(self):

real_request = request._get_current_object()
self.debug_toolbars_var.set({})
self.debug_toolbars_var.get()[real_request] = (
DebugToolbar(real_request, self.jinja_env))
self.debug_toolbars_var.get()[real_request] = DebugToolbar(
real_request, self.jinja_env
)

for panel in self.debug_toolbars_var.get()[real_request].panels:
panel.process_request(real_request)

def process_view(self, app, view_func, view_kwargs):
""" This method is called just before the flask view is called.
"""This method is called just before the flask view is called.
This is done by the dispatch_request method.
"""
real_request = request._get_current_object()

try:
toolbar = self.debug_toolbars_var.get({})[real_request]
except KeyError:
return view_func

for panel in toolbar.panels:
new_view = panel.process_view(real_request, view_func, view_kwargs)

if new_view:
view_func = new_view

return view_func

def process_response(self, response):
real_request = request._get_current_object()

if real_request not in self.debug_toolbars_var.get({}):
return response

# Intercept http redirect codes and display an html page with a
# link to the target.
if current_app.config['DEBUG_TB_INTERCEPT_REDIRECTS']:
if current_app.config["DEBUG_TB_INTERCEPT_REDIRECTS"]:
if response.status_code in self._redirect_codes:
redirect_to = response.location
redirect_code = response.status_code

if redirect_to:
content = self.render('redirect.html', {
'redirect_to': redirect_to,
'redirect_code': redirect_code
})
content = self.render(
"redirect.html",
{"redirect_to": redirect_to, "redirect_code": redirect_code},
)
response.content_length = len(content)
response.location = None
response.response = [content]
response.status_code = 200

# If the http response code is an allowed code then we process to add the
# toolbar to the returned html response.
if not (response.status_code in self._toolbar_codes and
response.is_sequence and
response.headers['content-type'].startswith('text/html')):
if not (
response.status_code in self._toolbar_codes
and response.is_sequence
and response.headers["content-type"].startswith("text/html")
):
return response

content_encoding = response.headers.get('Content-Encoding')
if content_encoding and 'gzip' in content_encoding:
content_encoding = response.headers.get("Content-Encoding")

if content_encoding and "gzip" in content_encoding:
response_html = gzip_decompress(response.data).decode()
else:
response_html = response.get_data(as_text=True)

no_case = response_html.lower()
body_end = no_case.rfind('</body>')
body_end = no_case.rfind("</body>")

if body_end >= 0:
before = response_html[:body_end]
after = response_html[body_end:]
elif no_case.startswith('<!doctype html>'):
elif no_case.startswith("<!doctype html>"):
before = response_html
after = ''
after = ""
else:
warnings.warn('Could not insert debug toolbar.'
' </body> tag not found in response.')
warnings.warn(
"Could not insert debug toolbar." " </body> tag not found in response.",
stacklevel=1,
)
return response

toolbar = self.debug_toolbars_var.get()[real_request]
Expand All @@ -239,10 +262,12 @@ def process_response(self, response):

toolbar_html = toolbar.render_toolbar()

content = ''.join((before, toolbar_html, after))
content = content.encode('utf-8')
if content_encoding and 'gzip' in content_encoding:
content = "".join((before, toolbar_html, after))
content = content.encode("utf-8")

if content_encoding and "gzip" in content_encoding:
content = gzip_compress(content)

response.response = [content]
response.content_length = len(content)

Expand Down
19 changes: 8 additions & 11 deletions src/flask_debugtoolbar/panels/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
"""Base DebugPanel class"""
class DebugPanel:
"""Base class for debug panels."""


class DebugPanel(object):
"""
Base class for debug panels.
"""
# name = Base

# If content returns something, set to true in subclass
Expand All @@ -18,10 +14,11 @@ class DebugPanel(object):
context = {}

# Panel methods
def __init__(self, jinja_env, context={}):
self.context.update(context)
self.jinja_env = jinja_env
def __init__(self, jinja_env, context=None):
if context is not None:
self.context.update(context)

self.jinja_env = jinja_env
# If the client enabled the panel
self.is_active = False

Expand Down Expand Up @@ -53,15 +50,15 @@ def render(self, template_name, context):
return template.render(**context)

def dom_id(self):
return 'flDebug%sPanel' % (self.name.replace(' ', ''))
return f"flDebug{self.name.replace(' ', '')}Panel"

def nav_title(self):
"""Title showing in toolbar"""
raise NotImplementedError

def nav_subtitle(self):
"""Subtitle showing until title in toolbar"""
return ''
return ""

def title(self):
"""Title showing in panel"""
Expand Down
Loading

0 comments on commit 691acc1

Please sign in to comment.