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.
Files changed (238) hide show
  1. data_profiling/__init__.py +34 -0
  2. data_profiling/compare_reports.py +359 -0
  3. data_profiling/config.py +496 -0
  4. data_profiling/config_default.yaml +223 -0
  5. data_profiling/config_minimal.yaml +222 -0
  6. data_profiling/controller/__init__.py +1 -0
  7. data_profiling/controller/console.py +125 -0
  8. data_profiling/controller/pandas_decorator.py +21 -0
  9. data_profiling/expectations_report.py +117 -0
  10. data_profiling/model/__init__.py +4 -0
  11. data_profiling/model/alerts.py +780 -0
  12. data_profiling/model/correlations.py +163 -0
  13. data_profiling/model/dataframe.py +35 -0
  14. data_profiling/model/describe.py +210 -0
  15. data_profiling/model/description.py +108 -0
  16. data_profiling/model/duplicates.py +14 -0
  17. data_profiling/model/expectation_algorithms.py +112 -0
  18. data_profiling/model/handler.py +81 -0
  19. data_profiling/model/missing.py +146 -0
  20. data_profiling/model/pairwise.py +33 -0
  21. data_profiling/model/pandas/__init__.py +55 -0
  22. data_profiling/model/pandas/correlations_pandas.py +207 -0
  23. data_profiling/model/pandas/dataframe_pandas.py +26 -0
  24. data_profiling/model/pandas/describe_boolean_pandas.py +43 -0
  25. data_profiling/model/pandas/describe_categorical_pandas.py +274 -0
  26. data_profiling/model/pandas/describe_counts_pandas.py +63 -0
  27. data_profiling/model/pandas/describe_date_pandas.py +77 -0
  28. data_profiling/model/pandas/describe_file_pandas.py +56 -0
  29. data_profiling/model/pandas/describe_generic_pandas.py +36 -0
  30. data_profiling/model/pandas/describe_image_pandas.py +255 -0
  31. data_profiling/model/pandas/describe_numeric_pandas.py +175 -0
  32. data_profiling/model/pandas/describe_path_pandas.py +63 -0
  33. data_profiling/model/pandas/describe_supported_pandas.py +41 -0
  34. data_profiling/model/pandas/describe_text_pandas.py +62 -0
  35. data_profiling/model/pandas/describe_timeseries_pandas.py +222 -0
  36. data_profiling/model/pandas/describe_url_pandas.py +57 -0
  37. data_profiling/model/pandas/discretize_pandas.py +81 -0
  38. data_profiling/model/pandas/duplicates_pandas.py +56 -0
  39. data_profiling/model/pandas/imbalance_pandas.py +35 -0
  40. data_profiling/model/pandas/missing_pandas.py +42 -0
  41. data_profiling/model/pandas/sample_pandas.py +38 -0
  42. data_profiling/model/pandas/summary_pandas.py +101 -0
  43. data_profiling/model/pandas/table_pandas.py +56 -0
  44. data_profiling/model/pandas/timeseries_index_pandas.py +33 -0
  45. data_profiling/model/pandas/utils_pandas.py +27 -0
  46. data_profiling/model/sample.py +37 -0
  47. data_profiling/model/spark/__init__.py +48 -0
  48. data_profiling/model/spark/correlations_spark.py +152 -0
  49. data_profiling/model/spark/dataframe_spark.py +34 -0
  50. data_profiling/model/spark/describe_boolean_spark.py +27 -0
  51. data_profiling/model/spark/describe_categorical_spark.py +28 -0
  52. data_profiling/model/spark/describe_counts_spark.py +105 -0
  53. data_profiling/model/spark/describe_date_spark.py +51 -0
  54. data_profiling/model/spark/describe_generic_spark.py +30 -0
  55. data_profiling/model/spark/describe_numeric_spark.py +155 -0
  56. data_profiling/model/spark/describe_supported_spark.py +33 -0
  57. data_profiling/model/spark/describe_text_spark.py +25 -0
  58. data_profiling/model/spark/duplicates_spark.py +54 -0
  59. data_profiling/model/spark/missing_spark.py +96 -0
  60. data_profiling/model/spark/sample_spark.py +43 -0
  61. data_profiling/model/spark/summary_spark.py +95 -0
  62. data_profiling/model/spark/table_spark.py +58 -0
  63. data_profiling/model/spark/timeseries_index_spark.py +12 -0
  64. data_profiling/model/summarizer.py +207 -0
  65. data_profiling/model/summary.py +66 -0
  66. data_profiling/model/summary_algorithms.py +276 -0
  67. data_profiling/model/table.py +10 -0
  68. data_profiling/model/timeseries_index.py +16 -0
  69. data_profiling/model/typeset.py +365 -0
  70. data_profiling/model/typeset_relations.py +143 -0
  71. data_profiling/profile_report.py +573 -0
  72. data_profiling/report/__init__.py +4 -0
  73. data_profiling/report/formatters.py +346 -0
  74. data_profiling/report/presentation/__init__.py +1 -0
  75. data_profiling/report/presentation/core/__init__.py +39 -0
  76. data_profiling/report/presentation/core/alerts.py +18 -0
  77. data_profiling/report/presentation/core/collapse.py +24 -0
  78. data_profiling/report/presentation/core/container.py +50 -0
  79. data_profiling/report/presentation/core/correlation_table.py +21 -0
  80. data_profiling/report/presentation/core/dropdown.py +44 -0
  81. data_profiling/report/presentation/core/duplicate.py +16 -0
  82. data_profiling/report/presentation/core/frequency_table.py +14 -0
  83. data_profiling/report/presentation/core/frequency_table_small.py +16 -0
  84. data_profiling/report/presentation/core/html.py +14 -0
  85. data_profiling/report/presentation/core/image.py +34 -0
  86. data_profiling/report/presentation/core/item_renderer.py +17 -0
  87. data_profiling/report/presentation/core/renderable.py +42 -0
  88. data_profiling/report/presentation/core/root.py +35 -0
  89. data_profiling/report/presentation/core/sample.py +20 -0
  90. data_profiling/report/presentation/core/scores.py +32 -0
  91. data_profiling/report/presentation/core/table.py +26 -0
  92. data_profiling/report/presentation/core/toggle_button.py +14 -0
  93. data_profiling/report/presentation/core/variable.py +40 -0
  94. data_profiling/report/presentation/core/variable_info.py +36 -0
  95. data_profiling/report/presentation/flavours/__init__.py +9 -0
  96. data_profiling/report/presentation/flavours/flavour_html.py +64 -0
  97. data_profiling/report/presentation/flavours/flavour_widget.py +61 -0
  98. data_profiling/report/presentation/flavours/flavours.py +43 -0
  99. data_profiling/report/presentation/flavours/html/__init__.py +47 -0
  100. data_profiling/report/presentation/flavours/html/alerts.py +10 -0
  101. data_profiling/report/presentation/flavours/html/collapse.py +7 -0
  102. data_profiling/report/presentation/flavours/html/container.py +58 -0
  103. data_profiling/report/presentation/flavours/html/correlation_table.py +13 -0
  104. data_profiling/report/presentation/flavours/html/dropdown.py +7 -0
  105. data_profiling/report/presentation/flavours/html/duplicate.py +24 -0
  106. data_profiling/report/presentation/flavours/html/frequency_table.py +20 -0
  107. data_profiling/report/presentation/flavours/html/frequency_table_small.py +15 -0
  108. data_profiling/report/presentation/flavours/html/html.py +6 -0
  109. data_profiling/report/presentation/flavours/html/image.py +7 -0
  110. data_profiling/report/presentation/flavours/html/root.py +14 -0
  111. data_profiling/report/presentation/flavours/html/sample.py +12 -0
  112. data_profiling/report/presentation/flavours/html/scores.py +11 -0
  113. data_profiling/report/presentation/flavours/html/table.py +7 -0
  114. data_profiling/report/presentation/flavours/html/templates/alerts/alert_constant.html +1 -0
  115. data_profiling/report/presentation/flavours/html/templates/alerts/alert_constant_length.html +1 -0
  116. data_profiling/report/presentation/flavours/html/templates/alerts/alert_dirty_category.html +1 -0
  117. data_profiling/report/presentation/flavours/html/templates/alerts/alert_duplicates.html +1 -0
  118. data_profiling/report/presentation/flavours/html/templates/alerts/alert_empty.html +1 -0
  119. data_profiling/report/presentation/flavours/html/templates/alerts/alert_high_cardinality.html +1 -0
  120. data_profiling/report/presentation/flavours/html/templates/alerts/alert_high_correlation.html +4 -0
  121. data_profiling/report/presentation/flavours/html/templates/alerts/alert_imbalance.html +1 -0
  122. data_profiling/report/presentation/flavours/html/templates/alerts/alert_infinite.html +1 -0
  123. data_profiling/report/presentation/flavours/html/templates/alerts/alert_missing.html +1 -0
  124. data_profiling/report/presentation/flavours/html/templates/alerts/alert_near_duplicates.html +1 -0
  125. data_profiling/report/presentation/flavours/html/templates/alerts/alert_non_stationary.html +1 -0
  126. data_profiling/report/presentation/flavours/html/templates/alerts/alert_seasonal.html +1 -0
  127. data_profiling/report/presentation/flavours/html/templates/alerts/alert_skewed.html +1 -0
  128. data_profiling/report/presentation/flavours/html/templates/alerts/alert_truncated.html +1 -0
  129. data_profiling/report/presentation/flavours/html/templates/alerts/alert_type_date.html +1 -0
  130. data_profiling/report/presentation/flavours/html/templates/alerts/alert_uniform.html +1 -0
  131. data_profiling/report/presentation/flavours/html/templates/alerts/alert_unique.html +1 -0
  132. data_profiling/report/presentation/flavours/html/templates/alerts/alert_unsupported.html +1 -0
  133. data_profiling/report/presentation/flavours/html/templates/alerts/alert_zeros.html +1 -0
  134. data_profiling/report/presentation/flavours/html/templates/alerts.html +47 -0
  135. data_profiling/report/presentation/flavours/html/templates/collapse.html +11 -0
  136. data_profiling/report/presentation/flavours/html/templates/correlation_table.html +5 -0
  137. data_profiling/report/presentation/flavours/html/templates/diagram.html +11 -0
  138. data_profiling/report/presentation/flavours/html/templates/dropdown.html +16 -0
  139. data_profiling/report/presentation/flavours/html/templates/duplicate.html +5 -0
  140. data_profiling/report/presentation/flavours/html/templates/frequency_table.html +45 -0
  141. data_profiling/report/presentation/flavours/html/templates/frequency_table_small.html +34 -0
  142. data_profiling/report/presentation/flavours/html/templates/report.html +26 -0
  143. data_profiling/report/presentation/flavours/html/templates/sample.html +10 -0
  144. data_profiling/report/presentation/flavours/html/templates/scores.html +78 -0
  145. data_profiling/report/presentation/flavours/html/templates/sequence/batch_grid.html +16 -0
  146. data_profiling/report/presentation/flavours/html/templates/sequence/grid.html +18 -0
  147. data_profiling/report/presentation/flavours/html/templates/sequence/list.html +7 -0
  148. data_profiling/report/presentation/flavours/html/templates/sequence/named_list.html +8 -0
  149. data_profiling/report/presentation/flavours/html/templates/sequence/overview_tabs.html +30 -0
  150. data_profiling/report/presentation/flavours/html/templates/sequence/scores.html +3 -0
  151. data_profiling/report/presentation/flavours/html/templates/sequence/sections.html +13 -0
  152. data_profiling/report/presentation/flavours/html/templates/sequence/select.html +40 -0
  153. data_profiling/report/presentation/flavours/html/templates/sequence/tabs.html +30 -0
  154. data_profiling/report/presentation/flavours/html/templates/table.html +38 -0
  155. data_profiling/report/presentation/flavours/html/templates/toggle_button.html +18 -0
  156. data_profiling/report/presentation/flavours/html/templates/variable.html +7 -0
  157. data_profiling/report/presentation/flavours/html/templates/variable_info.html +49 -0
  158. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/bootstrap.bundle.min.js +7 -0
  159. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/bootstrap.min.css +6 -0
  160. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/cosmo.bootstrap.min.css +12 -0
  161. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/flatly.bootstrap.min.css +12 -0
  162. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/script.js +52 -0
  163. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/simplex.bootstrap.min.css +12 -0
  164. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/style.css +253 -0
  165. data_profiling/report/presentation/flavours/html/templates/wrapper/assets/united.bootstrap.min.css +12 -0
  166. data_profiling/report/presentation/flavours/html/templates/wrapper/footer.html +7 -0
  167. data_profiling/report/presentation/flavours/html/templates/wrapper/javascript.html +18 -0
  168. data_profiling/report/presentation/flavours/html/templates/wrapper/navigation.html +36 -0
  169. data_profiling/report/presentation/flavours/html/templates/wrapper/style.html +53 -0
  170. data_profiling/report/presentation/flavours/html/templates.py +76 -0
  171. data_profiling/report/presentation/flavours/html/toggle_button.py +7 -0
  172. data_profiling/report/presentation/flavours/html/variable.py +7 -0
  173. data_profiling/report/presentation/flavours/html/variable_info.py +7 -0
  174. data_profiling/report/presentation/flavours/widget/__init__.py +49 -0
  175. data_profiling/report/presentation/flavours/widget/alerts.py +45 -0
  176. data_profiling/report/presentation/flavours/widget/collapse.py +43 -0
  177. data_profiling/report/presentation/flavours/widget/container.py +121 -0
  178. data_profiling/report/presentation/flavours/widget/correlation_table.py +14 -0
  179. data_profiling/report/presentation/flavours/widget/dropdown.py +31 -0
  180. data_profiling/report/presentation/flavours/widget/duplicate.py +14 -0
  181. data_profiling/report/presentation/flavours/widget/frequency_table.py +57 -0
  182. data_profiling/report/presentation/flavours/widget/frequency_table_small.py +66 -0
  183. data_profiling/report/presentation/flavours/widget/html.py +11 -0
  184. data_profiling/report/presentation/flavours/widget/image.py +26 -0
  185. data_profiling/report/presentation/flavours/widget/notebook.py +81 -0
  186. data_profiling/report/presentation/flavours/widget/root.py +10 -0
  187. data_profiling/report/presentation/flavours/widget/sample.py +14 -0
  188. data_profiling/report/presentation/flavours/widget/table.py +30 -0
  189. data_profiling/report/presentation/flavours/widget/toggle_button.py +17 -0
  190. data_profiling/report/presentation/flavours/widget/variable.py +12 -0
  191. data_profiling/report/presentation/flavours/widget/variable_info.py +11 -0
  192. data_profiling/report/presentation/frequency_table_utils.py +141 -0
  193. data_profiling/report/structure/__init__.py +1 -0
  194. data_profiling/report/structure/correlations.py +123 -0
  195. data_profiling/report/structure/overview.py +376 -0
  196. data_profiling/report/structure/report.py +457 -0
  197. data_profiling/report/structure/variables/__init__.py +35 -0
  198. data_profiling/report/structure/variables/render_boolean.py +132 -0
  199. data_profiling/report/structure/variables/render_categorical.py +566 -0
  200. data_profiling/report/structure/variables/render_common.py +31 -0
  201. data_profiling/report/structure/variables/render_complex.py +102 -0
  202. data_profiling/report/structure/variables/render_count.py +172 -0
  203. data_profiling/report/structure/variables/render_date.py +143 -0
  204. data_profiling/report/structure/variables/render_file.py +70 -0
  205. data_profiling/report/structure/variables/render_generic.py +45 -0
  206. data_profiling/report/structure/variables/render_image.py +204 -0
  207. data_profiling/report/structure/variables/render_path.py +134 -0
  208. data_profiling/report/structure/variables/render_real.py +314 -0
  209. data_profiling/report/structure/variables/render_text.py +189 -0
  210. data_profiling/report/structure/variables/render_timeseries.py +371 -0
  211. data_profiling/report/structure/variables/render_url.py +132 -0
  212. data_profiling/report/utils.py +34 -0
  213. data_profiling/serialize_report.py +143 -0
  214. data_profiling/utils/__init__.py +1 -0
  215. data_profiling/utils/backend.py +9 -0
  216. data_profiling/utils/cache.py +59 -0
  217. data_profiling/utils/common.py +142 -0
  218. data_profiling/utils/compat.py +31 -0
  219. data_profiling/utils/dataframe.py +238 -0
  220. data_profiling/utils/logger.py +53 -0
  221. data_profiling/utils/notebook.py +8 -0
  222. data_profiling/utils/paths.py +45 -0
  223. data_profiling/utils/progress_bar.py +15 -0
  224. data_profiling/utils/styles.py +22 -0
  225. data_profiling/utils/versions.py +19 -0
  226. data_profiling/version.py +1 -0
  227. data_profiling/visualisation/__init__.py +1 -0
  228. data_profiling/visualisation/context.py +87 -0
  229. data_profiling/visualisation/missing.py +138 -0
  230. data_profiling/visualisation/plot.py +1158 -0
  231. data_profiling/visualisation/utils.py +113 -0
  232. fg_data_profiling-4.19.0.dist-info/METADATA +362 -0
  233. fg_data_profiling-4.19.0.dist-info/RECORD +238 -0
  234. fg_data_profiling-4.19.0.dist-info/WHEEL +6 -0
  235. fg_data_profiling-4.19.0.dist-info/entry_points.txt +3 -0
  236. fg_data_profiling-4.19.0.dist-info/licenses/LICENSE +21 -0
  237. fg_data_profiling-4.19.0.dist-info/top_level.txt +2 -0
  238. 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,9 @@
