Skip to content

Commit 81d7deb

Browse files
feat: refactor code to render HTML and widget flavours (#1740)
* feat: refactor code to render HTML and widget flavours * fix: code linter issues * fix: issues related with the banner link * fix: linter errors with imports from flavour_widget * fix: remove unused import * fix: typing fixes * fix: linting types * fix: rm circular import * fix: linting * fix: linter and typing errors * feat: update report rendering to show overview * fix: remove unused import * fix(linting): code formatting --------- Co-authored-by: Azory YData Bot <azory@ydata.ai>
1 parent 58c28d1 commit 81d7deb

File tree

16 files changed

+302
-144
lines changed

16 files changed

+302
-144
lines changed

src/ydata_profiling/report/presentation/core/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ydata_profiling.report.presentation.core.image import Image
1313
from ydata_profiling.report.presentation.core.root import Root
1414
from ydata_profiling.report.presentation.core.sample import Sample
15+
from ydata_profiling.report.presentation.core.scores import Scores
1516
from ydata_profiling.report.presentation.core.table import Table
1617
from ydata_profiling.report.presentation.core.toggle_button import ToggleButton
1718
from ydata_profiling.report.presentation.core.variable import Variable
@@ -34,4 +35,5 @@
3435
"VariableInfo",
3536
"Alerts",
3637
"CorrelationTable",
38+
"Scores",
3739
]

src/ydata_profiling/report/presentation/core/container.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ def __init__(
1212
name: Optional[str] = None,
1313
anchor_id: Optional[str] = None,
1414
classes: Optional[str] = None,
15+
oss: Optional[bool] = None,
1516
**kwargs,
1617
):
1718
args = {"items": items, "nested": nested}
1819
args.update(**kwargs)
1920
super().__init__(args, name, anchor_id, classes)
21+
22+
if oss is not None:
23+
self.oss = oss
24+
2025
self.sequence_type = sequence_type
2126

2227
def __str__(self) -> str:

src/ydata_profiling/report/presentation/core/renderable.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from abc import ABC, abstractmethod
2-
from typing import Any, Callable, Dict, Optional
2+
from typing import Any, Dict, Optional
33

44

55
class Renderable(ABC):
@@ -38,5 +38,5 @@ def __str__(self):
3838
return self.__class__.__name__
3939

