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,376 @@
1
+ from datetime import datetime
2
+ from typing import Any, List
3
+ from urllib.parse import quote
4
+
5
+ from data_profiling.config import Settings
6
+ from data_profiling.model import BaseDescription
7
+ from data_profiling.model.alerts import AlertType
8
+ from data_profiling.model.description import TimeIndexAnalysis
9
+ from data_profiling.report.formatters import (
10
+ fmt,
11
+ fmt_bytesize,
12
+ fmt_number,
13
+ fmt_numeric,
14
+ fmt_percent,
15
+ fmt_timespan,
16
+ fmt_timespan_timedelta,
17
+ list_args,
18
+ )
19
+ from data_profiling.report.presentation.core import Alerts, Container
20
+ from data_profiling.report.presentation.core import Image as ImageWidget
21
+ from data_profiling.report.presentation.core import Table
22
+ from data_profiling.report.presentation.core.renderable import Renderable
23
+ from data_profiling.visualisation.plot import plot_overview_timeseries
24
+
25
+
26
+ def get_dataset_overview(config: Settings, summary: BaseDescription) -> Renderable:
27
+ table_metrics = [
28
+ {
29
+ "name": "Number of variables",
30
+ "value": fmt_number(summary.table["n_var"]),
31
+ },
32
+ {
33
+ "name": "Number of observations",
34
+ "value": fmt_number(summary.table["n"]),
35
+ },
36
+ {
37
+ "name": "Missing cells",
38
+ "value": fmt_number(summary.table["n_cells_missing"]),
39
+ },
40
+ {
41
+ "name": "Missing cells (%)",
42
+ "value": fmt_percent(summary.table["p_cells_missing"]),
43
+ },
44
+ ]
45
+ if "n_duplicates" in summary.table:
46
+ table_metrics.extend(
47
+ [
48
+ {
49
+ "name": "Duplicate rows",
50
+ "value": fmt_number(summary.table["n_duplicates"]),
51
+ },
52
+ {
53
+ "name": "Duplicate rows (%)",
54
+ "value": fmt_percent(summary.table["p_duplicates"]),
55
+ },
56
+ ]
57
+ )
58
+ if "memory_size" in summary.table:
59
+ table_metrics.extend(
60
+ [
61
+ {
62
+ "name": "Total size in memory",
63
+ "value": fmt_bytesize(summary.table["memory_size"]),
64
+ },
65
+ {
66
+ "name": "Average record size in memory",
67
+ "value": fmt_bytesize(summary.table["record_size"]),
68
+ },
69
+ ]
70
+ )
71
+
72
+ dataset_info = Table(
73
+ table_metrics, name="Dataset statistics", style=config.html.style
74
+ )
75
+
76
+ dataset_types = Table(
77
+ [
78
+ {
79
+ "name": str(type_name),
80
+ "value": fmt_numeric(count, precision=config.report.precision),
81
+ }
82
+ for type_name, count in summary.table["types"].items()
83
+ ],
84
+ name="Variable types",
85
+ style=config.html.style,
86
+ )
87
+
88
+ return Container(
89
+ [dataset_info, dataset_types],
90
+ anchor_id="dataset_overview",
91
+ name="Overview",
92
+ sequence_type="grid",
93
+ )
94
+
95
+
96
+ def get_dataset_schema(config: Settings, metadata: dict) -> Container:
97
+ about_dataset = []
98
+ for key in ["description", "creator", "author"]:
99
+ if key in metadata and len(metadata[key]) > 0:
100
+ about_dataset.append(
101
+ {"name": key.capitalize(), "value": fmt(metadata[key])}
102
+ )
103
+
104
+ if "url" in metadata:
105
+ about_dataset.append(
106
+ {
107
+ "name": "URL",
108
+ "value": f'<a href="{metadata["url"]}">{metadata["url"]}</a>',
109
+ }
110
+ )
111
+
112
+ if "copyright_holder" in metadata and len(metadata["copyright_holder"]) > 0:
113
+ if "copyright_year" not in metadata:
114
+ about_dataset.append(
115
+ {
116
+ "name": "Copyright",
117
+ "value": fmt(f"(c) {metadata['copyright_holder']}"),
118
+ }
119
+ )
120
+ else:
121
+ about_dataset.append(
122
+ {
123
+ "name": "Copyright",
124
+ "value": fmt(
125
+ f"(c) {metadata['copyright_holder']} {metadata['copyright_year']}"
126
+ ),
127
+ }
128
+ )
129
+
130
+ return Container(
131
+ [
132
+ Table(
133
+ about_dataset,
134
+ name="Dataset",
135
+ anchor_id="metadata_dataset",
136
+ style=config.html.style,
137
+ )
138
+ ],
139
+ name="Dataset",
140
+ anchor_id="dataset",
141
+ sequence_type="grid",
142
+ )
143
+
144
+
145
+ def get_dataset_reproduction(config: Settings, summary: BaseDescription) -> Renderable:
146
+ """Dataset reproduction part of the report
147
+
148
+ Args:
149
+ config: settings object
150
+ summary: the dataset summary.
151
+
152
+ Returns:
153
+ A renderable object
154
+ """
155
+
156
+ version = summary.package["data_profiling_version"]
157
+ config_file = summary.package["data_profiling_config"]
158
+ date_start = summary.analysis.date_start
159
+ date_end = summary.analysis.date_end
160
+ duration = summary.analysis.duration
161
+
162
+ @list_args
163
+ def fmt_version(version: str) -> str:
164
+ return f'<a href="https://github.com/Data-Centric-AI-Community/data-profiling">data-profiling v{version}</a>'
165
+
166
+ @list_args
167
+ def fmt_config(config: str) -> str:
168
+ return f'<a download="config.json" href="data:text/plain;charset=utf-8,{quote(config)}">config.json</a>'
169
+
170
+ reproduction_table = Table(
171
+ [
172
+ {"name": "Analysis started", "value": fmt(date_start)},
173
+ {"name": "Analysis finished", "value": fmt(date_end)},
174
+ {"name": "Duration", "value": fmt_timespan(duration)},
175
+ {"name": "Software version", "value": fmt_version(version)},
176
+ {"name": "Download configuration", "value": fmt_config(config_file)},
177
+ ],
178
+ name="Reproduction",
179
+ anchor_id="overview_reproduction",
180
+ style=config.html.style,
181
+ )
182
+
183
+ return Container(
184
+ [reproduction_table],
185
+ name="Reproduction",
186
+ anchor_id="reproduction",
187
+ sequence_type="grid",
188
+ )
189
+
190
+
191
+ def get_dataset_column_definitions(config: Settings, definitions: dict) -> Container:
192
+ """Generate an overview section for the variable description
193
+
194
+ Args:
195
+ config: settings object
196
+ definitions: the variable descriptions.
197
+
198
+ Returns:
199
+ A container object
200
+ """
201
+
202
+ variable_descriptions = [
203
+ Table(
204
+ [
205
+ {"name": column, "value": fmt(value)}
206
+ for column, value in definitions.items()
207
+ ],
208
+ name="Variable descriptions",
209
+ anchor_id="variable_definition_table",
210
+ style=config.html.style,
211
+ )
212
+ ]
213
+
214
+ return Container(
215
+ variable_descriptions,
216
+ name="Variables",
217
+ anchor_id="variable_descriptions",
218
+ sequence_type="grid",
219
+ )
220
+
221
+
222
+ def get_dataset_alerts(config: Settings, alerts: list) -> Alerts:
223
+ """Obtain the alerts for the report
224
+
225
+ Args:
226
+ config: settings object
227
+ alerts: list of alerts
228
+
229
+ Returns:
230
+ Alerts renderable object
231
+ """
232
+ # add up alerts from multiple reports
233
+ if isinstance(alerts, tuple):
234
+ count = 0
235
+
236
+ # Initialize
237
+ combined_alerts = {
238
+ f"{alert.alert_type}_{alert.column_name}": [
239
+ None for _ in range(len(alerts))
240
+ ]
241
+ for report_alerts in alerts
242
+ for alert in report_alerts
243
+ }
244
+
245
+ for report_idx, report_alerts in enumerate(alerts):
246
+ for alert in report_alerts:
247
+ combined_alerts[f"{alert.alert_type}_{alert.column_name}"][
248
+ report_idx
249
+ ] = alert
250
+
251
+ count += len(
252
+ [
253
+ alert
254
+ for alert in report_alerts
255
+ if alert.alert_type != AlertType.REJECTED
256
+ ]
257
+ )
258
+
259
+ return Alerts(
260
+ alerts=combined_alerts,
261
+ name=f"Alerts ({count})",
262
+ anchor_id="alerts",
263
+ style=config.html.style,
264
+ )
265
+
266
+ count = len([alert for alert in alerts if alert.alert_type != AlertType.REJECTED])
267
+ return Alerts(
268
+ alerts=alerts,
269
+ name=f"Alerts ({count})",
270
+ anchor_id="alerts",
271
+ style=config.html.style,
272
+ )
273
+
274
+
275
+ def get_timeseries_items(config: Settings, summary: BaseDescription) -> Container:
276
+ @list_args
277
+ def fmt_tsindex_limit(limit: Any) -> str:
278
+ if isinstance(limit, datetime):
279
+ return limit.strftime("%Y-%m-%d %H:%M:%S")
280
+ else:
281
+ return fmt_number(limit)
282
+
283
+ assert isinstance(summary.time_index_analysis, TimeIndexAnalysis)
284
+ table_stats = [
285
+ {
286
+ "name": "Number of series",
287
+ "value": fmt_number(summary.time_index_analysis.n_series),
288
+ },
289
+ {
290
+ "name": "Time series length",
291
+ "value": fmt_number(summary.time_index_analysis.length),
292
+ },
293
+ {
294
+ "name": "Starting point",
295
+ "value": fmt_tsindex_limit(summary.time_index_analysis.start),
296
+ },
297
+ {
298
+ "name": "Ending point",
299
+ "value": fmt_tsindex_limit(summary.time_index_analysis.end),
300
+ },
301
+ {
302
+ "name": "Period",
303
+ "value": fmt_timespan_timedelta(summary.time_index_analysis.period),
304
+ },
305
+ ]
306
+
307
+ ts_info = Table(table_stats, name="Timeseries statistics", style=config.html.style)
308
+
309
+ dpi_bak = config.plot.dpi
310
+ config.plot.dpi = 300
311
+ timeseries = ImageWidget(
312
+ plot_overview_timeseries(config, summary.variables),
313
+ image_format=config.plot.image_format,
314
+ alt="ts_plot",
315
+ name="Original",
316
+ anchor_id="ts_plot_overview",
317
+ )
318
+ timeseries_scaled = ImageWidget(
319
+ plot_overview_timeseries(config, summary.variables, scale=True),
320
+ image_format=config.plot.image_format,
321
+ alt="ts_plot_scaled",
322
+ name="Scaled",
323
+ anchor_id="ts_plot_scaled_overview",
324
+ )
325
+ config.plot.dpi = dpi_bak
326
+ ts_tab = Container(
327
+ [timeseries, timeseries_scaled],
328
+ anchor_id="ts_plot_overview",
329
+ name="",
330
+ sequence_type="tabs",
331
+ )
332
+
333
+ return Container(
334
+ [ts_info, ts_tab],
335
+ anchor_id="timeseries_overview",
336
+ name="Time Series",
337
+ sequence_type="grid",
338
+ )
339
+
340
+
341
+ def get_dataset_items(config: Settings, summary: BaseDescription, alerts: list) -> list:
342
+ """Returns the dataset overview (at the top of the report)
343
+
344
+ Args:
345
+ config: settings object
346
+ summary: the calculated summary
347
+ alerts: the alerts
348
+
349
+ Returns:
350
+ A list with components for the dataset overview (overview, reproduction, alerts)
351
+ """
352
+
353
+ items: List[Renderable] = [get_dataset_overview(config, summary)]
354
+
355
+ metadata = {key: config.dataset.dict()[key] for key in config.dataset.dict().keys()}
356
+
357
+ if len(metadata) > 0 and any(len(value) > 0 for value in metadata.values()):
358
+ items.append(get_dataset_schema(config, metadata))
359
+
360
+ column_details = {
361
+ key: config.variables.descriptions[key]
362
+ for key in config.variables.descriptions.keys()
363
+ }
364
+
365
+ if len(column_details) > 0:
366
+ items.append(get_dataset_column_definitions(config, column_details))
367
+
368
+ if summary.time_index_analysis:
369
+ items.append(get_timeseries_items(config, summary))
370
+
371
+ if alerts:
372
+ items.append(get_dataset_alerts(config, alerts))
373
+
374
+ items.append(get_dataset_reproduction(config, summary))
375
+
376
+ return items