djcheckup 0.2.6__tar.gz → 0.3.0__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.
- {djcheckup-0.2.6 → djcheckup-0.3.0}/PKG-INFO +1 -1
- {djcheckup-0.2.6 → djcheckup-0.3.0}/pyproject.toml +1 -1
- djcheckup-0.3.0/src/djcheckup/__init__.py +6 -0
- {djcheckup-0.2.6 → djcheckup-0.3.0}/src/djcheckup/cli.py +2 -2
- djcheckup-0.3.0/src/djcheckup/outputs.py +96 -0
- {djcheckup-0.2.6 → djcheckup-0.3.0}/src/djcheckup/run.py +6 -6
- djcheckup-0.2.6/src/djcheckup/__init__.py +0 -5
- djcheckup-0.2.6/src/djcheckup/outputs.py +0 -56
- {djcheckup-0.2.6 → djcheckup-0.3.0}/LICENSE +0 -0
- {djcheckup-0.2.6 → djcheckup-0.3.0}/README.md +0 -0
- {djcheckup-0.2.6 → djcheckup-0.3.0}/src/djcheckup/check_defs.py +0 -0
- {djcheckup-0.2.6 → djcheckup-0.3.0}/src/djcheckup/checks.py +0 -0
|
@@ -7,7 +7,7 @@ import typer
|
|
|
7
7
|
|
|
8
8
|
from djcheckup.check_defs import all_checks
|
|
9
9
|
from djcheckup.checks import SiteChecker
|
|
10
|
-
from djcheckup.outputs import
|
|
10
|
+
from djcheckup.outputs import rich_output, sitecheck_as_json
|
|
11
11
|
|
|
12
12
|
app = typer.Typer()
|
|
13
13
|
|
|
@@ -26,6 +26,6 @@ def run_checks(
|
|
|
26
26
|
results = checker.run_checks(all_checks)
|
|
27
27
|
|
|
28
28
|
if output_json:
|
|
29
|
-
rich.print_json(
|
|
29
|
+
rich.print_json(sitecheck_as_json(results))
|
|
30
30
|
else:
|
|
31
31
|
rich_output(results)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Output formats for the site check results."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from collections.abc import Mapping, Sequence
|
|
5
|
+
from dataclasses import asdict
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import TypedDict
|
|
8
|
+
|
|
9
|
+
from rich.console import Console
|
|
10
|
+
from rich.markdown import Markdown
|
|
11
|
+
from rich.panel import Panel
|
|
12
|
+
from rich.table import Table
|
|
13
|
+
|
|
14
|
+
from djcheckup.checks import CheckResult, SiteCheckResult
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class CheckResponseDict(TypedDict):
|
|
18
|
+
"""Represents the response for a single check."""
|
|
19
|
+
|
|
20
|
+
name: str
|
|
21
|
+
result: str # from CheckResult
|
|
22
|
+
severity_score: int # from SeverityWeight
|
|
23
|
+
message: str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SiteCheckResultDict(TypedDict):
|
|
27
|
+
"""Represents the response for a site check."""
|
|
28
|
+
|
|
29
|
+
url: str
|
|
30
|
+
check_results: list[CheckResponseDict]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def rich_output(check_results: SiteCheckResult) -> None:
|
|
34
|
+
"""Display results using Rich."""
|
|
35
|
+
console = Console()
|
|
36
|
+
|
|
37
|
+
table = Table(title=f"DJ Checkup Results for {check_results.url}", show_lines=True)
|
|
38
|
+
|
|
39
|
+
table.add_column("Check", justify="left")
|
|
40
|
+
table.add_column("Result", justify="left")
|
|
41
|
+
table.add_column("Message", justify="left")
|
|
42
|
+
|
|
43
|
+
for result in check_results.check_results:
|
|
44
|
+
emoji = ""
|
|
45
|
+
if result.result == CheckResult.SUCCESS:
|
|
46
|
+
emoji = "🟢 "
|
|
47
|
+
|
|
48
|
+
if result.result == CheckResult.FAILURE:
|
|
49
|
+
emoji = "🔴 "
|
|
50
|
+
|
|
51
|
+
if result.result == CheckResult.SKIPPED:
|
|
52
|
+
emoji = "🟡 "
|
|
53
|
+
|
|
54
|
+
display_result = emoji + result.result.value.capitalize()
|
|
55
|
+
table.add_row(result.name, display_result, Markdown(result.message))
|
|
56
|
+
|
|
57
|
+
console.print(Panel(table))
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
type JSONValue = str | int | Mapping[str, "JSONValue"] | Sequence["JSONValue"]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def normalize_for_json(obj: JSONValue) -> JSONValue:
|
|
64
|
+
"""Recursively convert a dict with Enums to a json-serialisable dict.
|
|
65
|
+
|
|
66
|
+
This is used to convert the SiteCheckResult object to one that can be converted directly to JSON.
|
|
67
|
+
"""
|
|
68
|
+
# dict-like objects
|
|
69
|
+
if isinstance(obj, Mapping):
|
|
70
|
+
return {k: normalize_for_json(v) for k, v in obj.items()}
|
|
71
|
+
|
|
72
|
+
# list-like objects
|
|
73
|
+
if isinstance(obj, Sequence) and not isinstance(obj, (str, bytes, bytearray)):
|
|
74
|
+
return [normalize_for_json(v) for v in obj]
|
|
75
|
+
|
|
76
|
+
# Enums, e.g. SeverityWeight and CheckResult
|
|
77
|
+
if isinstance(obj, Enum):
|
|
78
|
+
return obj.value
|
|
79
|
+
|
|
80
|
+
if isinstance(obj, (str, int)):
|
|
81
|
+
return obj
|
|
82
|
+
|
|
83
|
+
# The following code should never be reached
|
|
84
|
+
msg = f"Unexpected type: {type(obj)}" # pragma: no cover
|
|
85
|
+
raise TypeError(msg) # pragma: no cover
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def sitecheck_as_dict(site_result: SiteCheckResult) -> SiteCheckResultDict:
|
|
89
|
+
"""Convert SiteCheckResult into JSON-serialisable dict."""
|
|
90
|
+
return normalize_for_json(asdict(site_result)) # type: ignore # noqa: PGH003
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def sitecheck_as_json(site_result: SiteCheckResult) -> str:
|
|
94
|
+
"""Convert SiteCheckResult into JSON string."""
|
|
95
|
+
data = sitecheck_as_dict(site_result)
|
|
96
|
+
return json.dumps(data)
|
|
@@ -5,8 +5,8 @@ from typing import Literal, overload
|
|
|
5
5
|
import httpx
|
|
6
6
|
|
|
7
7
|
from djcheckup.check_defs import all_checks
|
|
8
|
-
from djcheckup.checks import SiteChecker
|
|
9
|
-
from djcheckup.outputs import
|
|
8
|
+
from djcheckup.checks import SiteChecker
|
|
9
|
+
from djcheckup.outputs import SiteCheckResultDict, sitecheck_as_dict, sitecheck_as_json
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
@overload
|
|
@@ -14,7 +14,7 @@ def run_checks(
|
|
|
14
14
|
url: str,
|
|
15
15
|
output_format: Literal["object"] = "object",
|
|
16
16
|
client: httpx.Client | None = None,
|
|
17
|
-
) ->
|
|
17
|
+
) -> SiteCheckResultDict: ...
|
|
18
18
|
@overload
|
|
19
19
|
def run_checks(url: str, output_format: Literal["json"], client: httpx.Client | None = None) -> str: ...
|
|
20
20
|
|
|
@@ -23,7 +23,7 @@ def run_checks(
|
|
|
23
23
|
url: str,
|
|
24
24
|
output_format: Literal["object", "json"] = "object",
|
|
25
25
|
client: httpx.Client | None = None,
|
|
26
|
-
) -> str |
|
|
26
|
+
) -> str | SiteCheckResultDict:
|
|
27
27
|
"""Run the DJ Checkup tool.
|
|
28
28
|
|
|
29
29
|
Args:
|
|
@@ -42,7 +42,7 @@ def run_checks(
|
|
|
42
42
|
raise ValueError(msg)
|
|
43
43
|
|
|
44
44
|
if output_format == "json":
|
|
45
|
-
return
|
|
45
|
+
return sitecheck_as_json(results)
|
|
46
46
|
|
|
47
47
|
# Default to object output
|
|
48
|
-
return results
|
|
48
|
+
return sitecheck_as_dict(results)
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"""Output formats for the site check results."""
|
|
2
|
-
|
|
3
|
-
import json
|
|
4
|
-
from dataclasses import asdict
|
|
5
|
-
|
|
6
|
-
from rich.console import Console
|
|
7
|
-
from rich.markdown import Markdown
|
|
8
|
-
from rich.panel import Panel
|
|
9
|
-
from rich.table import Table
|
|
10
|
-
|
|
11
|
-
from djcheckup.checks import CheckResult, SeverityWeight, SiteCheckResult
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def rich_output(check_results: SiteCheckResult) -> None:
|
|
15
|
-
"""Display results using Rich."""
|
|
16
|
-
console = Console()
|
|
17
|
-
|
|
18
|
-
table = Table(title=f"DJ Checkup Results for {check_results.url}", show_lines=True)
|
|
19
|
-
|
|
20
|
-
table.add_column("Check", justify="left")
|
|
21
|
-
table.add_column("Result", justify="left")
|
|
22
|
-
table.add_column("Message", justify="left")
|
|
23
|
-
|
|
24
|
-
for result in check_results.check_results:
|
|
25
|
-
emoji = ""
|
|
26
|
-
if result.result == CheckResult.SUCCESS:
|
|
27
|
-
emoji = "🟢 "
|
|
28
|
-
|
|
29
|
-
if result.result == CheckResult.FAILURE:
|
|
30
|
-
emoji = "🔴 "
|
|
31
|
-
|
|
32
|
-
if result.result == CheckResult.SKIPPED:
|
|
33
|
-
emoji = "🟡 "
|
|
34
|
-
|
|
35
|
-
display_result = emoji + result.result.value.capitalize()
|
|
36
|
-
table.add_row(result.name, display_result, Markdown(result.message))
|
|
37
|
-
|
|
38
|
-
console.print(Panel(table))
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def json_encoder(obj: object) -> str | int:
|
|
42
|
-
"""Custom JSON encoder for non-serialisable types."""
|
|
43
|
-
if isinstance(obj, SeverityWeight):
|
|
44
|
-
return obj.value
|
|
45
|
-
|
|
46
|
-
if isinstance(obj, CheckResult):
|
|
47
|
-
return obj.value
|
|
48
|
-
|
|
49
|
-
# The following should never happen since this encoder is only used for SeverityWeight and CheckResult
|
|
50
|
-
msg = f"Object of type {type(obj).__name__} is not JSON serialisable" # pragma: no cover
|
|
51
|
-
raise TypeError(msg) # pragma: no cover
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def output_results_as_json(results: SiteCheckResult) -> str:
|
|
55
|
-
"""Convert the results to JSON format."""
|
|
56
|
-
return json.dumps(asdict(results), default=json_encoder)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|