diff --git a/source/incqueryserver-jupyter/iqs_jupyter/analysis_extensions.py b/source/incqueryserver-jupyter/iqs_jupyter/analysis_extensions.py
index a55a1c2..0dbc669 100644
--- a/source/incqueryserver-jupyter/iqs_jupyter/analysis_extensions.py
+++ b/source/incqueryserver-jupyter/iqs_jupyter/analysis_extensions.py
@@ -18,29 +18,37 @@
'''
import html
+import json
+from typing import Union
import iqs_client
+import iqs_jupyter.config_defaults as defaults
+import iqs_jupyter.tool_extension_point as ext_point
+from IPython.core.display import display
+from ipywidgets import widgets
+from iqs_client import AnalysisConfigurationIdentifier, AnalysisApi
+from iqs_jupyter import IQSClient
+from iqs_jupyter.core_extensions import validation_color_scale
from iqs_jupyter.helpers import cell_to_html as _cell_to_html
from iqs_jupyter.helpers import dict_to_element as _dict_to_element
-from iqs_jupyter.core_extensions import validation_color_scale
-def _monkey_patch_analysis_results_repr_html(self : iqs_client.AnalysisResults):
+def _monkey_patch_analysis_results_repr_html(self: iqs_client.AnalysisResults):
escaped_id = html.escape(self.configuration.configuration_id)
header_report = '''
Results for model analysis "{}"
Analysis configuration id: {} (see hover for details)
'''.format(
html.escape(self.configuration.configuration_name),
- html.escape(self.to_str()),
+ html.escape(self.to_str()),
escaped_id
)
-
+
kpi_rows = "\n".join([
"{} | {} |
".format(
- html.escape(kpi.name),
+ html.escape(kpi.name),
html.escape(str(kpi.value))
- )
+ )
for kpi in self.kpi_values
])
kpi_report = '''
@@ -59,15 +67,15 @@ def _monkey_patch_analysis_results_repr_html(self : iqs_client.AnalysisResults):
'''.format(
kpi_rows
)
-
+
toc_rows = "\n".join([
'''
{} by rule "{}"
'''.format(
_marker_count_report(self.analysis_results[result_index]),
- #escaped_id, str(result_index),
+ # escaped_id, str(result_index),
html.escape(self.analysis_results[result_index].configuration_rule.name)
- )
+ )
for result_index in range(len(self.analysis_results))
])
toc_report = '''
@@ -79,7 +87,6 @@ def _monkey_patch_analysis_results_repr_html(self : iqs_client.AnalysisResults):
toc_rows
)
-
individual_result_tables = "\n".join([
'''
@@ -87,10 +94,10 @@ def _monkey_patch_analysis_results_repr_html(self : iqs_client.AnalysisResults):
'''.format(
self.analysis_results[result_index]._repr_html_("h4")
- )
+ )
for result_index in range(len(self.analysis_results))
])
-
+
style = ""
return '''
{}
@@ -103,7 +110,7 @@ def _monkey_patch_analysis_results_repr_html(self : iqs_client.AnalysisResults):
'''.format(header_report, style, kpi_report, toc_report, individual_result_tables)
-def _marker_count_report(analysis_result : iqs_client.AnalysisResult) -> str:
+def _marker_count_report(analysis_result: iqs_client.AnalysisResult) -> str:
marker_color = validation_color_scale.get(analysis_result.configuration_rule.severity.lower(), None)
marker_style_string = 'style="background-color:{}; color: bisque;"'.format(marker_color) if marker_color else ""
return '{} {} marker{}'.format(
@@ -113,12 +120,14 @@ def _marker_count_report(analysis_result : iqs_client.AnalysisResult) -> str:
"s" if 1 != len(analysis_result.matches) else ""
)
-def _monkey_patch_analysis_result_repr_html(self : iqs_client.AnalysisResult, heading_lvl: str = 'h4', anchor : str = None):
+
+def _monkey_patch_analysis_result_repr_html(self: iqs_client.AnalysisResult, heading_lvl: str = 'h4',
+ anchor: str = None):
anchor_tag = ''.format(anchor) if anchor else ""
anchor_href = '# '.format(anchor) if anchor else ""
subheader_report = '{}{} via "{}" (see hover for details)'.format(
anchor_href,
- html.escape(self.to_str()),
+ html.escape(self.to_str()),
_marker_count_report(self),
html.escape(self.configuration_rule.query_fqn)
)
@@ -135,21 +144,21 @@ def _monkey_patch_analysis_result_repr_html(self : iqs_client.AnalysisResult, he
)
if not self.matches:
return header_report
-
+
# we can assume at least one match
pattern_params = [
argument_value.parameter
- for argument_value in self.matches[0].matching_elements
+ for argument_value in self.matches[0].matching_elements
]
-
+
param_headers = " ".join(["{} | ".format(html.escape(param)) for param in pattern_params])
match_rows = "\n".join([
"{} | {} | {}
\n".format(row_index, self.matches[row_index].message, " ".join([
- " {} | ".format(_cell_to_html(_dict_to_element(argument_value.value)))
+ " {} | ".format(_cell_to_html(_dict_to_element(argument_value.value)))
for argument_value in self.matches[row_index].matching_elements
])) for row_index in range(len(self.matches))
])
-
+
style = ""
return '''
{}
@@ -171,9 +180,61 @@ def _monkey_patch_analysis_result_repr_html(self : iqs_client.AnalysisResult, he
'''.format(header_report, style, param_headers, match_rows)
+class ConfigSelector:
+
+ def __init__(
+ self,
+ iqs: IQSClient,
+ initial_config: Union[AnalysisConfigurationIdentifier, str] = defaults.default_auto_display,
+ auto_display=defaults.default_auto_display):
+ self.dropdown = widgets.Dropdown(description='')
+ self.box = widgets.HBox([widgets.Label(value="Configuration"), self.dropdown])
+ config_list = iqs.analysis.list_model_analysis_configurations()
+ configs = config_list.model_analysis_configuration_identifiers
+ options = [("---- Select model analysis configuration", None)]
+ for config in configs:
+ additional = (f"{config.configuration_name} (ID: {config.configuration_id})", config)
+ options.append(additional)
+ self.dropdown.options = options
+ if initial_config:
+ if isinstance(initial_config, str):
+ for config in configs:
+ if config.configuration_id == initial_config:
+ self.dropdown.value = config
+ elif isinstance(initial_config, AnalysisConfigurationIdentifier):
+ self.dropdown.value = initial_config
+ if auto_display:
+ display(self.box)
+
+ def value(self) -> AnalysisConfigurationIdentifier:
+ return self.dropdown.value
+
+ def _repr_html_(self):
+ display(self.box)
+
+
+def _get_analysis_configuration_selector_widget(
+ self: ext_point.IQSJupyterTools,
+ initial_config: Union[AnalysisConfigurationIdentifier, str] = None,
+ auto_display=True):
+ return ConfigSelector(self._iqs, initial_config, auto_display)
+
+
+def _register_or_update_configuration(self: AnalysisApi, path: str):
+ with open(path, "r") as file:
+ conf = json.load(file)
+ on_server = self.list_model_analysis_configurations().model_analysis_configuration_identifiers
+ for old in on_server:
+ if old.configuration_name == conf["name"]:
+ self.delete_model_analysis_configuration(analysis_configuration_identifier=old)
+ self.register_model_analysis_configuration(analysis_configuration=conf)
+
def _do_monkey_patching():
iqs_client.AnalysisResults._repr_html_ = _monkey_patch_analysis_results_repr_html
iqs_client.AnalysisResult._repr_html_ = _monkey_patch_analysis_result_repr_html
+ ext_point.IQSJupyterTools.analysis_configuration_selector_widget = _get_analysis_configuration_selector_widget
+ AnalysisApi.register_or_update_model_analysis_configuration = _register_or_update_configuration
+
_do_monkey_patching()
diff --git a/source/incqueryserver-jupyter/iqs_jupyter/config_defaults.py b/source/incqueryserver-jupyter/iqs_jupyter/config_defaults.py
index 9c15c3e..9912bfb 100644
--- a/source/incqueryserver-jupyter/iqs_jupyter/config_defaults.py
+++ b/source/incqueryserver-jupyter/iqs_jupyter/config_defaults.py
@@ -24,6 +24,9 @@
default_use_oidc: bool = False
default_use_password: bool = True
+default_analysis_config = None
+default_model_viewer_address = None
+
default_IQS_address : str = None
default_IQS_username : str = None
default_IQS_password : str = None