1
+ from data_profiling.report.presentation.flavours.flavours import (
2
+ HTMLReport,
3
+ WidgetReport,
4
+ )
5
+
6
+ __all__ = [
7
+ "HTMLReport",
8
+ "WidgetReport",
9
+ ]
@@ -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,7 @@
1
+ from data_profiling.report.presentation.core import Collapse
2
+ from data_profiling.report.presentation.flavours.html import templates
3
+
4
+
5
+ class HTMLCollapse(Collapse):
6
+ def render(self) -> str:
7
+ return templates.template("collapse.html").render(**self.content)
@@ -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,7 @@
1
+ from data_profiling.report.presentation.core import Dropdown
2
+ from data_profiling.report.presentation.flavours.html import templates
3
+
4
+
5
+ class HTMLDropdown(Dropdown):
6
+ def render(self) -> str:
7
+ return templates.template("dropdown.html").render(**self.content)
@@ -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,6 @@
1
+ from data_profiling.report.presentation.core import HTML
2
+
3
+
4
+ class HTMLHTML(HTML):
5
+ def render(self) -> str:
6
+ return self.content["html"]
@@ -0,0 +1,7 @@
1
+ from data_profiling.report.presentation.core import Image
2
+ from data_profiling.report.presentation.flavours.html import templates
3
+
4
+
5
+ class HTMLImage(Image):
6
+ def render(self) -> str:
7
+ return templates.template("diagram.html").render(**self.content)
@@ -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
+ )