4040
@classmethod
41-
def convert_to_class(cls, obj: "Renderable", flv: Callable) -> None:
41+
def convert_to_class(cls, obj: "Renderable", flavour_func) -> None: # noqa: ANN001
4242
obj.__class__ = cls
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""
2+
Scores ItemRendered class
3+
"""
4+
from typing import Any, Dict, List, Optional
5+
6+
from ydata_profiling.report.presentation.core.item_renderer import ItemRenderer
7+
8+
9+
class Scores(ItemRenderer):
10+
def __init__(
11+
self,
12+
items: List[Dict],
13+
overall_score: float,
14+
name: Optional[str],
15+
caption: Optional[str],
16+
**kwargs
17+
):
18+
content = {
19+
"items": items,
20+
"overall_score": overall_score,
21+
"name": name,
22+
"caption": caption,
23+
}
24+
25+
super().__init__("scores", content=content, **kwargs)
26+
27+
def __repr__(self) -> str:
28+
return "Scores"
29+
30+
def render(self) -> Any:
31+
raise NotImplementedError("Handled by flavour-specific class")
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
HTML flavour mapping
3+
"""
4+
from ydata_profiling.report.presentation.core import (
5+
HTML,
6+
Alerts,
7+
Collapse,
8+
Container,
9+
CorrelationTable,
10+
Dropdown,
11+
Duplicate,
12+
FrequencyTable,
13+
FrequencyTableSmall,
14+
Image,
15+
Root,
16+
Sample,
17+
Scores,
18+
Table,
19+
ToggleButton,
20+
Variable,
21+
VariableInfo,
22+
)
23+
from ydata_profiling.report.presentation.flavours.flavours import register_flavour
24+
from ydata_profiling.report.presentation.flavours.html import (
25+
HTMLHTML,
26+
HTMLAlerts,
27+
HTMLCollapse,
28+
HTMLContainer,
29+
HTMLCorrelationTable,
30+
HTMLDropdown,
31+
HTMLDuplicate,
32+
HTMLFrequencyTable,
33+
HTMLFrequencyTableSmall,
34+
HTMLImage,
35+
HTMLRoot,
36+
HTMLSample,
37+
HTMLScores,
38+
HTMLTable,
39+
HTMLToggleButton,
40+
HTMLVariable,
41+
HTMLVariableInfo,
42+
)
43+
44+
html_mapping = {
45+
Container: HTMLContainer,
46+
Variable: HTMLVariable,
47+
VariableInfo: HTMLVariableInfo,
48+
Table: HTMLTable,
49+
HTML: HTMLHTML,
50+
Root: HTMLRoot,
51+
Image: HTMLImage,
52+
FrequencyTable: HTMLFrequencyTable,
53+
FrequencyTableSmall: HTMLFrequencyTableSmall,
54+
Alerts: HTMLAlerts,
55+
Duplicate: HTMLDuplicate,
56+
Dropdown: HTMLDropdown,
57+
Sample: HTMLSample,
58+
ToggleButton: HTMLToggleButton,
59+
Collapse: HTMLCollapse,
60+
CorrelationTable: HTMLCorrelationTable,
61+
Scores: HTMLScores,
62+
}
63+
64+
register_flavour("html", html_mapping)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
"""
2+
Flavour widget
3+
"""
4+
from ydata_profiling.report.presentation.core import (
5+
HTML,
6+
Alerts,
7+
Collapse,
8+
Container,
9+
CorrelationTable,
10+
Dropdown,
11+
Duplicate,
12+
FrequencyTable,
13+
FrequencyTableSmall,
14+
Image,
15+
Root,
16+
Sample,
17+
Table,
18+
ToggleButton,
19+
Variable,
20+
VariableInfo,
21+
)
22+
from ydata_profiling.report.presentation.flavours.flavours import register_flavour
23+
from ydata_profiling.report.presentation.flavours.widget import (
24+
WidgetAlerts,
25+
WidgetCollapse,
26+
WidgetContainer,
27+
WidgetCorrelationTable,
28+
WidgetDropdown,
29+
WidgetDuplicate,
30+
WidgetFrequencyTable,
31+
WidgetFrequencyTableSmall,
32+
WidgetHTML,
33+
WidgetImage,
34+
WidgetRoot,
35+
WidgetSample,
36+
WidgetTable,
37+
WidgetToggleButton,
38+
WidgetVariable,
39+
WidgetVariableInfo,
40+
)
41+
42+
widget_mapping = {
43+
Container: WidgetContainer,
44+
Variable: WidgetVariable,
45+
VariableInfo: WidgetVariableInfo,
46+
Table: WidgetTable,
47+
HTML: WidgetHTML,
48+
Root: WidgetRoot,
49+
Image: WidgetImage,
50+
FrequencyTable: WidgetFrequencyTable,
51+
FrequencyTableSmall: WidgetFrequencyTableSmall,
52+
Alerts: WidgetAlerts,
53+
Duplicate: WidgetDuplicate,
54+
Dropdown: WidgetDropdown,
55+
Sample: WidgetSample,
56+
ToggleButton: WidgetToggleButton,
57+
Collapse: WidgetCollapse,
58+
CorrelationTable: WidgetCorrelationTable,
59+
}
60+
61+
register_flavour("widget", widget_mapping)
Lines changed: 25 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,153 +1,43 @@
1-
from typing import Callable, Dict, Type
2-
1+
"""
2+
Flavours registry information
3+
"""
34
from ydata_profiling.report.presentation.core import Root
45
from ydata_profiling.report.presentation.core.renderable import Renderable
56

7+
_FLAVOUR_REGISTRY: dict = {}
68

7-
def apply_renderable_mapping(
8-
mapping: Dict[Type[Renderable], Type[Renderable]],
9-
structure: Renderable,
10-
flavour: Callable,
11-
) -> None:
12-
mapping[type(structure)].convert_to_class(structure, flavour)
139

10+
def register_flavour(name: str, mapping: dict) -> None:
11+
_FLAVOUR_REGISTRY[name] = mapping
1412

15-
def get_html_renderable_mapping() -> Dict[Type[Renderable], Type[Renderable]]:
16-
"""Workaround variable type annotations not being supported in Python 3.5
1713

18-
Returns:
19-
type annotated mapping dict
20-
"""
21-
from ydata_profiling.report.presentation.core import (
22-
HTML,
23-
Alerts,
24-
Collapse,
25-
Container,
26-
CorrelationTable,
27-
Dropdown,
28-
Duplicate,
29-
FrequencyTable,
30-
FrequencyTableSmall,
31-
Image,
32-
Root,
33-
Sample,
34-
Table,
35-
ToggleButton,
36-
Variable,
37-
VariableInfo,
38-
)
39-
from ydata_profiling.report.presentation.flavours.html import (
40-
HTMLHTML,
41-
HTMLAlerts,
42-
HTMLCollapse,
43-
HTMLContainer,
44-
HTMLCorrelationTable,
45-
HTMLDropdown,
46-
HTMLDuplicate,
47-
HTMLFrequencyTable,
48-
HTMLFrequencyTableSmall,
49-
HTMLImage,
50-
HTMLRoot,
51-
HTMLSample,
52-
HTMLTable,
53-
HTMLToggleButton,
54-
HTMLVariable,
55-
HTMLVariableInfo,
56-
)
57-
58-
return {
59-
Container: HTMLContainer,
60-
Variable: HTMLVariable,
61-
VariableInfo: HTMLVariableInfo,
62-
Table: HTMLTable,
63-
HTML: HTMLHTML,
64-
Root: HTMLRoot,
65-
Image: HTMLImage,
66-
FrequencyTable: HTMLFrequencyTable,
67-
FrequencyTableSmall: HTMLFrequencyTableSmall,
68-
Alerts: HTMLAlerts,
69-
Duplicate: HTMLDuplicate,
70-
Dropdown: HTMLDropdown,
71-
Sample: HTMLSample,
72-
ToggleButton: HTMLToggleButton,
73-
Collapse: HTMLCollapse,
74-
CorrelationTable: HTMLCorrelationTable,
75-
}
14+
def get_flavour_mapping(name: str) -> dict:
15+
if name not in _FLAVOUR_REGISTRY:
16+
raise ValueError(f"Flavour '{name}' is not registered.")
17+
return _FLAVOUR_REGISTRY[name]
7618

