Skip to content

Commit e5eceef

Browse files
authored
Move to Report Creator (#786)
2 parents cb2d870 + 5d970af commit e5eceef

34 files changed

+575
-483
lines changed

THIRD_PARTY_LICENSES.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ asteval
1818
* Source code: https://github.com/newville/asteval
1919
* Project home: https://github.com/newville/asteval
2020

21+
autots
22+
* Copyright (c) 2024 Colin Catlin
23+
* License: MIT License
24+
* Source code: https://github.com/winedarksea/AutoTS
25+
* Project home: https://winedarksea.github.io/AutoTS/build/html/index.html
26+
2127
bokeh
2228
* Copyright Copyright (c) 2012 - 2021, Anaconda, Inc., and Bokeh Contributors
2329
* License: BSD 3-Clause "New" or "Revised" License
@@ -169,6 +175,12 @@ nbformat
169175
* Source code: https://github.com/jupyter/nbconvert
170176
* Project home: https://jupyter.org/
171177

178+
neuralprophet
179+
* Copyright (c) 2020 Oskar Triebe
180+
* License: MIT License
181+
* Source Code: https://github.com/ourownstory/neural_prophet
182+
* Project Home: https://neuralprophet.com
183+
172184
numpy
173185
* Copyright (c) 2005-2021, NumPy Developers.
174186
* License: BSD 3-Clause "New" or "Revised" License
@@ -247,6 +259,18 @@ plotly
247259
* Source code: https://github.com/plotly/plotly.py
248260
* Project home: https://plotly.com/
249261

262+
pmdarima
263+
* Copyright (c) 2017 Taylor G Smith
264+
* License: MIT License
265+
* Source code: https://github.com/alkaline-ml/pmdarima
266+
* Project home: https://alkaline-ml.com/pmdarima/
267+
268+
prophet
269+
* Copyright (c) Facebook, Inc. and its affiliates.
270+
* License: MIT License
271+
* Source code: https://github.com/facebook/prophet
272+
* Project home: https://facebook.github.io/prophet/
273+
250274
protobuf
251275
* Copyright 2008 Google Inc. All rights reserved.
252276
* License: Google Protobuf License
@@ -289,6 +313,12 @@ PyYAML
289313
* Source code: https://github.com/yaml/pyyaml/
290314
* Project home: https://pyyaml.org/
291315

316+
report-creator
317+
* Copyright 2024 Daren Race
318+
* License: MIT License
319+
* Source code: https://github.com/darenr/report_creator
320+
* Project home: https://darenr.github.io/report_creator/
321+
292322
requests
293323
* Copyright 2023 Kenneth Reitz
294324
* License: Apache-2.0 license

ads/llm/serializers/runnable_parallel.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*--
3+
4+
# Copyright (c) 2024 Oracle and/or its affiliates.
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
6+
17
from langchain.schema.runnable import RunnableParallel
28
from langchain.load.dump import dumpd
39
from langchain.load.load import load
@@ -10,7 +16,7 @@ def type():
1016

1117
@staticmethod
1218
def load(config: dict, **kwargs):
13-
steps = config["kwargs"]["steps"]
19+
steps = config.get("kwargs", dict()).get("steps", dict())
1420
steps = {k: load(v, **kwargs) for k, v in steps.items()}
1521
return RunnableParallel(**steps)
1622

ads/opctl/operator/lowcode/anomaly/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ All generated configurations should be ready to use without the need for any add
3535
To run anomaly detection locally, create and activate a new conda environment (`ads-anomaly`). Install all the required libraries listed in the `environment.yaml` file.
3636

3737
```yaml
38-
- datapane
38+
- report-creator
3939
- cerberus
4040
- oracle-automlx==23.4.1
4141
- oracle-automlx[classic]==23.4.1

ads/opctl/operator/lowcode/anomaly/environment.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ dependencies:
55
- python=3.8
66
- pip
77
- pip:
8-
- datapane
8+
- report-creator
99
- cerberus
1010
- oracle-automlx==23.4.1
1111
- oracle-automlx[classic]==23.4.1

ads/opctl/operator/lowcode/anomaly/model/automlx.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*--
33

4-
# Copyright (c) 2023 Oracle and/or its affiliates.
4+
# Copyright (c) 2023, 2024 Oracle and/or its affiliates.
55
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
66

77
import pandas as pd
@@ -27,8 +27,13 @@ class AutoMLXOperatorModel(AnomalyOperatorBaseModel):
2727
def _build_model(self) -> pd.DataFrame:
2828
from automlx import init
2929
import logging
30+
3031
try:
31-
init(engine="ray", engine_opts={"ray_setup": {"_temp_dir": "/tmp/ray-temp"}}, loglevel=logging.CRITICAL)
32+
init(
33+
engine="ray",
34+
engine_opts={"ray_setup": {"_temp_dir": "/tmp/ray-temp"}},
35+
loglevel=logging.CRITICAL,
36+
)
3237
except Exception as e:
3338
logger.info("Ray already initialized")
3439
date_column = self.spec.datetime_column.name
@@ -68,21 +73,21 @@ def _build_model(self) -> pd.DataFrame:
6873
return anomaly_output
6974

7075
def _generate_report(self):
71-
import datapane as dp
76+
import report_creator as rc
7277

7378
"""The method that needs to be implemented on the particular model level."""
74-
selected_models_text = dp.Text(
75-
f"## Selected Models Overview \n "
76-
"The following tables provide information regarding the chosen model."
77-
)
78-
all_sections = [selected_models_text]
79+
other_sections = [
80+
rc.Heading("Selected Models Overview", level=2),
81+
rc.Text(
82+
"The following tables provide information regarding the chosen model."
83+
),
84+
]
7985

80-
model_description = dp.Text(
86+
model_description = rc.Text(
8187
"The automlx model automatically pre-processes, selects and engineers "
8288
"high-quality features in your dataset, which then given to an automatically "
8389
"chosen and optimized machine learning model.."
8490
)
85-
other_sections = all_sections
8691

8792
return (
8893
model_description,

ads/opctl/operator/lowcode/anomaly/model/autots.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*--
33

4-
# Copyright (c) 2023 Oracle and/or its affiliates.
4+
# Copyright (c) 2023, 2024 Oracle and/or its affiliates.
55
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
66

77
import pandas as pd
@@ -81,21 +81,20 @@ def _build_model(self) -> AnomalyOutput:
8181
return anomaly_output
8282

8383
def _generate_report(self):
84-
import datapane as dp
84+
import report_creator as rc
8585

8686
"""The method that needs to be implemented on the particular model level."""
87-
selected_models_text = dp.Text(
88-
f"## Selected Models Overview \n "
89-
"The following tables provide information regarding the chosen model."
90-
)
91-
all_sections = [selected_models_text]
92-
93-
model_description = dp.Text(
87+
other_sections = [
88+
rc.Heading("Selected Models Overview", level=2),
89+
rc.Text(
90+
"The following tables provide information regarding the chosen model."
91+
),
92+
]
93+
model_description = rc.Text(
9494
"The automlx model automatically pre-processes, selects and engineers "
9595
"high-quality features in your dataset, which then given to an automatically "
9696
"chosen and optimized machine learning model.."
9797
)
98-
other_sections = all_sections
9998

10099
return (
101100
model_description,

ads/opctl/operator/lowcode/anomaly/model/base_model.py

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# -*- coding: utf-8 -*--
33

4-
# Copyright (c) 2023 Oracle and/or its affiliates.
4+
# Copyright (c) 2023, 2024 Oracle and/or its affiliates.
55
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
66

77
import os
@@ -57,7 +57,7 @@ def __init__(self, config: AnomalyOperatorConfig, datasets: AnomalyDatasets):
5757

5858
def generate_report(self):
5959
"""Generates the report."""
60-
import datapane as dp
60+
import report_creator as rc
6161
import matplotlib.pyplot as plt
6262

6363
start_time = time.time()
@@ -79,12 +79,10 @@ def generate_report(self):
7979
anomaly_output, test_data, elapsed_time
8080
)
8181
table_blocks = [
82-
dp.DataTable(df, label=col)
82+
rc.DataTable(df, label=col, index=True)
8383
for col, df in self.datasets.full_data_dict.items()
8484
]
85-
data_table = (
86-
dp.Select(blocks=table_blocks) if len(table_blocks) > 1 else table_blocks[0]
87-
)
85+
data_table = rc.Select(blocks=table_blocks)
8886
date_column = self.spec.datetime_column.name
8987

9088
blocks = []
@@ -106,44 +104,42 @@ def generate_report(self):
106104
plt.xlabel(date_column)
107105
plt.ylabel(col)
108106
plt.title(f"`{col}` with reference to anomalies")
109-
figure_blocks.append(ax)
110-
blocks.append(dp.Group(blocks=figure_blocks, label=target))
111-
plots = dp.Select(blocks=blocks) if len(blocks) > 1 else blocks[0]
107+
figure_blocks.append(rc.Widget(ax))
108+
blocks.append(rc.Group(*figure_blocks, label=target))
109+
plots = rc.Select(blocks)
112110

113111
report_sections = []
114-
title_text = dp.Text("# Anomaly Detection Report")
115-
116-
yaml_appendix_title = dp.Text(f"## Reference: YAML File")
117-
yaml_appendix = dp.Code(code=self.config.to_yaml(), language="yaml")
118-
summary = dp.Blocks(
119-
blocks=[
120-
dp.Group(
121-
dp.Text(f"You selected the **`{self.spec.model}`** model."),
122-
dp.Text(
123-
"Based on your dataset, you could have also selected "
124-
f"any of the models: `{'`, `'.join(SupportedModels.keys())}`."
125-
),
126-
dp.BigNumber(
127-
heading="Analysis was completed in ",
128-
value=human_time_friendly(elapsed_time),
129-
),
130-
label="Summary",
131-
)
132-
]
112+
title_text = rc.Heading("Anomaly Detection Report", level=1)
113+
114+
yaml_appendix_title = rc.Heading("Reference: YAML File", level=2)
115+
yaml_appendix = rc.Yaml(self.config.to_dict())
116+
summary = rc.Block(
117+
rc.Group(
118+
rc.Text(f"You selected the **`{self.spec.model}`** model."),
119+
rc.Text(
120+
"Based on your dataset, you could have also selected "
121+
f"any of the models: `{'`, `'.join(SupportedModels.keys())}`."
122+
),
123+
rc.Metric(
124+
heading="Analysis was completed in ",
125+
value=human_time_friendly(elapsed_time),
126+
),
127+
label="Summary",
128+
)
133129
)
134-
sec_text = dp.Text(f"## Train Evaluation Metrics")
135-
sec = dp.DataTable(self._evaluation_metrics(anomaly_output))
130+
sec_text = rc.Heading("Train Evaluation Metrics", level=2)
131+
sec = rc.DataTable(self._evaluation_metrics(anomaly_output), index=True)
136132
evaluation_metrics_sec = [sec_text, sec]
137133

138134
test_metrics_sections = []
139135
if total_metrics is not None and not total_metrics.empty:
140-
sec_text = dp.Text(f"## Test Data Evaluation Metrics")
141-
sec = dp.DataTable(total_metrics)
136+
sec_text = rc.Heading("Test Data Evaluation Metrics", level=2)
137+
sec = rc.DataTable(total_metrics, index=True)
142138
test_metrics_sections = test_metrics_sections + [sec_text, sec]
143139

144140
if summary_metrics is not None and not summary_metrics.empty:
145-
sec_text = dp.Text(f"## Test Data Summary Metrics")
146-
sec = dp.DataTable(summary_metrics)
141+
sec_text = rc.Heading("Test Data Summary Metrics", level=2)
142+
sec = rc.DataTable(summary_metrics, index=True)
147143
test_metrics_sections = test_metrics_sections + [sec_text, sec]
148144

149145
report_sections = (
@@ -248,7 +244,7 @@ def _save_report(
248244
test_metrics: pd.DataFrame,
249245
):
250246
"""Saves resulting reports to the given folder."""
251-
import datapane as dp
247+
import report_creator as rc
252248

253249
unique_output_dir = find_output_dirname(self.spec.output_directory)
254250

@@ -257,11 +253,12 @@ def _save_report(
257253
else:
258254
storage_options = dict()
259255

260-
# datapane html report
256+
# report-creator html report
261257
with tempfile.TemporaryDirectory() as temp_dir:
262258
report_local_path = os.path.join(temp_dir, "___report.html")
263259
disable_print()
264-
dp.save_report(report_sections, report_local_path)
260+
with rc.ReportCreator("My Report") as report:
261+
report.save(rc.Block(*report_sections), report_local_path)
265262
enable_print()
266263
with open(report_local_path) as f1:
267264
with fsspec.open(

ads/opctl/operator/lowcode/anomaly/model/tods.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# #!/usr/bin/env python
22
# # -*- coding: utf-8 -*--
33

4-
# # Copyright (c) 2023 Oracle and/or its affiliates.
4+
# # Copyright (c) 2023, 2024 Oracle and/or its affiliates.
55
# # Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
66

77
# import importlib
@@ -97,16 +97,16 @@
9797
# return anomaly_output
9898

9999
# def _generate_report(self):
100-
# import datapane as dp
100+
# import report_creator as rc
101101

102102
# """The method that needs to be implemented on the particular model level."""
103-
# selected_models_text = dp.Text(
103+
# selected_models_text = rc.Text(
104104
# f"## Selected Models Overview \n "
105105
# "The following tables provide information regarding the chosen model."
106106
# )
107107
# all_sections = [selected_models_text]
108108

109-
# model_description = dp.Text(
109+
# model_description = rc.Text(
110110
# "The tods model is a full-stack automated machine learning system for outlier detection "
111111
# "on univariate / multivariate time-series data. It provides exhaustive modules for building "
112112
# "machine learning-based outlier detection systems and wide range of algorithms."

ads/opctl/operator/lowcode/anomaly/schema.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ spec:
323323
missing_value_imputation:
324324
type: boolean
325325
required: false
326-
default: true
326+
default: false
327327

328328
generate_report:
329329
type: boolean

ads/opctl/operator/lowcode/forecast/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ To run forecasting locally, create and activate a new conda environment (`ads-fo
3535
- neuralprophet
3636
- pmdarima
3737
- statsmodels
38-
- datapane
38+
- report-creator
3939
- cerberus
4040
- sktime
4141
- optuna==3.1.0

0 commit comments

Comments
 (0)