fg-data-profiling 4.19.0__py2.py3-none-any.whl
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.
- data_profiling/__init__.py +34 -0
- data_profiling/compare_reports.py +359 -0
- data_profiling/config.py +496 -0
- data_profiling/config_default.yaml +223 -0
- data_profiling/config_minimal.yaml +222 -0
- data_profiling/controller/__init__.py +1 -0
- data_profiling/controller/console.py +125 -0
- data_profiling/controller/pandas_decorator.py +21 -0
- data_profiling/expectations_report.py +117 -0
- data_profiling/model/__init__.py +4 -0
- data_profiling/model/alerts.py +780 -0
- data_profiling/model/correlations.py +163 -0
- data_profiling/model/dataframe.py +35 -0
- data_profiling/model/describe.py +210 -0
- data_profiling/model/description.py +108 -0
- data_profiling/model/duplicates.py +14 -0
- data_profiling/model/expectation_algorithms.py +112 -0
- data_profiling/model/handler.py +81 -0
- data_profiling/model/missing.py +146 -0
- data_profiling/model/pairwise.py +33 -0
- data_profiling/model/pandas/__init__.py +55 -0
- data_profiling/model/pandas/correlations_pandas.py +207 -0
- data_profiling/model/pandas/dataframe_pandas.py +26 -0
- data_profiling/model/pandas/describe_boolean_pandas.py +43 -0
- data_profiling/model/pandas/describe_categorical_pandas.py +274 -0
- data_profiling/model/pandas/describe_counts_pandas.py +63 -0
- data_profiling/model/pandas/describe_date_pandas.py +77 -0
- data_profiling/model/pandas/describe_file_pandas.py +56 -0
- data_profiling/model/pandas/describe_generic_pandas.py +36 -0
- data_profiling/model/pandas/describe_image_pandas.py +255 -0
- data_profiling/model/pandas/describe_numeric_pandas.py +175 -0
- data_profiling/model/pandas/describe_path_pandas.py +63 -0
- data_profiling/model/pandas/describe_supported_pandas.py +41 -0
- data_profiling/model/pandas/describe_text_pandas.py +62 -0
- data_profiling/model/pandas/describe_timeseries_pandas.py +222 -0
- data_profiling/model/pandas/describe_url_pandas.py +57 -0
- data_profiling/model/pandas/discretize_pandas.py +81 -0
- data_profiling/model/pandas/duplicates_pandas.py +56 -0
- data_profiling/model/pandas/imbalance_pandas.py +35 -0
- data_profiling/model/pandas/missing_pandas.py +42 -0
- data_profiling/model/pandas/sample_pandas.py +38 -0
- data_profiling/model/pandas/summary_pandas.py +101 -0
- data_profiling/model/pandas/table_pandas.py +56 -0
- data_profiling/model/pandas/timeseries_index_pandas.py +33 -0
- data_profiling/model/pandas/utils_pandas.py +27 -0
- data_profiling/model/sample.py +37 -0
- data_profiling/model/spark/__init__.py +48 -0
- data_profiling/model/spark/correlations_spark.py +152 -0
- data_profiling/model/spark/dataframe_spark.py +34 -0
- data_profiling/model/spark/describe_boolean_spark.py +27 -0
- data_profiling/model/spark/describe_categorical_spark.py +28 -0
- data_profiling/model/spark/describe_counts_spark.py +105 -0
- data_profiling/model/spark/describe_date_spark.py +51 -0
- data_profiling/model/spark/describe_generic_spark.py +30 -0
- data_profiling/model/spark/describe_numeric_spark.py +155 -0
- data_profiling/model/spark/describe_supported_spark.py +33 -0
- data_profiling/model/spark/describe_text_spark.py +25 -0
- data_profiling/model/spark/duplicates_spark.py +54 -0
- data_profiling/model/spark/missing_spark.py +96 -0
- data_profiling/model/spark/sample_spark.py +43 -0
- data_profiling/model/spark/summary_spark.py +95 -0
- data_profiling/model/spark/table_spark.py +58 -0
- data_profiling/model/spark/timeseries_index_spark.py +12 -0
- data_profiling/model/summarizer.py +207 -0
- data_profiling/model/summary.py +66 -0
- data_profiling/model/summary_algorithms.py +276 -0
- data_profiling/model/table.py +10 -0
- data_profiling/model/timeseries_index.py +16 -0
- data_profiling/model/typeset.py +365 -0
- data_profiling/model/typeset_relations.py +143 -0
- data_profiling/profile_report.py +573 -0
- data_profiling/report/__init__.py +4 -0
- data_profiling/report/formatters.py +346 -0
- data_profiling/report/presentation/__init__.py +1 -0
- data_profiling/report/presentation/core/__init__.py +39 -0
- data_profiling/report/presentation/core/alerts.py +18 -0
- data_profiling/report/presentation/core/collapse.py +24 -0
- data_profiling/report/presentation/core/container.py +50 -0
- data_profiling/report/presentation/core/correlation_table.py +21 -0
- data_profiling/report/presentation/core/dropdown.py +44 -0
- data_profiling/report/presentation/core/duplicate.py +16 -0
- data_profiling/report/presentation/core/frequency_table.py +14 -0
- data_profiling/report/presentation/core/frequency_table_small.py +16 -0
- data_profiling/report/presentation/core/html.py +14 -0
- data_profiling/report/presentation/core/image.py +34 -0
- data_profiling/report/presentation/core/item_renderer.py +17 -0
- data_profiling/report/presentation/core/renderable.py +42 -0
- data_profiling/report/presentation/core/root.py +35 -0
- data_profiling/report/presentation/core/sample.py +20 -0
- data_profiling/report/presentation/core/scores.py +32 -0
- data_profiling/report/presentation/core/table.py +26 -0
- data_profiling/report/presentation/core/toggle_button.py +14 -0
- data_profiling/report/presentation/core/variable.py +40 -0
- data_profiling/report/presentation/core/variable_info.py +36 -0
- data_profiling/report/presentation/flavours/__init__.py +9 -0
- data_profiling/report/presentation/flavours/flavour_html.py +64 -0
- data_profiling/report/presentation/flavours/flavour_widget.py +61 -0
- data_profiling/report/presentation/flavours/flavours.py +43 -0
- data_profiling/report/presentation/flavours/html/__init__.py +47 -0
- data_profiling/report/presentation/flavours/html/alerts.py +10 -0
- data_profiling/report/presentation/flavours/html/collapse.py +7 -0
- data_profiling/report/presentation/flavours/html/container.py +58 -0
- data_profiling/report/presentation/flavours/html/correlation_table.py +13 -0
- data_profiling/report/presentation/flavours/html/dropdown.py +7 -0
- data_profiling/report/presentation/flavours/html/duplicate.py +24 -0
- data_profiling/report/presentation/flavours/html/frequency_table.py +20 -0
- data_profiling/report/presentation/flavours/html/frequency_table_small.py +15 -0
- data_profiling/report/presentation/flavours/html/html.py +6 -0
- data_profiling/report/presentation/flavours/html/image.py +7 -0
- data_profiling/report/presentation/flavours/html/root.py +14 -0
- data_profiling/report/presentation/flavours/html/sample.py +12 -0
- data_profiling/report/presentation/flavours/html/scores.py +11 -0
- data_profiling/report/presentation/flavours/html/table.py +7 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_constant.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_constant_length.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_dirty_category.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_duplicates.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_empty.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_high_cardinality.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_high_correlation.html +4 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_imbalance.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_infinite.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_missing.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_near_duplicates.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_non_stationary.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_seasonal.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_skewed.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_truncated.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_type_date.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_uniform.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_unique.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_unsupported.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts/alert_zeros.html +1 -0
- data_profiling/report/presentation/flavours/html/templates/alerts.html +47 -0
- data_profiling/report/presentation/flavours/html/templates/collapse.html +11 -0
- data_profiling/report/presentation/flavours/html/templates/correlation_table.html +5 -0
- data_profiling/report/presentation/flavours/html/templates/diagram.html +11 -0
- data_profiling/report/presentation/flavours/html/templates/dropdown.html +16 -0
- data_profiling/report/presentation/flavours/html/templates/duplicate.html +5 -0
- data_profiling/report/presentation/flavours/html/templates/frequency_table.html +45 -0
- data_profiling/report/presentation/flavours/html/templates/frequency_table_small.html +34 -0
- data_profiling/report/presentation/flavours/html/templates/report.html +26 -0
- data_profiling/report/presentation/flavours/html/templates/sample.html +10 -0
- data_profiling/report/presentation/flavours/html/templates/scores.html +78 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/batch_grid.html +16 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/grid.html +18 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/list.html +7 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/named_list.html +8 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/overview_tabs.html +30 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/scores.html +3 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/sections.html +13 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/select.html +40 -0
- data_profiling/report/presentation/flavours/html/templates/sequence/tabs.html +30 -0
- data_profiling/report/presentation/flavours/html/templates/table.html +38 -0
- data_profiling/report/presentation/flavours/html/templates/toggle_button.html +18 -0
- data_profiling/report/presentation/flavours/html/templates/variable.html +7 -0
- data_profiling/report/presentation/flavours/html/templates/variable_info.html +49 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/bootstrap.bundle.min.js +7 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/bootstrap.min.css +6 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/cosmo.bootstrap.min.css +12 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/flatly.bootstrap.min.css +12 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/script.js +52 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/simplex.bootstrap.min.css +12 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/style.css +253 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/assets/united.bootstrap.min.css +12 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/footer.html +7 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/javascript.html +18 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/navigation.html +36 -0
- data_profiling/report/presentation/flavours/html/templates/wrapper/style.html +53 -0
- data_profiling/report/presentation/flavours/html/templates.py +76 -0
- data_profiling/report/presentation/flavours/html/toggle_button.py +7 -0
- data_profiling/report/presentation/flavours/html/variable.py +7 -0
- data_profiling/report/presentation/flavours/html/variable_info.py +7 -0
- data_profiling/report/presentation/flavours/widget/__init__.py +49 -0
- data_profiling/report/presentation/flavours/widget/alerts.py +45 -0
- data_profiling/report/presentation/flavours/widget/collapse.py +43 -0
- data_profiling/report/presentation/flavours/widget/container.py +121 -0
- data_profiling/report/presentation/flavours/widget/correlation_table.py +14 -0
- data_profiling/report/presentation/flavours/widget/dropdown.py +31 -0
- data_profiling/report/presentation/flavours/widget/duplicate.py +14 -0
- data_profiling/report/presentation/flavours/widget/frequency_table.py +57 -0
- data_profiling/report/presentation/flavours/widget/frequency_table_small.py +66 -0
- data_profiling/report/presentation/flavours/widget/html.py +11 -0
- data_profiling/report/presentation/flavours/widget/image.py +26 -0
- data_profiling/report/presentation/flavours/widget/notebook.py +81 -0
- data_profiling/report/presentation/flavours/widget/root.py +10 -0
- data_profiling/report/presentation/flavours/widget/sample.py +14 -0
- data_profiling/report/presentation/flavours/widget/table.py +30 -0
- data_profiling/report/presentation/flavours/widget/toggle_button.py +17 -0
- data_profiling/report/presentation/flavours/widget/variable.py +12 -0
- data_profiling/report/presentation/flavours/widget/variable_info.py +11 -0
- data_profiling/report/presentation/frequency_table_utils.py +141 -0
- data_profiling/report/structure/__init__.py +1 -0
- data_profiling/report/structure/correlations.py +123 -0
- data_profiling/report/structure/overview.py +376 -0
- data_profiling/report/structure/report.py +457 -0
- data_profiling/report/structure/variables/__init__.py +35 -0
- data_profiling/report/structure/variables/render_boolean.py +132 -0
- data_profiling/report/structure/variables/render_categorical.py +566 -0
- data_profiling/report/structure/variables/render_common.py +31 -0
- data_profiling/report/structure/variables/render_complex.py +102 -0
- data_profiling/report/structure/variables/render_count.py +172 -0
- data_profiling/report/structure/variables/render_date.py +143 -0
- data_profiling/report/structure/variables/render_file.py +70 -0
- data_profiling/report/structure/variables/render_generic.py +45 -0
- data_profiling/report/structure/variables/render_image.py +204 -0
- data_profiling/report/structure/variables/render_path.py +134 -0
- data_profiling/report/structure/variables/render_real.py +314 -0
- data_profiling/report/structure/variables/render_text.py +189 -0
- data_profiling/report/structure/variables/render_timeseries.py +371 -0
- data_profiling/report/structure/variables/render_url.py +132 -0
- data_profiling/report/utils.py +34 -0
- data_profiling/serialize_report.py +143 -0
- data_profiling/utils/__init__.py +1 -0
- data_profiling/utils/backend.py +9 -0
- data_profiling/utils/cache.py +59 -0
- data_profiling/utils/common.py +142 -0
- data_profiling/utils/compat.py +31 -0
- data_profiling/utils/dataframe.py +238 -0
- data_profiling/utils/logger.py +53 -0
- data_profiling/utils/notebook.py +8 -0
- data_profiling/utils/paths.py +45 -0
- data_profiling/utils/progress_bar.py +15 -0
- data_profiling/utils/styles.py +22 -0
- data_profiling/utils/versions.py +19 -0
- data_profiling/version.py +1 -0
- data_profiling/visualisation/__init__.py +1 -0
- data_profiling/visualisation/context.py +87 -0
- data_profiling/visualisation/missing.py +138 -0
- data_profiling/visualisation/plot.py +1158 -0
- data_profiling/visualisation/utils.py +113 -0
- fg_data_profiling-4.19.0.dist-info/METADATA +362 -0
- fg_data_profiling-4.19.0.dist-info/RECORD +238 -0
- fg_data_profiling-4.19.0.dist-info/WHEEL +6 -0
- fg_data_profiling-4.19.0.dist-info/entry_points.txt +3 -0
- fg_data_profiling-4.19.0.dist-info/licenses/LICENSE +21 -0
- fg_data_profiling-4.19.0.dist-info/top_level.txt +2 -0
- ydata_profiling/__init__.py +43 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
from typing import Any, Dict, Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Renderable(ABC):
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
content: Dict[str, Any],
|
|
9
|
+
name: Optional[str] = None,
|
|
10
|
+
anchor_id: Optional[str] = None,
|
|
11
|
+
classes: Optional[str] = None,
|
|
12
|
+
):
|
|
13
|
+
self.content = content
|
|
14
|
+
if name is not None:
|
|
15
|
+
self.content["name"] = name
|
|
16
|
+
if anchor_id is not None:
|
|
17
|
+
self.content["anchor_id"] = anchor_id
|
|
18
|
+
if classes is not None:
|
|
19
|
+
self.content["classes"] = classes
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def name(self) -> str:
|
|
23
|
+
return self.content["name"]
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def anchor_id(self) -> str:
|
|
27
|
+
return self.content["anchor_id"]
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def classes(self) -> str:
|
|
31
|
+
return self.content["classes"]
|
|
32
|
+
|
|
33
|
+
@abstractmethod
|
|
34
|
+
def render(self) -> Any:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
def __str__(self):
|
|
38
|
+
return self.__class__.__name__
|
|
39
|
+
|
|
40
|
+
@classmethod
|
|
41
|
+
def convert_to_class(cls, obj: "Renderable", flavour_func) -> None: # noqa: ANN001
|
|
42
|
+
obj.__class__ = cls
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from typing import Any, Callable
|
|
2
|
+
|
|
3
|
+
from data_profiling.config import Style
|
|
4
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
5
|
+
from data_profiling.report.presentation.core.renderable import Renderable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Root(ItemRenderer):
|
|
9
|
+
"""
|
|
10
|
+
Wrapper for the report.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(
|
|
14
|
+
self, name: str, body: Renderable, footer: Renderable, style: Style, **kwargs
|
|
15
|
+
):
|
|
16
|
+
super().__init__(
|
|
17
|
+
"report",
|
|
18
|
+
{"body": body, "footer": footer, "style": style},
|
|
19
|
+
name=name,
|
|
20
|
+
**kwargs
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
def __repr__(self) -> str:
|
|
24
|
+
return "Root"
|
|
25
|
+
|
|
26
|
+
def render(self, **kwargs) -> Any:
|
|
27
|
+
raise NotImplementedError()
|
|
28
|
+
|
|
29
|
+
@classmethod
|
|
30
|
+
def convert_to_class(cls, obj: Renderable, flv: Callable) -> None:
|
|
31
|
+
obj.__class__ = cls
|
|
32
|
+
if "body" in obj.content:
|
|
33
|
+
flv(obj.content["body"])
|
|
34
|
+
if "footer" in obj.content:
|
|
35
|
+
flv(obj.content["footer"])
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from typing import Any, Optional
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
|
|
5
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Sample(ItemRenderer):
|
|
9
|
+
def __init__(
|
|
10
|
+
self, name: str, sample: pd.DataFrame, caption: Optional[str] = None, **kwargs
|
|
11
|
+
):
|
|
12
|
+
super().__init__(
|
|
13
|
+
"sample", {"sample": sample, "caption": caption}, name=name, **kwargs
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
def __repr__(self) -> str:
|
|
17
|
+
return "Sample"
|
|
18
|
+
|
|
19
|
+
def render(self) -> Any:
|
|
20
|
+
raise NotImplementedError()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Scores ItemRendered class
|
|
3
|
+
"""
|
|
4
|
+
from typing import Any, Dict, List, Optional
|
|
5
|
+
|
|
6
|
+
from data_profiling.config import Style
|
|
7
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Scores(ItemRenderer):
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
items: List[Dict],
|
|
14
|
+
overall_score: float,
|
|
15
|
+
style: Style,
|
|
16
|
+
name: Optional[str],
|
|
17
|
+
**kwargs
|
|
18
|
+
):
|
|
19
|
+
content = {
|
|
20
|
+
"items": items,
|
|
21
|
+
"overall_score": overall_score,
|
|
22
|
+
"name": name,
|
|
23
|
+
"style": style,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
super().__init__("scores", content=content, **kwargs)
|
|
27
|
+
|
|
28
|
+
def __repr__(self) -> str:
|
|
29
|
+
return "Scores"
|
|
30
|
+
|
|
31
|
+
def render(self) -> Any:
|
|
32
|
+
raise NotImplementedError("Handled by flavour-specific class")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from typing import Any, Optional, Sequence
|
|
2
|
+
|
|
3
|
+
from data_profiling.config import Style
|
|
4
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Table(ItemRenderer):
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
rows: Sequence,
|
|
11
|
+
style: Style,
|
|
12
|
+
name: Optional[str] = None,
|
|
13
|
+
caption: Optional[str] = None,
|
|
14
|
+
**kwargs
|
|
15
|
+
):
|
|
16
|
+
super().__init__(
|
|
17
|
+
"table",
|
|
18
|
+
{"rows": rows, "name": name, "caption": caption, "style": style},
|
|
19
|
+
**kwargs
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
def __repr__(self) -> str:
|
|
23
|
+
return "Table"
|
|
24
|
+
|
|
25
|
+
def render(self) -> Any:
|
|
26
|
+
raise NotImplementedError()
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ToggleButton(ItemRenderer):
|
|
7
|
+
def __init__(self, text: str, **kwargs):
|
|
8
|
+
super().__init__("toggle_button", {"text": text}, **kwargs)
|
|
9
|
+
|
|
10
|
+
def __repr__(self) -> str:
|
|
11
|
+
return "ToggleButton"
|
|
12
|
+
|
|
13
|
+
def render(self) -> Any:
|
|
14
|
+
raise NotImplementedError()
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Any, Callable, Optional
|
|
2
|
+
|
|
3
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
4
|
+
from data_profiling.report.presentation.core.renderable import Renderable
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Variable(ItemRenderer):
|
|
8
|
+
def __init__(
|
|
9
|
+
self,
|
|
10
|
+
top: Renderable,
|
|
11
|
+
bottom: Optional[Renderable] = None,
|
|
12
|
+
ignore: bool = False,
|
|
13
|
+
**kwargs,
|
|
14
|
+
):
|
|
15
|
+
super().__init__(
|
|
16
|
+
"variable", {"top": top, "bottom": bottom, "ignore": ignore}, **kwargs
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
def __str__(self):
|
|
20
|
+
top_text = str(self.content["top"]).replace("\n", "\n\t")
|
|
21
|
+
bottom_text = str(self.content["bottom"]).replace("\n", "\n\t")
|
|
22
|
+
|
|
23
|
+
text = "Variable\n"
|
|
24
|
+
text += f"- top: {top_text}"
|
|
25
|
+
text += f"- bottom: {bottom_text}"
|
|
26
|
+
return text
|
|
27
|
+
|
|
28
|
+
def __repr__(self):
|
|
29
|
+
return "Variable"
|
|
30
|
+
|
|
31
|
+
def render(self) -> Any:
|
|
32
|
+
raise NotImplementedError()
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def convert_to_class(cls, obj: Renderable, flv: Callable) -> None:
|
|
36
|
+
obj.__class__ = cls
|
|
37
|
+
if "top" in obj.content and obj.content["top"] is not None:
|
|
38
|
+
flv(obj.content["top"])
|
|
39
|
+
if "bottom" in obj.content and obj.content["bottom"] is not None:
|
|
40
|
+
flv(obj.content["bottom"])
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
from typing import Any, List
|
|
2
|
+
|
|
3
|
+
from data_profiling.config import Style
|
|
4
|
+
from data_profiling.model.alerts import Alert
|
|
5
|
+
from data_profiling.report.presentation.core.item_renderer import ItemRenderer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class VariableInfo(ItemRenderer):
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
anchor_id: str,
|
|
12
|
+
var_name: str,
|
|
13
|
+
var_type: str,
|
|
14
|
+
alerts: List[Alert],
|
|
15
|
+
description: str,
|
|
16
|
+
style: Style,
|
|
17
|
+
**kwargs
|
|
18
|
+
):
|
|
19
|
+
super().__init__(
|
|
20
|
+
"variable_info",
|
|
21
|
+
{
|
|
22
|
+
"anchor_id": anchor_id,
|
|
23
|
+
"var_name": var_name,
|
|
24
|
+
"description": description,
|
|
25
|
+
"var_type": var_type,
|
|
26
|
+
"alerts": alerts,
|
|
27
|
+
"style": style,
|
|
28
|
+
},
|
|
29
|
+
**kwargs
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def __repr__(self) -> str:
|
|
33
|
+
return "VariableInfo"
|
|
34
|
+
|
|
35
|
+
def render(self) -> Any:
|
|
36
|
+
raise NotImplementedError()
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""
|
|
2
|
+
HTML flavour mapping
|
|
3
|
+
"""
|
|
4
|
+
from data_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 data_profiling.report.presentation.flavours.flavours import register_flavour
|
|
24
|
+
from data_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)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Flavour widget
|
|
3
|
+
"""
|
|
4
|
+
from data_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 data_profiling.report.presentation.flavours.flavours import register_flavour
|
|
23
|
+
from data_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)
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Flavours registry information
|
|
3
|
+
"""
|
|
4
|
+
from data_profiling.report.presentation.core import Root
|
|
5
|
+
from data_profiling.report.presentation.core.renderable import Renderable
|
|
6
|
+
|
|
7
|
+
_FLAVOUR_REGISTRY: dict = {}
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def register_flavour(name: str, mapping: dict) -> None:
|
|
11
|
+
_FLAVOUR_REGISTRY[name] = mapping
|
|
12
|
+
|
|
13
|
+
|
|
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]
|
|
18
|
+
|
|
19
|
+
|
|
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)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def HTMLReport(structure: Root) -> Root:
|
|
29
|
+
from data_profiling.report.presentation.flavours import flavour_html # noqa: F401
|
|
30
|
+
|
|
31
|
+
mapping = get_flavour_mapping("html")
|
|
32
|
+
apply_renderable_mapping(mapping, structure, flavour_func=HTMLReport)
|
|
33
|
+
return structure
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def WidgetReport(structure: Root) -> Root:
|
|
37
|
+
from data_profiling.report.presentation.flavours import ( # noqa: F401
|
|
38
|
+
flavour_widget,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
mapping = get_flavour_mapping("widget")
|
|
42
|
+
apply_renderable_mapping(mapping, structure, flavour_func=WidgetReport)
|
|
43
|
+
return structure
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from data_profiling.report.presentation.flavours.html.alerts import HTMLAlerts
|
|
2
|
+
from data_profiling.report.presentation.flavours.html.collapse import HTMLCollapse
|
|
3
|
+
from data_profiling.report.presentation.flavours.html.container import HTMLContainer
|
|
4
|
+
from data_profiling.report.presentation.flavours.html.correlation_table import (
|
|
5
|
+
HTMLCorrelationTable,
|
|
6
|
+
)
|
|
7
|
+
from data_profiling.report.presentation.flavours.html.dropdown import HTMLDropdown
|
|
8
|
+
from data_profiling.report.presentation.flavours.html.duplicate import HTMLDuplicate
|
|
9
|
+
from data_profiling.report.presentation.flavours.html.frequency_table import (
|
|
10
|
+
HTMLFrequencyTable,
|
|
11
|
+
)
|
|
12
|
+
from data_profiling.report.presentation.flavours.html.frequency_table_small import (
|
|
13
|
+
HTMLFrequencyTableSmall,
|
|
14
|
+
)
|
|
15
|
+
from data_profiling.report.presentation.flavours.html.html import HTMLHTML
|
|
16
|
+
from data_profiling.report.presentation.flavours.html.image import HTMLImage
|
|
17
|
+
from data_profiling.report.presentation.flavours.html.root import HTMLRoot
|
|
18
|
+
from data_profiling.report.presentation.flavours.html.sample import HTMLSample
|
|
19
|
+
from data_profiling.report.presentation.flavours.html.scores import HTMLScores
|
|
20
|
+
from data_profiling.report.presentation.flavours.html.table import HTMLTable
|
|
21
|
+
from data_profiling.report.presentation.flavours.html.toggle_button import (
|
|
22
|
+
HTMLToggleButton,
|
|
23
|
+
)
|
|
24
|
+
from data_profiling.report.presentation.flavours.html.variable import HTMLVariable
|
|
25
|
+
from data_profiling.report.presentation.flavours.html.variable_info import (
|
|
26
|
+
HTMLVariableInfo,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"HTMLCollapse",
|
|
31
|
+
"HTMLContainer",
|
|
32
|
+
"HTMLDuplicate",
|
|
33
|
+
"HTMLDropdown",
|
|
34
|
+
"HTMLFrequencyTable",
|
|
35
|
+
"HTMLFrequencyTableSmall",
|
|
36
|
+
"HTMLHTML",
|
|
37
|
+
"HTMLImage",
|
|
38
|
+
"HTMLRoot",
|
|
39
|
+
"HTMLSample",
|
|
40
|
+
"HTMLTable",
|
|
41
|
+
"HTMLToggleButton",
|
|
42
|
+
"HTMLVariable",
|
|
43
|
+
"HTMLVariableInfo",
|
|
44
|
+
"HTMLAlerts",
|
|
45
|
+
"HTMLCorrelationTable",
|
|
46
|
+
"HTMLScores",
|
|
47
|
+
]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from data_profiling.report.presentation.core.alerts import Alerts
|
|
2
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
3
|
+
from data_profiling.utils.styles import get_alert_styles
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class HTMLAlerts(Alerts):
|
|
7
|
+
def render(self) -> str:
|
|
8
|
+
styles = get_alert_styles()
|
|
9
|
+
|
|
10
|
+
return templates.template("alerts.html").render(**self.content, styles=styles)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Container class definition
|
|
3
|
+
"""
|
|
4
|
+
from data_profiling.report.presentation.core.container import Container
|
|
5
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class HTMLContainer(Container):
|
|
9
|
+
def render(self) -> str:
|
|
10
|
+
if self.sequence_type in ["list", "accordion"]:
|
|
11
|
+
return templates.template("sequence/list.html").render(
|
|
12
|
+
anchor_id=self.content["anchor_id"], items=self.content["items"]
|
|
13
|
+
)
|
|
14
|
+
elif self.sequence_type == "named_list":
|
|
15
|
+
return templates.template("sequence/named_list.html").render(
|
|
16
|
+
anchor_id=self.content["anchor_id"], items=self.content["items"]
|
|
17
|
+
)
|
|
18
|
+
elif self.sequence_type == "overview_tabs":
|
|
19
|
+
return templates.template("sequence/overview_tabs.html").render(
|
|
20
|
+
tabs=self.content["items"],
|
|
21
|
+
anchor_id=self.content["anchor_id"],
|
|
22
|
+
nested=self.content["nested"],
|
|
23
|
+
oss=self.oss,
|
|
24
|
+
)
|
|
25
|
+
elif self.sequence_type == "tabs":
|
|
26
|
+
return templates.template("sequence/tabs.html").render(
|
|
27
|
+
tabs=self.content["items"],
|
|
28
|
+
anchor_id=self.content["anchor_id"],
|
|
29
|
+
nested=self.content["nested"],
|
|
30
|
+
)
|
|
31
|
+
elif self.sequence_type == "select":
|
|
32
|
+
return templates.template("sequence/select.html").render(
|
|
33
|
+
tabs=self.content["items"],
|
|
34
|
+
anchor_id=self.content["anchor_id"],
|
|
35
|
+
nested=self.content["nested"],
|
|
36
|
+
)
|
|
37
|
+
elif self.sequence_type == "sections":
|
|
38
|
+
return templates.template("sequence/sections.html").render(
|
|
39
|
+
sections=self.content["items"],
|
|
40
|
+
full_width=self.content["full_width"],
|
|
41
|
+
)
|
|
42
|
+
elif self.sequence_type == "grid":
|
|
43
|
+
return templates.template("sequence/grid.html").render(
|
|
44
|
+
items=self.content["items"]
|
|
45
|
+
)
|
|
46
|
+
elif self.sequence_type == "batch_grid":
|
|
47
|
+
return templates.template("sequence/batch_grid.html").render(
|
|
48
|
+
items=self.content["items"],
|
|
49
|
+
batch_size=self.content["batch_size"],
|
|
50
|
+
titles=self.content.get("titles", True),
|
|
51
|
+
subtitles=self.content.get("subtitles", False),
|
|
52
|
+
)
|
|
53
|
+
elif self.sequence_type == "scores":
|
|
54
|
+
return templates.template("sequence/scores.html").render(
|
|
55
|
+
anchor_id=self.content["anchor_id"], items=self.content["items"]
|
|
56
|
+
)
|
|
57
|
+
else:
|
|
58
|
+
raise ValueError("Template not understood", self.sequence_type)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from data_profiling.report.presentation.core.correlation_table import CorrelationTable
|
|
2
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HTMLCorrelationTable(CorrelationTable):
|
|
6
|
+
def render(self) -> str:
|
|
7
|
+
correlation_matrix_html = self.content["correlation_matrix"].to_html(
|
|
8
|
+
classes="correlation-table table table-striped",
|
|
9
|
+
float_format="{:.3f}".format,
|
|
10
|
+
)
|
|
11
|
+
return templates.template("correlation_table.html").render(
|
|
12
|
+
**self.content, correlation_matrix_html=correlation_matrix_html
|
|
13
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
from data_profiling.report.presentation.core.duplicate import Duplicate
|
|
4
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def to_html(df: pd.DataFrame) -> str:
|
|
8
|
+
html = df.to_html(
|
|
9
|
+
classes="duplicate table table-striped",
|
|
10
|
+
)
|
|
11
|
+
if df.empty:
|
|
12
|
+
html = html.replace(
|
|
13
|
+
"<tbody>",
|
|
14
|
+
f"<tbody><tr><td colspan={len(df.columns) + 1}>Dataset does not contain duplicate rows.</td></tr>",
|
|
15
|
+
)
|
|
16
|
+
return html
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class HTMLDuplicate(Duplicate):
|
|
20
|
+
def render(self) -> str:
|
|
21
|
+
duplicate_html = to_html(self.content["duplicate"])
|
|
22
|
+
return templates.template("duplicate.html").render(
|
|
23
|
+
**self.content, duplicate_html=duplicate_html
|
|
24
|
+
)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from data_profiling.report.presentation.core import FrequencyTable
|
|
2
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HTMLFrequencyTable(FrequencyTable):
|
|
6
|
+
def render(self) -> str:
|
|
7
|
+
if isinstance(self.content["rows"][0], list):
|
|
8
|
+
html = ""
|
|
9
|
+
|
|
10
|
+
kwargs = self.content.copy()
|
|
11
|
+
del kwargs["rows"]
|
|
12
|
+
for idx, rows in enumerate(self.content["rows"]):
|
|
13
|
+
html += templates.template("frequency_table.html").render(
|
|
14
|
+
rows=rows, idx=idx, **kwargs
|
|
15
|
+
)
|
|
16
|
+
return html
|
|
17
|
+
else:
|
|
18
|
+
return templates.template("frequency_table.html").render(
|
|
19
|
+
**self.content, idx=0
|
|
20
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from data_profiling.report.presentation.core import FrequencyTableSmall
|
|
2
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HTMLFrequencyTableSmall(FrequencyTableSmall):
|
|
6
|
+
def render(self) -> str:
|
|
7
|
+
html = ""
|
|
8
|
+
kwargs = self.content.copy()
|
|
9
|
+
del kwargs["rows"]
|
|
10
|
+
|
|
11
|
+
for idx, rows in enumerate(self.content["rows"]):
|
|
12
|
+
html += templates.template("frequency_table_small.html").render(
|
|
13
|
+
rows=rows, idx=idx, **kwargs
|
|
14
|
+
)
|
|
15
|
+
return html
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from data_profiling.report.presentation.core.root import Root
|
|
2
|
+
from data_profiling.report.presentation.flavours.html import templates
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class HTMLRoot(Root):
|
|
6
|
+
def render(self, **kwargs) -> str:
|
|
7
|
+
nav_items = [
|
|
8
|
+
(section.name, section.anchor_id)
|
|
9
|
+
for section in self.content["body"].content["items"]
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
return templates.template("report.html").render(
|
|
13
|
+
**self.content, nav_items=nav_items, **kwargs
|
|
14
|
+
)
|