7719

78-
def HTMLReport(structure: Root) -> Root:
79-
"""Adds HTML flavour to Renderable
20+
def apply_renderable_mapping(
21+
mapping: dict,
22+
structure: Renderable,
23+
flavour_func, # noqa: ANN001
24+
) -> None:
25+
mapping[type(structure)].convert_to_class(structure, flavour_func)
8026

81-
Args:
82-
structure:
8327

84-
Returns:
28+
def HTMLReport(structure: Root) -> Root:
29+
from ydata_profiling.report.presentation.flavours import flavour_html # noqa: F401
8530

86-
"""
87-
mapping = get_html_renderable_mapping()
88-
apply_renderable_mapping(mapping, structure, flavour=HTMLReport)
31+
mapping = get_flavour_mapping("html")
32+
apply_renderable_mapping(mapping, structure, flavour_func=HTMLReport)
8933
return structure
9034

9135

92-
def get_widget_renderable_mapping() -> Dict[Type[Renderable], Type[Renderable]]:
93-
from ydata_profiling.report.presentation.core import (
94-
HTML,
95-
Alerts,
96-
Collapse,
97-
Container,
98-
CorrelationTable,
99-
Dropdown,
100-
Duplicate,
101-
FrequencyTable,
102-
FrequencyTableSmall,
103-
Image,
104-
Root,
105-
Sample,
106-
Table,
107-
ToggleButton,
108-
Variable,
109-
VariableInfo,
110-
)
111-
from ydata_profiling.report.presentation.flavours.widget import (
112-
WidgetAlerts,
113-
WidgetCollapse,
114-
WidgetContainer,
115-
WidgetCorrelationTable,
116-
WidgetDropdown,
117-
WidgetDuplicate,
118-
WidgetFrequencyTable,
119-
WidgetFrequencyTableSmall,
120-
WidgetHTML,
121-
WidgetImage,
122-
WidgetRoot,
123-
WidgetSample,
124-
WidgetTable,
125-
WidgetToggleButton,
126-
WidgetVariable,
127-
WidgetVariableInfo,
36+
def WidgetReport(structure: Root) -> Root:
37+
from ydata_profiling.report.presentation.flavours import ( # noqa: F401
38+
flavour_widget,
12839
)
12940

130-
return {
131-
Container: WidgetContainer,
132-
Variable: WidgetVariable,
133-
VariableInfo: WidgetVariableInfo,
134-
Table: WidgetTable,
135-
HTML: WidgetHTML,
136-
Root: WidgetRoot,
137-
Image: WidgetImage,
138-
FrequencyTable: WidgetFrequencyTable,
139-
FrequencyTableSmall: WidgetFrequencyTableSmall,
140-
Alerts: WidgetAlerts,
141-
Duplicate: WidgetDuplicate,
142-
Dropdown: WidgetDropdown,
143-
Sample: WidgetSample,
144-
ToggleButton: WidgetToggleButton,
145-
Collapse: WidgetCollapse,
146-
CorrelationTable: WidgetCorrelationTable,
147-
}
148-
149-
150-
def WidgetReport(structure: Root) -> Root:
151-
mapping = get_widget_renderable_mapping()
152-
apply_renderable_mapping(mapping, structure, flavour=WidgetReport)
41+
mapping = get_flavour_mapping("widget")
42+
apply_renderable_mapping(mapping, structure, flavour_func=WidgetReport)
15343
return structure

src/ydata_profiling/report/presentation/flavours/html/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from ydata_profiling.report.presentation.flavours.html.image import HTMLImage
1717
from ydata_profiling.report.presentation.flavours.html.root import HTMLRoot
1818
from ydata_profiling.report.presentation.flavours.html.sample import HTMLSample
19+
from ydata_profiling.report.presentation.flavours.html.scores import HTMLScores
1920
from ydata_profiling.report.presentation.flavours.html.table import HTMLTable
2021
from ydata_profiling.report.presentation.flavours.html.toggle_button import (
2122
HTMLToggleButton,
@@ -42,4 +43,5 @@
4243
"HTMLVariableInfo",
4344
"HTMLAlerts",
4445
"HTMLCorrelationTable",
46+
"HTMLScores",
4547
]

0 commit comments

Comments
 (0)