py4web-debug-tools 0.1.1__tar.gz → 0.2.0.dev0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/PKG-INFO +13 -5
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/README.md +12 -4
- py4web-debug-tools-0.2.0.dev0/py4web_debug/core.py +64 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/debugbar.py +2 -2
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/dumping.py +1 -1
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/internals.py +53 -43
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/PKG-INFO +13 -5
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/setup.py +1 -1
- py4web-debug-tools-0.1.1/py4web_debug/core.py +0 -49
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/__init__.py +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/env.py +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/debugbar.html +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/dumpdie.html +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/error_default.html +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/fancy_dumpdie.html +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/SOURCES.txt +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/dependency_links.txt +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/requires.txt +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/top_level.txt +0 -0
- {py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py4web-debug-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0.dev0
|
|
4
4
|
Summary: Debug Tools for py4web
|
|
5
5
|
Home-page: https://github.com/trialandsuccess/py4web-debug-tools
|
|
6
6
|
Author: Robin van der Noord
|
|
@@ -9,7 +9,8 @@ Requires-Python: >3.10.0
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
|
|
11
11
|
# py4web debug tools
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
Tooling to improve the developer experience when working with py4web.
|
|
13
14
|
|
|
14
15
|
There are two main tools and some helpers that this package provides.
|
|
15
16
|
|
|
@@ -19,9 +20,16 @@ There are two main tools and some helpers that this package provides.
|
|
|
19
20
|
## In this package:
|
|
20
21
|
|
|
21
22
|
- `tools`:
|
|
22
|
-
- `enable(db: DAL, enabled
|
|
23
|
-
Fixture).
|
|
24
|
-
The first argument (DAL) is required for the debug bar to collect queries.
|
|
23
|
+
- `enable(db: DAL, enabled?: bool, fancy_rendering?: bool, bar_style?: "bootstrap", slow_threshold_ms?: int)`:
|
|
24
|
+
activate or disable the debug tools (add the custom error screen and create the Debug Bar Fixture).
|
|
25
|
+
The first argument (DAL) is required for the debug bar to collect queries.
|
|
26
|
+
`enabled` can be used to dynamically turn on/off the debug features.
|
|
27
|
+
`fancy_rendering`: This will render the `data` section of the debug bar using `json-browse`, which
|
|
28
|
+
includes `jQuery`. If this clashes with the other JS on a page, this can be set to False to simply show a `<pre>`
|
|
29
|
+
block with data.
|
|
30
|
+
`bar_style`: only bootstrap is supported at this moment.
|
|
31
|
+
`slow_threshold_ms`: amount of milliseconds an SQL query has to take before it is considered a 'slow query' in the
|
|
32
|
+
debug bar.
|
|
25
33
|
- `debug_bar`: this Fixture can be used on py4web actions to enable the bar for that page.
|
|
26
34
|
- `catch(*)`: Data and a stacktrace of where `catch()` is called can be found in the catch tab of the debug bar.
|
|
27
35
|
- `dump(*)`: convert objects to JSON, with a more capable converter than the default json.dumps (e.g. it works better
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# py4web debug tools
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
Tooling to improve the developer experience when working with py4web.
|
|
3
4
|
|
|
4
5
|
There are two main tools and some helpers that this package provides.
|
|
5
6
|
|
|
@@ -9,9 +10,16 @@ There are two main tools and some helpers that this package provides.
|
|
|
9
10
|
## In this package:
|
|
10
11
|
|
|
11
12
|
- `tools`:
|
|
12
|
-
- `enable(db: DAL, enabled
|
|
13
|
-
Fixture).
|
|
14
|
-
The first argument (DAL) is required for the debug bar to collect queries.
|
|
13
|
+
- `enable(db: DAL, enabled?: bool, fancy_rendering?: bool, bar_style?: "bootstrap", slow_threshold_ms?: int)`:
|
|
14
|
+
activate or disable the debug tools (add the custom error screen and create the Debug Bar Fixture).
|
|
15
|
+
The first argument (DAL) is required for the debug bar to collect queries.
|
|
16
|
+
`enabled` can be used to dynamically turn on/off the debug features.
|
|
17
|
+
`fancy_rendering`: This will render the `data` section of the debug bar using `json-browse`, which
|
|
18
|
+
includes `jQuery`. If this clashes with the other JS on a page, this can be set to False to simply show a `<pre>`
|
|
19
|
+
block with data.
|
|
20
|
+
`bar_style`: only bootstrap is supported at this moment.
|
|
21
|
+
`slow_threshold_ms`: amount of milliseconds an SQL query has to take before it is considered a 'slow query' in the
|
|
22
|
+
debug bar.
|
|
15
23
|
- `debug_bar`: this Fixture can be used on py4web actions to enable the bar for that page.
|
|
16
24
|
- `catch(*)`: Data and a stacktrace of where `catch()` is called can be found in the catch tab of the debug bar.
|
|
17
25
|
- `dump(*)`: convert objects to JSON, with a more capable converter than the default json.dumps (e.g. it works better
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Transforms janky 'internals' into easy to work with tool
|
|
2
|
+
import os
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
from py4web import DAL as P4WDAL
|
|
6
|
+
|
|
7
|
+
from .debugbar import DummyDebugBar, DebugBar
|
|
8
|
+
from .env import is_debug
|
|
9
|
+
from .internals import patch_py4
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DebugTools:
|
|
13
|
+
# by default, it is not enabled! This is so you can still import it on production,
|
|
14
|
+
# but don't actually show any debug info. enable(on_off) can be called with e.g. an ENV variable
|
|
15
|
+
enabled = False
|
|
16
|
+
db: P4WDAL
|
|
17
|
+
debug_bar = DummyDebugBar()
|
|
18
|
+
IS_DEBUG: bool = is_debug()
|
|
19
|
+
|
|
20
|
+
def enable(
|
|
21
|
+
self,
|
|
22
|
+
# general settings:
|
|
23
|
+
db: P4WDAL,
|
|
24
|
+
enabled: bool | None = None, # OVERWRITES errorpage_enabled and debugbar_enabled
|
|
25
|
+
set_env_var: bool = True,
|
|
26
|
+
|
|
27
|
+
# error screen settings:
|
|
28
|
+
errorpage_enabled: bool = None, # value of 'enabled' is used by default
|
|
29
|
+
errorpage_renderer: typing.Callable = None,
|
|
30
|
+
|
|
31
|
+
# debugbar settings:
|
|
32
|
+
debugbar_enabled: bool = None, # value of 'enabled' is used by default
|
|
33
|
+
debugbar_fancy_rendering: bool = True,
|
|
34
|
+
debugbar_style: typing.Literal["bootstrap"] = "bootstrap",
|
|
35
|
+
debugbar_slow_threshold_ms: int = 10,
|
|
36
|
+
):
|
|
37
|
+
"""
|
|
38
|
+
By default, on_off looks at PY4WEB_DEBUG_MODE in the env
|
|
39
|
+
|
|
40
|
+
@todo: debugbar style (bootstrap/default, bulma, ...)
|
|
41
|
+
"""
|
|
42
|
+
if enabled is None:
|
|
43
|
+
enabled = is_debug()
|
|
44
|
+
|
|
45
|
+
self.db = db
|
|
46
|
+
self.enabled = enabled
|
|
47
|
+
|
|
48
|
+
self.IS_DEBUG = enabled
|
|
49
|
+
if enabled:
|
|
50
|
+
if errorpage_enabled in (True, None):
|
|
51
|
+
patch_py4(errorpage_renderer)
|
|
52
|
+
|
|
53
|
+
if debugbar_enabled in (True, None):
|
|
54
|
+
self.debug_bar = DebugBar(db, debugbar_fancy_rendering, debugbar_style, debugbar_slow_threshold_ms)
|
|
55
|
+
|
|
56
|
+
if set_env_var:
|
|
57
|
+
# will change the result of is_debug (hopefully)
|
|
58
|
+
os.environ["PY4WEB_DEBUG_MODE"] = "1"
|
|
59
|
+
else:
|
|
60
|
+
self.debug_bar = DummyDebugBar()
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
tools = DebugTools()
|
|
64
|
+
|
|
@@ -133,7 +133,7 @@ def debugbar_template(fixture: Fixture, debug_data: dict, fancy=True):
|
|
|
133
133
|
T = typing.TypeVar("T")
|
|
134
134
|
|
|
135
135
|
|
|
136
|
-
def _prune_long_values(value: T) -> T:
|
|
136
|
+
def _prune_long_values(value: T) -> T | str:
|
|
137
137
|
"""
|
|
138
138
|
Find the end values in nested dicts and lists and prune them if they are too long,
|
|
139
139
|
Usually (tm) returns the same type as the input (except when the input is long bytes)
|
|
@@ -146,7 +146,7 @@ def _prune_long_values(value: T) -> T:
|
|
|
146
146
|
for key, item in value.items():
|
|
147
147
|
value[key] = _prune_long_values(item)
|
|
148
148
|
elif isinstance(value, str | bytes) and len(value) > 50:
|
|
149
|
-
|
|
149
|
+
return "[pruned due to length]"
|
|
150
150
|
|
|
151
151
|
return value
|
|
152
152
|
|
|
@@ -5,6 +5,7 @@ import logging
|
|
|
5
5
|
import os
|
|
6
6
|
import re
|
|
7
7
|
import traceback
|
|
8
|
+
import typing
|
|
8
9
|
|
|
9
10
|
import ombott as bottle
|
|
10
11
|
import yatl
|
|
@@ -27,12 +28,17 @@ def custom_error_page(
|
|
|
27
28
|
color=None,
|
|
28
29
|
message=None,
|
|
29
30
|
traceback="",
|
|
30
|
-
err_type=None,
|
|
31
|
+
err_type: str | typing.Type | None = None,
|
|
31
32
|
bare_exception=None,
|
|
33
|
+
|
|
34
|
+
renderer=None
|
|
32
35
|
):
|
|
33
|
-
if not isinstance(err_type, str):
|
|
36
|
+
if err_type and not isinstance(err_type, str):
|
|
34
37
|
err_type = err_type.__name__
|
|
35
38
|
|
|
39
|
+
# make sure the name is a string (but it probably already is:)
|
|
40
|
+
err_type_name = str(err_type)
|
|
41
|
+
|
|
36
42
|
if hasattr(Template, "_on_success"):
|
|
37
43
|
# reset here on error, because on_error might not be called!
|
|
38
44
|
Template.on_success = Template._on_success
|
|
@@ -60,6 +66,9 @@ def custom_error_page(
|
|
|
60
66
|
return json.dumps(context)
|
|
61
67
|
# else - return html error-page
|
|
62
68
|
|
|
69
|
+
if renderer:
|
|
70
|
+
return renderer(context)
|
|
71
|
+
|
|
63
72
|
templates = {
|
|
64
73
|
"default": "error_default.html",
|
|
65
74
|
"DumpDieError": "dumpdie.html",
|
|
@@ -67,7 +76,7 @@ def custom_error_page(
|
|
|
67
76
|
"ApiDumpDieError": None,
|
|
68
77
|
}
|
|
69
78
|
|
|
70
|
-
_tmpl = templates.get(
|
|
79
|
+
_tmpl = templates.get(err_type_name, templates["default"])
|
|
71
80
|
|
|
72
81
|
if _tmpl is None:
|
|
73
82
|
# just bare exception
|
|
@@ -84,44 +93,45 @@ def custom_error_page(
|
|
|
84
93
|
)
|
|
85
94
|
|
|
86
95
|
|
|
87
|
-
def
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
96
|
+
def patch_py4(renderer=None):
|
|
97
|
+
def custom_catch_errors(app_name, func):
|
|
98
|
+
"""Catches and logs errors in an action; also sets request.app_name"""
|
|
99
|
+
|
|
100
|
+
@functools.wraps(func)
|
|
101
|
+
def wrapper(*func_args, **func_kwargs):
|
|
102
|
+
try:
|
|
103
|
+
request.app_name = app_name
|
|
104
|
+
ret = func(*func_args, **func_kwargs)
|
|
105
|
+
if isinstance(ret, dict):
|
|
106
|
+
response.headers["Content-Type"] = "application/json"
|
|
107
|
+
ret = dumps(ret)
|
|
108
|
+
return ret
|
|
109
|
+
except HTTP as http:
|
|
110
|
+
response.status = http.status
|
|
111
|
+
response.headers.update(http.headers)
|
|
112
|
+
return http.body
|
|
113
|
+
except bottle.HTTPResponse:
|
|
114
|
+
raise
|
|
115
|
+
except Exception as e:
|
|
116
|
+
snapshot = get_error_snapshot()
|
|
117
|
+
logging.error(snapshot["traceback"])
|
|
118
|
+
ticket_uuid = error_logger.log(request.app_name, snapshot) or "unknown"
|
|
119
|
+
response.status = 500
|
|
120
|
+
|
|
121
|
+
raise bottle.HTTPResponse(
|
|
122
|
+
body=custom_error_page(
|
|
123
|
+
500,
|
|
124
|
+
button_text=ticket_uuid,
|
|
125
|
+
href="/_dashboard/ticket/" + ticket_uuid,
|
|
126
|
+
traceback=traceback.format_exc(),
|
|
127
|
+
err_type=type(e),
|
|
128
|
+
bare_exception=e,
|
|
129
|
+
|
|
130
|
+
renderer=renderer
|
|
131
|
+
),
|
|
132
|
+
status=500,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return wrapper
|
|
136
|
+
|
|
127
137
|
action.catch_errors = custom_catch_errors
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: py4web-debug-tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0.dev0
|
|
4
4
|
Summary: Debug Tools for py4web
|
|
5
5
|
Home-page: https://github.com/trialandsuccess/py4web-debug-tools
|
|
6
6
|
Author: Robin van der Noord
|
|
@@ -9,7 +9,8 @@ Requires-Python: >3.10.0
|
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
|
|
11
11
|
# py4web debug tools
|
|
12
|
-
|
|
12
|
+
|
|
13
|
+
Tooling to improve the developer experience when working with py4web.
|
|
13
14
|
|
|
14
15
|
There are two main tools and some helpers that this package provides.
|
|
15
16
|
|
|
@@ -19,9 +20,16 @@ There are two main tools and some helpers that this package provides.
|
|
|
19
20
|
## In this package:
|
|
20
21
|
|
|
21
22
|
- `tools`:
|
|
22
|
-
- `enable(db: DAL, enabled
|
|
23
|
-
Fixture).
|
|
24
|
-
The first argument (DAL) is required for the debug bar to collect queries.
|
|
23
|
+
- `enable(db: DAL, enabled?: bool, fancy_rendering?: bool, bar_style?: "bootstrap", slow_threshold_ms?: int)`:
|
|
24
|
+
activate or disable the debug tools (add the custom error screen and create the Debug Bar Fixture).
|
|
25
|
+
The first argument (DAL) is required for the debug bar to collect queries.
|
|
26
|
+
`enabled` can be used to dynamically turn on/off the debug features.
|
|
27
|
+
`fancy_rendering`: This will render the `data` section of the debug bar using `json-browse`, which
|
|
28
|
+
includes `jQuery`. If this clashes with the other JS on a page, this can be set to False to simply show a `<pre>`
|
|
29
|
+
block with data.
|
|
30
|
+
`bar_style`: only bootstrap is supported at this moment.
|
|
31
|
+
`slow_threshold_ms`: amount of milliseconds an SQL query has to take before it is considered a 'slow query' in the
|
|
32
|
+
debug bar.
|
|
25
33
|
- `debug_bar`: this Fixture can be used on py4web actions to enable the bar for that page.
|
|
26
34
|
- `catch(*)`: Data and a stacktrace of where `catch()` is called can be found in the catch tab of the debug bar.
|
|
27
35
|
- `dump(*)`: convert objects to JSON, with a more capable converter than the default json.dumps (e.g. it works better
|
|
@@ -7,7 +7,7 @@ dependencies = ["py4web", "yatl", "pydal", "configurable-json"]
|
|
|
7
7
|
|
|
8
8
|
setup(
|
|
9
9
|
name="py4web-debug-tools",
|
|
10
|
-
version="0.
|
|
10
|
+
version="0.2.0-dev",
|
|
11
11
|
description="Debug Tools for py4web",
|
|
12
12
|
author="Robin van der Noord",
|
|
13
13
|
author_email="contact@trialandsuccess.nl",
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# Transforms janky 'internals' into easy to work with tool
|
|
2
|
-
import os
|
|
3
|
-
|
|
4
|
-
from py4web import DAL as P4WDAL
|
|
5
|
-
|
|
6
|
-
from .debugbar import DummyDebugBar, DebugBar
|
|
7
|
-
from .env import is_debug
|
|
8
|
-
from .internals import patch_py4
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class DebugTools:
|
|
12
|
-
# by default, it is not enabled! This is so you can still import it on production,
|
|
13
|
-
# but don't actually show any debug info. enable(on_off) can be called with e.g. an ENV variable
|
|
14
|
-
enabled = False
|
|
15
|
-
db: P4WDAL
|
|
16
|
-
debug_bar = DummyDebugBar()
|
|
17
|
-
IS_DEBUG: bool = is_debug()
|
|
18
|
-
|
|
19
|
-
def enable(
|
|
20
|
-
self,
|
|
21
|
-
db: P4WDAL,
|
|
22
|
-
enabled: bool = None,
|
|
23
|
-
fancy_rendering=True,
|
|
24
|
-
bar_style="bootstrap",
|
|
25
|
-
slow_threshold_ms=10,
|
|
26
|
-
):
|
|
27
|
-
"""
|
|
28
|
-
By default, on_off looks at PY4WEB_DEBUG_MODE in the env
|
|
29
|
-
|
|
30
|
-
@todo: debugbar style (bootstrap/default, bulma, ...)
|
|
31
|
-
"""
|
|
32
|
-
if enabled is None:
|
|
33
|
-
enabled = os.getenv("PY4WEB_DEBUG_MODE", False)
|
|
34
|
-
|
|
35
|
-
self.db = db
|
|
36
|
-
self.enabled = enabled
|
|
37
|
-
|
|
38
|
-
self.IS_DEBUG = enabled
|
|
39
|
-
if enabled:
|
|
40
|
-
patch_py4()
|
|
41
|
-
self.debug_bar = DebugBar(db, fancy_rendering, bar_style, slow_threshold_ms)
|
|
42
|
-
|
|
43
|
-
# will change the result of is_debug (hopefully)
|
|
44
|
-
os.environ["PY4WEB_DEBUG_MODE"] = "1"
|
|
45
|
-
else:
|
|
46
|
-
self.debug_bar = DummyDebugBar()
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
tools = DebugTools()
|
|
File without changes
|
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/debugbar.html
RENAMED
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/dumpdie.html
RENAMED
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/error_default.html
RENAMED
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug/templates/fancy_dumpdie.html
RENAMED
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/requires.txt
RENAMED
|
File without changes
|
{py4web-debug-tools-0.1.1 → py4web-debug-tools-0.2.0.dev0}/py4web_debug_tools.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|