py4web-debug-tools 1.1.4__tar.gz → 1.2.1__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-1.1.4 → py4web_debug_tools-1.2.1}/.gitignore +2 -1
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/CHANGELOG.md +10 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/PKG-INFO +3 -3
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/pyproject.toml +2 -2
- py4web_debug_tools-1.2.1/src/py4web_debug/__about__.py +1 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/core.py +4 -4
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/debugbar.py +1 -2
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/dumping.py +10 -20
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/internals.py +26 -5
- py4web_debug_tools-1.2.1/src/py4web_debug/types.py +50 -0
- py4web_debug_tools-1.1.4/src/py4web_debug/__about__.py +0 -1
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/README.md +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/__init__.py +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/_internals.py +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/env.py +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/py.typed +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/debugbar.html +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/dumpdie.html +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/error_default.html +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/fancy_dumpdie.html +0 -0
- {py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/wsgi.py +0 -0
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
<!--next-version-placeholder-->
|
|
4
4
|
|
|
5
|
+
## v1.2.1 (2024-11-20)
|
|
6
|
+
|
|
7
|
+
### Fix
|
|
8
|
+
|
|
9
|
+
* Allow logger to be set to False in case you're using py4webs default logger (PY4WEB_ERRORLOG=:stderr) ([`43639f3`](https://github.com/trialandsuccess/py4web-debug-tools/commit/43639f377d92b2f8b96bbdb31f61251fde95f831))
|
|
10
|
+
|
|
11
|
+
## v1.2.0 (2023-11-06)
|
|
12
|
+
### Feature
|
|
13
|
+
* Allow custom `error_logger` for tools.enable ([`a8301bc`](https://github.com/trialandsuccess/py4web-debug-tools/commit/a8301bc1762984fc5af420075acdc09e97bcc378))
|
|
14
|
+
|
|
5
15
|
## v1.1.4 (2023-07-19)
|
|
6
16
|
|
|
7
17
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: py4web-debug-tools
|
|
3
|
-
Version: 1.1
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: Debug Tools for py4web
|
|
5
5
|
Project-URL: Documentation, https://github.com/trialandsuccess/py4web-debug-tools#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/trialandsuccess/py4web-debug-tools/issues
|
|
7
7
|
Project-URL: Source, https://github.com/trialandsuccess/py4web-debug-tools
|
|
8
8
|
Author-email: Robin van der Noord <contact@trialandsuccess.nl>
|
|
9
|
-
License
|
|
9
|
+
License: MIT
|
|
10
10
|
Classifier: Development Status :: 4 - Beta
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -110,7 +110,9 @@ exclude = ["venv", ".bak"]
|
|
|
110
110
|
[tool.ruff]
|
|
111
111
|
target-version = "py311"
|
|
112
112
|
line-length = 120
|
|
113
|
+
extend-exclude = ["*.bak/", "venv*/"]
|
|
113
114
|
|
|
115
|
+
[tool.ruff.lint]
|
|
114
116
|
select = [
|
|
115
117
|
"F", # pyflake error
|
|
116
118
|
"E", # pycodestyle error
|
|
@@ -129,8 +131,6 @@ unfixable = [
|
|
|
129
131
|
# Don't touch unused imports
|
|
130
132
|
"F401",
|
|
131
133
|
]
|
|
132
|
-
extend-exclude = ["*.bak/", "venv*/"]
|
|
133
|
-
|
|
134
134
|
ignore = [
|
|
135
135
|
"RUF013" # implicit Optional
|
|
136
136
|
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.1"
|
|
@@ -7,7 +7,7 @@ from py4web import DAL as P4WDAL
|
|
|
7
7
|
|
|
8
8
|
from .debugbar import DebugBar, DummyDebugBar
|
|
9
9
|
from .env import is_debug
|
|
10
|
-
from .internals import T_Renderer, patch_py4
|
|
10
|
+
from .internals import T_Logger, T_Renderer, patch_py4
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
@dataclass
|
|
@@ -45,6 +45,8 @@ class DebugTools:
|
|
|
45
45
|
# error screen settings:
|
|
46
46
|
errorpage_enabled: bool = None, # value of 'enabled' is used by default
|
|
47
47
|
errorpage_renderer: T_Renderer = None,
|
|
48
|
+
# can be set to False to disable (e.g. when using PY4WEB_ERRORLOG: ":stderr"):
|
|
49
|
+
error_logger: T_Logger | typing.Literal[False] | None = None,
|
|
48
50
|
# debugbar settings:
|
|
49
51
|
debugbar_enabled: bool = None, # value of 'enabled' is used by default
|
|
50
52
|
debugbar_fancy_rendering: bool = True,
|
|
@@ -53,8 +55,6 @@ class DebugTools:
|
|
|
53
55
|
) -> None:
|
|
54
56
|
"""
|
|
55
57
|
By default, on_off looks at PY4WEB_DEBUG_MODE in the env
|
|
56
|
-
|
|
57
|
-
@todo: debugbar style (bootstrap/default, bulma, ...)
|
|
58
58
|
"""
|
|
59
59
|
if enabled is None:
|
|
60
60
|
enabled = is_debug()
|
|
@@ -73,7 +73,7 @@ class DebugTools:
|
|
|
73
73
|
|
|
74
74
|
if enabled:
|
|
75
75
|
if self.config.errorpage.enabled:
|
|
76
|
-
patch_py4(errorpage_renderer)
|
|
76
|
+
patch_py4(errorpage_renderer, error_logger)
|
|
77
77
|
|
|
78
78
|
if self.config.debugbar.enabled:
|
|
79
79
|
if not db:
|
|
@@ -10,35 +10,25 @@ from .env import is_debug
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class PossiblyAsDict(typing.Protocol):
|
|
13
|
-
def as_dict(self) -> dict[str, typing.Any]:
|
|
14
|
-
...
|
|
13
|
+
def as_dict(self) -> dict[str, typing.Any]: ...
|
|
15
14
|
|
|
16
|
-
def asdict(self) -> dict[str, typing.Any]:
|
|
17
|
-
...
|
|
15
|
+
def asdict(self) -> dict[str, typing.Any]: ...
|
|
18
16
|
|
|
19
|
-
def _asdict(self) -> dict[str, typing.Any]:
|
|
20
|
-
...
|
|
17
|
+
def _asdict(self) -> dict[str, typing.Any]: ...
|
|
21
18
|
|
|
22
|
-
def _as_dict(self) -> dict[str, typing.Any]:
|
|
23
|
-
...
|
|
19
|
+
def _as_dict(self) -> dict[str, typing.Any]: ...
|
|
24
20
|
|
|
25
|
-
def to_dict(self) -> dict[str, typing.Any]:
|
|
26
|
-
...
|
|
21
|
+
def to_dict(self) -> dict[str, typing.Any]: ...
|
|
27
22
|
|
|
28
|
-
def todict(self) -> dict[str, typing.Any]:
|
|
29
|
-
...
|
|
23
|
+
def todict(self) -> dict[str, typing.Any]: ...
|
|
30
24
|
|
|
31
|
-
def _todict(self) -> dict[str, typing.Any]:
|
|
32
|
-
...
|
|
25
|
+
def _todict(self) -> dict[str, typing.Any]: ...
|
|
33
26
|
|
|
34
|
-
def _to_dict(self) -> dict[str, typing.Any]:
|
|
35
|
-
...
|
|
27
|
+
def _to_dict(self) -> dict[str, typing.Any]: ...
|
|
36
28
|
|
|
37
|
-
def __json__(self) -> dict[str, typing.Any]:
|
|
38
|
-
...
|
|
29
|
+
def __json__(self) -> dict[str, typing.Any]: ...
|
|
39
30
|
|
|
40
|
-
def as_list(self) -> list[typing.Any]:
|
|
41
|
-
...
|
|
31
|
+
def as_list(self) -> list[typing.Any]: ...
|
|
42
32
|
|
|
43
33
|
|
|
44
34
|
class DDJsonEncoder(ConfigurableJsonEncoder):
|
|
@@ -22,6 +22,8 @@ from py4web.core import (
|
|
|
22
22
|
from typing_extensions import NotRequired
|
|
23
23
|
from yatl import XML
|
|
24
24
|
|
|
25
|
+
from .types import ErrorSnapshot
|
|
26
|
+
|
|
25
27
|
|
|
26
28
|
class ContextDict(typing.TypedDict):
|
|
27
29
|
code: int
|
|
@@ -48,7 +50,7 @@ def custom_error_page(
|
|
|
48
50
|
message: str = None,
|
|
49
51
|
traceback: str = "",
|
|
50
52
|
err_type: str | typing.Type[Exception] | None = None,
|
|
51
|
-
bare_exception: Exception | str = None,
|
|
53
|
+
bare_exception: typing.Optional[Exception | str] = None,
|
|
52
54
|
renderer: T_Renderer = None,
|
|
53
55
|
) -> str:
|
|
54
56
|
if err_type and not isinstance(err_type, str):
|
|
@@ -108,11 +110,23 @@ def custom_error_page(
|
|
|
108
110
|
return typing.cast(str, result)
|
|
109
111
|
|
|
110
112
|
|
|
113
|
+
def default_error_logger(snapshot: ErrorSnapshot) -> None:
|
|
114
|
+
logging.error(snapshot["traceback"])
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
T_Logger = typing.Callable[[ErrorSnapshot], None]
|
|
118
|
+
|
|
119
|
+
|
|
111
120
|
class patch_py4:
|
|
112
121
|
# THIS IS ONLY CALLED ONCE, WHEN tools.enable IS CALLED OR py4web_debug.wsgi IS USED!
|
|
113
122
|
renderer: T_Renderer | None = None
|
|
123
|
+
logger: T_Logger | typing.Literal[False] | None = None
|
|
124
|
+
|
|
125
|
+
def __init__(self, renderer: T_Renderer = None, logger: T_Logger | bool | None = None):
|
|
126
|
+
if logger is True:
|
|
127
|
+
# use default logger:
|
|
128
|
+
logger = None
|
|
114
129
|
|
|
115
|
-
def __init__(self, renderer: T_Renderer = None):
|
|
116
130
|
def custom_catch_errors(app_name: str, func: AnyFunc) -> typing.Callable[..., str]:
|
|
117
131
|
"""Catches and logs errors in an action; also sets request.app_name"""
|
|
118
132
|
|
|
@@ -136,14 +150,19 @@ class patch_py4:
|
|
|
136
150
|
except bottle.HTTPResponse:
|
|
137
151
|
raise
|
|
138
152
|
except Exception as e:
|
|
153
|
+
err_code = 500
|
|
139
154
|
snapshot = get_error_snapshot()
|
|
140
|
-
|
|
155
|
+
if self.logger is not False:
|
|
156
|
+
# False - don't log
|
|
157
|
+
# None - default logger
|
|
158
|
+
(self.logger or default_error_logger)(snapshot)
|
|
159
|
+
|
|
141
160
|
ticket_uuid = error_logger.log(request.app_name, snapshot) or "unknown"
|
|
142
|
-
response.status =
|
|
161
|
+
response.status = err_code
|
|
143
162
|
|
|
144
163
|
raise bottle.HTTPResponse(
|
|
145
164
|
body=custom_error_page(
|
|
146
|
-
|
|
165
|
+
err_code,
|
|
147
166
|
button_text=ticket_uuid,
|
|
148
167
|
href=f"/_dashboard/ticket/{ticket_uuid}",
|
|
149
168
|
traceback=tb.format_exc(),
|
|
@@ -162,3 +181,5 @@ class patch_py4:
|
|
|
162
181
|
|
|
163
182
|
# allows swapping renderer on the fly with tools.set_renderer():
|
|
164
183
|
patch_py4.renderer = renderer
|
|
184
|
+
_logger = getattr(patch_py4, "logger", None) or logger
|
|
185
|
+
patch_py4.logger = staticmethod(_logger) if _logger else None
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import TypedDict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class SystemInfo(TypedDict):
|
|
5
|
+
machine: str
|
|
6
|
+
node: str
|
|
7
|
+
platform: str
|
|
8
|
+
processor: str
|
|
9
|
+
python_branch: str
|
|
10
|
+
python_build: tuple[str, str]
|
|
11
|
+
python_compiler: str
|
|
12
|
+
python_implementation: str
|
|
13
|
+
python_revision: str
|
|
14
|
+
python_version: str
|
|
15
|
+
python_version_tuple: tuple[str, str, str]
|
|
16
|
+
release: str
|
|
17
|
+
system: str
|
|
18
|
+
uname: tuple[str, str, str, str, str]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class OsEnviron(TypedDict):
|
|
22
|
+
SHELL: str
|
|
23
|
+
SESSION_MANAGER: str
|
|
24
|
+
QT_ACCESSIBILITY: str
|
|
25
|
+
# ... (other key-value pairs)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class StackFrame(TypedDict):
|
|
29
|
+
file: str
|
|
30
|
+
func: str
|
|
31
|
+
lnum: int
|
|
32
|
+
code: list[str]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Traceback(TypedDict):
|
|
36
|
+
file: str
|
|
37
|
+
func: str
|
|
38
|
+
lnum: int
|
|
39
|
+
code: list[str]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ErrorSnapshot(TypedDict):
|
|
43
|
+
timestamp: str
|
|
44
|
+
python_version: str
|
|
45
|
+
platform_info: SystemInfo
|
|
46
|
+
os_environ: OsEnviron
|
|
47
|
+
traceback: str
|
|
48
|
+
exception_type: str
|
|
49
|
+
exception_value: str
|
|
50
|
+
stackframes: list[StackFrame]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.1.4"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/debugbar.html
RENAMED
|
File without changes
|
{py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/dumpdie.html
RENAMED
|
File without changes
|
{py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/error_default.html
RENAMED
|
File without changes
|
{py4web_debug_tools-1.1.4 → py4web_debug_tools-1.2.1}/src/py4web_debug/templates/fancy_dumpdie.html
RENAMED
|
File without changes
|
|
File without changes
|