mlrun 1.7.0rc4__py3-none-any.whl → 1.7.0rc20__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.

Potentially problematic release.


This version of mlrun might be problematic. Click here for more details.

Files changed (200) hide show
  1. mlrun/__init__.py +11 -1
  2. mlrun/__main__.py +25 -111
  3. mlrun/{datastore/helpers.py → alerts/__init__.py} +2 -5
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/api/schemas/__init__.py +4 -3
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +38 -254
  8. mlrun/artifacts/dataset.py +9 -190
  9. mlrun/artifacts/manager.py +41 -47
  10. mlrun/artifacts/model.py +30 -158
  11. mlrun/artifacts/plots.py +23 -380
  12. mlrun/common/constants.py +68 -0
  13. mlrun/common/formatters/__init__.py +19 -0
  14. mlrun/{model_monitoring/stores/models/sqlite.py → common/formatters/artifact.py} +6 -8
  15. mlrun/common/formatters/base.py +78 -0
  16. mlrun/common/formatters/function.py +41 -0
  17. mlrun/common/formatters/pipeline.py +53 -0
  18. mlrun/common/formatters/project.py +51 -0
  19. mlrun/{runtimes → common/runtimes}/constants.py +32 -4
  20. mlrun/common/schemas/__init__.py +25 -4
  21. mlrun/common/schemas/alert.py +203 -0
  22. mlrun/common/schemas/api_gateway.py +148 -0
  23. mlrun/common/schemas/artifact.py +15 -5
  24. mlrun/common/schemas/auth.py +8 -2
  25. mlrun/common/schemas/client_spec.py +2 -0
  26. mlrun/common/schemas/frontend_spec.py +1 -0
  27. mlrun/common/schemas/function.py +4 -0
  28. mlrun/common/schemas/hub.py +7 -9
  29. mlrun/common/schemas/model_monitoring/__init__.py +19 -3
  30. mlrun/common/schemas/model_monitoring/constants.py +96 -26
  31. mlrun/common/schemas/model_monitoring/grafana.py +9 -5
  32. mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
  33. mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
  34. mlrun/common/schemas/pipeline.py +0 -9
  35. mlrun/common/schemas/project.py +22 -21
  36. mlrun/common/types.py +7 -1
  37. mlrun/config.py +87 -19
  38. mlrun/data_types/data_types.py +4 -0
  39. mlrun/data_types/to_pandas.py +9 -9
  40. mlrun/datastore/__init__.py +5 -8
  41. mlrun/datastore/alibaba_oss.py +130 -0
  42. mlrun/datastore/azure_blob.py +4 -5
  43. mlrun/datastore/base.py +69 -30
  44. mlrun/datastore/datastore.py +10 -2
  45. mlrun/datastore/datastore_profile.py +90 -6
  46. mlrun/datastore/google_cloud_storage.py +1 -1
  47. mlrun/datastore/hdfs.py +5 -0
  48. mlrun/datastore/inmem.py +2 -2
  49. mlrun/datastore/redis.py +2 -2
  50. mlrun/datastore/s3.py +5 -0
  51. mlrun/datastore/snowflake_utils.py +43 -0
  52. mlrun/datastore/sources.py +172 -44
  53. mlrun/datastore/store_resources.py +7 -7
  54. mlrun/datastore/targets.py +285 -41
  55. mlrun/datastore/utils.py +68 -5
  56. mlrun/datastore/v3io.py +27 -50
  57. mlrun/db/auth_utils.py +152 -0
  58. mlrun/db/base.py +149 -14
  59. mlrun/db/factory.py +1 -1
  60. mlrun/db/httpdb.py +608 -178
  61. mlrun/db/nopdb.py +191 -7
  62. mlrun/errors.py +11 -0
  63. mlrun/execution.py +37 -20
  64. mlrun/feature_store/__init__.py +0 -2
  65. mlrun/feature_store/api.py +21 -52
  66. mlrun/feature_store/feature_set.py +48 -23
  67. mlrun/feature_store/feature_vector.py +2 -1
  68. mlrun/feature_store/ingestion.py +7 -6
  69. mlrun/feature_store/retrieval/base.py +9 -4
  70. mlrun/feature_store/retrieval/conversion.py +9 -9
  71. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  72. mlrun/feature_store/retrieval/job.py +9 -3
  73. mlrun/feature_store/retrieval/local_merger.py +2 -0
  74. mlrun/feature_store/retrieval/spark_merger.py +34 -24
  75. mlrun/feature_store/steps.py +30 -19
  76. mlrun/features.py +4 -13
  77. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
  78. mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
  79. mlrun/frameworks/lgbm/__init__.py +1 -1
  80. mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
  81. mlrun/frameworks/lgbm/model_handler.py +1 -1
  82. mlrun/frameworks/parallel_coordinates.py +2 -1
  83. mlrun/frameworks/pytorch/__init__.py +2 -2
  84. mlrun/frameworks/sklearn/__init__.py +1 -1
  85. mlrun/frameworks/tf_keras/__init__.py +5 -2
  86. mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
  87. mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
  88. mlrun/frameworks/xgboost/__init__.py +1 -1
  89. mlrun/k8s_utils.py +10 -11
  90. mlrun/launcher/__init__.py +1 -1
  91. mlrun/launcher/base.py +6 -5
  92. mlrun/launcher/client.py +8 -6
  93. mlrun/launcher/factory.py +1 -1
  94. mlrun/launcher/local.py +9 -3
  95. mlrun/launcher/remote.py +9 -3
  96. mlrun/lists.py +6 -2
  97. mlrun/model.py +58 -19
  98. mlrun/model_monitoring/__init__.py +1 -1
  99. mlrun/model_monitoring/api.py +127 -301
  100. mlrun/model_monitoring/application.py +5 -296
  101. mlrun/model_monitoring/applications/__init__.py +11 -0
  102. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  103. mlrun/model_monitoring/applications/base.py +282 -0
  104. mlrun/model_monitoring/applications/context.py +214 -0
  105. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  106. mlrun/model_monitoring/applications/histogram_data_drift.py +224 -93
  107. mlrun/model_monitoring/applications/results.py +99 -0
  108. mlrun/model_monitoring/controller.py +30 -36
  109. mlrun/model_monitoring/db/__init__.py +18 -0
  110. mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
  111. mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
  112. mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +58 -32
  113. mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
  114. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
  115. mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
  116. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
  117. mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
  118. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
  119. mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
  120. mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +302 -155
  121. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  122. mlrun/model_monitoring/db/tsdb/base.py +329 -0
  123. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  124. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  125. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  126. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  127. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
  128. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  129. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  130. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
  131. mlrun/model_monitoring/evidently_application.py +6 -118
  132. mlrun/model_monitoring/features_drift_table.py +34 -22
  133. mlrun/model_monitoring/helpers.py +100 -7
  134. mlrun/model_monitoring/model_endpoint.py +3 -2
  135. mlrun/model_monitoring/stream_processing.py +93 -228
  136. mlrun/model_monitoring/tracking_policy.py +7 -1
  137. mlrun/model_monitoring/writer.py +152 -124
  138. mlrun/package/packagers_manager.py +1 -0
  139. mlrun/package/utils/_formatter.py +2 -2
  140. mlrun/platforms/__init__.py +11 -10
  141. mlrun/platforms/iguazio.py +21 -202
  142. mlrun/projects/operations.py +30 -16
  143. mlrun/projects/pipelines.py +92 -99
  144. mlrun/projects/project.py +757 -268
  145. mlrun/render.py +15 -14
  146. mlrun/run.py +160 -162
  147. mlrun/runtimes/__init__.py +55 -3
  148. mlrun/runtimes/base.py +33 -19
  149. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  150. mlrun/runtimes/funcdoc.py +0 -28
  151. mlrun/runtimes/kubejob.py +28 -122
  152. mlrun/runtimes/local.py +5 -2
  153. mlrun/runtimes/mpijob/__init__.py +0 -20
  154. mlrun/runtimes/mpijob/abstract.py +8 -8
  155. mlrun/runtimes/mpijob/v1.py +1 -1
  156. mlrun/runtimes/nuclio/__init__.py +1 -0
  157. mlrun/runtimes/nuclio/api_gateway.py +709 -0
  158. mlrun/runtimes/nuclio/application/__init__.py +15 -0
  159. mlrun/runtimes/nuclio/application/application.py +523 -0
  160. mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
  161. mlrun/runtimes/nuclio/function.py +98 -58
  162. mlrun/runtimes/nuclio/serving.py +36 -42
  163. mlrun/runtimes/pod.py +196 -45
  164. mlrun/runtimes/remotesparkjob.py +1 -1
  165. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  166. mlrun/runtimes/utils.py +6 -73
  167. mlrun/secrets.py +6 -2
  168. mlrun/serving/remote.py +2 -3
  169. mlrun/serving/routers.py +7 -4
  170. mlrun/serving/server.py +7 -8
  171. mlrun/serving/states.py +73 -43
  172. mlrun/serving/v2_serving.py +8 -7
  173. mlrun/track/tracker.py +2 -1
  174. mlrun/utils/async_http.py +25 -5
  175. mlrun/utils/helpers.py +141 -75
  176. mlrun/utils/http.py +1 -1
  177. mlrun/utils/logger.py +39 -7
  178. mlrun/utils/notifications/notification/__init__.py +14 -9
  179. mlrun/utils/notifications/notification/base.py +12 -0
  180. mlrun/utils/notifications/notification/console.py +2 -0
  181. mlrun/utils/notifications/notification/git.py +3 -1
  182. mlrun/utils/notifications/notification/ipython.py +2 -0
  183. mlrun/utils/notifications/notification/slack.py +101 -21
  184. mlrun/utils/notifications/notification/webhook.py +11 -1
  185. mlrun/utils/notifications/notification_pusher.py +147 -16
  186. mlrun/utils/retryer.py +3 -2
  187. mlrun/utils/v3io_clients.py +0 -1
  188. mlrun/utils/version/version.json +2 -2
  189. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +33 -18
  190. mlrun-1.7.0rc20.dist-info/RECORD +353 -0
  191. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +1 -1
  192. mlrun/kfpops.py +0 -868
  193. mlrun/model_monitoring/batch.py +0 -974
  194. mlrun/model_monitoring/stores/models/__init__.py +0 -27
  195. mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -382
  196. mlrun/platforms/other.py +0 -305
  197. mlrun-1.7.0rc4.dist-info/RECORD +0 -321
  198. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
  199. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
  200. {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
@@ -12,121 +12,9 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- import uuid
16
- import warnings
17
- from typing import Union
18
-
19
- import pandas as pd
20
- import semver
21
-
22
- from mlrun.errors import MLRunIncompatibleVersionError
23
- from mlrun.model_monitoring.application import ModelMonitoringApplicationBase
24
-
25
- SUPPORTED_EVIDENTLY_VERSION = semver.Version.parse("0.4.11")
26
-
27
-
28
- def _check_evidently_version(*, cur: semver.Version, ref: semver.Version) -> None:
29
- if ref.is_compatible(cur) or (
30
- cur.major == ref.major == 0 and cur.minor == ref.minor and cur.patch > ref.patch
31
- ):
32
- return
33
- if cur.major == ref.major == 0 and cur.minor > ref.minor:
34
- warnings.warn(
35
- f"Evidently version {cur} is not compatible with the tested "
36
- f"version {ref}, use at your own risk."
37
- )
38
- else:
39
- raise MLRunIncompatibleVersionError(
40
- f"Evidently version {cur} is not supported, please change to "
41
- f"{ref} (or another compatible version)."
42
- )
43
-
44
-
45
- _HAS_EVIDENTLY = False
46
- try:
47
- import evidently # noqa: F401
48
-
49
- _check_evidently_version(
50
- cur=semver.Version.parse(evidently.__version__),
51
- ref=SUPPORTED_EVIDENTLY_VERSION,
52
- )
53
- _HAS_EVIDENTLY = True
54
- except ModuleNotFoundError:
55
- pass
56
-
57
-
58
- if _HAS_EVIDENTLY:
59
- from evidently.renderers.notebook_utils import determine_template
60
- from evidently.report.report import Report
61
- from evidently.suite.base_suite import Suite
62
- from evidently.ui.type_aliases import STR_UUID
63
- from evidently.ui.workspace import Workspace
64
- from evidently.utils.dashboard import TemplateParams
65
-
66
-
67
- class EvidentlyModelMonitoringApplicationBase(ModelMonitoringApplicationBase):
68
- def __init__(
69
- self, evidently_workspace_path: str, evidently_project_id: "STR_UUID"
70
- ) -> None:
71
- """
72
- A class for integrating Evidently for mlrun model monitoring within a monitoring application.
73
- Note: evidently is not installed by default in the mlrun/mlrun image.
74
- It must be installed separately to use this class.
75
-
76
- :param evidently_workspace_path: (str) The path to the Evidently workspace.
77
- :param evidently_project_id: (str) The ID of the Evidently project.
78
-
79
- """
80
- if not _HAS_EVIDENTLY:
81
- raise ModuleNotFoundError("Evidently is not installed - the app cannot run")
82
- self.evidently_workspace = Workspace.create(evidently_workspace_path)
83
- self.evidently_project_id = evidently_project_id
84
- self.evidently_project = self.evidently_workspace.get_project(
85
- evidently_project_id
86
- )
87
-
88
- def log_evidently_object(
89
- self, evidently_object: Union["Report", "Suite"], artifact_name: str
90
- ):
91
- """
92
- Logs an Evidently report or suite as an artifact.
93
-
94
- :param evidently_object: (Union[Report, Suite]) The Evidently report or suite object.
95
- :param artifact_name: (str) The name for the logged artifact.
96
- """
97
- evidently_object_html = evidently_object.get_html()
98
- self.context.log_artifact(
99
- artifact_name, body=evidently_object_html.encode("utf-8"), format="html"
100
- )
101
-
102
- def log_project_dashboard(
103
- self,
104
- timestamp_start: pd.Timestamp,
105
- timestamp_end: pd.Timestamp,
106
- artifact_name: str = "dashboard",
107
- ):
108
- """
109
- Logs an Evidently project dashboard.
110
-
111
- :param timestamp_start: (pd.Timestamp) The start timestamp for the dashboard data.
112
- :param timestamp_end: (pd.Timestamp) The end timestamp for the dashboard data.
113
- :param artifact_name: (str) The name for the logged artifact.
114
- """
115
-
116
- dashboard_info = self.evidently_project.build_dashboard_info(
117
- timestamp_start, timestamp_end
118
- )
119
- template_params = TemplateParams(
120
- dashboard_id="pd_" + str(uuid.uuid4()).replace("-", ""),
121
- dashboard_info=dashboard_info,
122
- additional_graphs={},
123
- )
124
-
125
- dashboard_html = self._render(determine_template("inline"), template_params)
126
- self.context.log_artifact(
127
- artifact_name, body=dashboard_html.encode("utf-8"), format="html"
128
- )
129
-
130
- @staticmethod
131
- def _render(temple_func, template_params: "TemplateParams"):
132
- return temple_func(params=template_params)
15
+ # TODO : delete this file in 1.9.0
16
+ from mlrun.model_monitoring.applications import ( # noqa: F401
17
+ _HAS_EVIDENTLY,
18
+ SUPPORTED_EVIDENTLY_VERSION,
19
+ EvidentlyModelMonitoringApplicationBase,
20
+ )
@@ -21,9 +21,34 @@ import plotly.graph_objects as go
21
21
  from plotly.subplots import make_subplots
22
22
 
23
23
  import mlrun.common.schemas.model_monitoring
24
+ from mlrun.artifacts import PlotlyArtifact
24
25
 
25
26
  # A type for representing a drift result, a tuple of the status and the drift mean:
26
- DriftResultType = tuple[mlrun.common.schemas.model_monitoring.DriftStatus, float]
27
+ DriftResultType = tuple[
28
+ mlrun.common.schemas.model_monitoring.constants.ResultStatusApp, float
29
+ ]
30
+
31
+
32
+ class _PlotlyTableArtifact(PlotlyArtifact):
33
+ """A custom class for plotly table artifacts"""
34
+
35
+ @staticmethod
36
+ def _disable_table_dragging(figure_html: str) -> str:
37
+ """
38
+ Disable the table columns dragging by adding the following
39
+ JavaScript code
40
+ """
41
+ start, end = figure_html.rsplit(";", 1)
42
+ middle = (
43
+ ';for (const element of document.getElementsByClassName("table")) '
44
+ '{element.style.pointerEvents = "none";}'
45
+ )
46
+ figure_html = start + middle + end
47
+ return figure_html
48
+
49
+ def get_body(self) -> str:
50
+ """Get the adjusted HTML representation of the figure"""
51
+ return self._disable_table_dragging(super().get_body())
27
52
 
28
53
 
29
54
  class FeaturesDriftTablePlot:
@@ -62,9 +87,9 @@ class FeaturesDriftTablePlot:
62
87
 
63
88
  # Status configurations:
64
89
  _STATUS_COLORS = {
65
- mlrun.common.schemas.model_monitoring.DriftStatus.NO_DRIFT: "rgb(0,176,80)", # Green
66
- mlrun.common.schemas.model_monitoring.DriftStatus.POSSIBLE_DRIFT: "rgb(255,192,0)", # Orange
67
- mlrun.common.schemas.model_monitoring.DriftStatus.DRIFT_DETECTED: "rgb(208,0,106)", # Magenta
90
+ mlrun.common.schemas.model_monitoring.constants.ResultStatusApp.no_detection: "rgb(0,176,80)", # Green
91
+ mlrun.common.schemas.model_monitoring.constants.ResultStatusApp.potential_detection: "rgb(255,192,0)", # Orange
92
+ mlrun.common.schemas.model_monitoring.constants.ResultStatusApp.detected: "rgb(208,0,106)", # Magenta
68
93
  }
69
94
 
70
95
  # Font configurations:
@@ -97,7 +122,7 @@ class FeaturesDriftTablePlot:
97
122
  inputs_statistics: dict,
98
123
  metrics: dict[str, Union[dict, float]],
99
124
  drift_results: dict[str, DriftResultType],
100
- ) -> str:
125
+ ) -> _PlotlyTableArtifact:
101
126
  """
102
127
  Produce the html code of the table plot with the given information and the stored configurations in the class.
103
128
 
@@ -106,9 +131,8 @@ class FeaturesDriftTablePlot:
106
131
  :param metrics: The drift detection metrics calculated on the sample set and inputs.
107
132
  :param drift_results: The drift results per feature according to the rules of the monitor.
108
133
 
109
- :return: The full path to the html file of the plot.
134
+ :return: The drift table as a plotly artifact.
110
135
  """
111
- # Plot the drift table:
112
136
  figure = self._plot(
113
137
  features=list(inputs_statistics.keys()),
114
138
  sample_set_statistics=sample_set_statistics,
@@ -116,19 +140,7 @@ class FeaturesDriftTablePlot:
116
140
  metrics=metrics,
117
141
  drift_results=drift_results,
118
142
  )
119
-
120
- # Get its HTML representation:
121
- figure_html = figure.to_html()
122
-
123
- # Turn off the table columns dragging by injecting the following JavaScript code:
124
- start, end = figure_html.rsplit(";", 1)
125
- middle = (
126
- ';for (const element of document.getElementsByClassName("table")) '
127
- '{element.style.pointerEvents = "none";}'
128
- )
129
- figure_html = start + middle + end
130
-
131
- return figure_html
143
+ return _PlotlyTableArtifact(figure=figure, key="drift_table_plot")
132
144
 
133
145
  def _read_columns_names(self, statistics_dictionary: dict, drift_metrics: dict):
134
146
  """
@@ -366,10 +378,10 @@ class FeaturesDriftTablePlot:
366
378
  bins = np.array(bins)
367
379
  if bins[0] == -sys.float_info.max:
368
380
  bins[0] = bins[1] - (bins[2] - bins[1])
369
- hovertext[0] = f"(-∞, {bins[1]})"
381
+ hovertext[0] = f"(-inf, {bins[1]})"
370
382
  if bins[-1] == sys.float_info.max:
371
383
  bins[-1] = bins[-2] + (bins[-2] - bins[-3])
372
- hovertext[-1] = f"({bins[-2]}, )"
384
+ hovertext[-1] = f"({bins[-2]}, inf)"
373
385
  # Center the bins (leave the first one):
374
386
  bins = 0.5 * (bins[:-1] + bins[1:])
375
387
  # Plot the histogram as a line with filled background below it:
@@ -15,12 +15,19 @@
15
15
  import datetime
16
16
  import typing
17
17
 
18
+ import numpy as np
19
+ import pandas as pd
20
+
18
21
  import mlrun
19
22
  import mlrun.common.model_monitoring.helpers
20
23
  import mlrun.common.schemas
21
24
  from mlrun.common.schemas.model_monitoring import (
22
25
  EventFieldType,
23
26
  )
27
+ from mlrun.common.schemas.model_monitoring.model_endpoints import (
28
+ ModelEndpointMonitoringMetricType,
29
+ _compose_full_name,
30
+ )
24
31
  from mlrun.model_monitoring.model_endpoint import ModelEndpoint
25
32
  from mlrun.utils import logger
26
33
 
@@ -36,14 +43,10 @@ class _BatchDict(typing.TypedDict):
36
43
  days: int
37
44
 
38
45
 
39
- class _MLRunNoRunsFoundError(Exception):
40
- pass
41
-
42
-
43
46
  def get_stream_path(
44
47
  project: str = None,
45
48
  function_name: str = mm_constants.MonitoringFunctionNames.STREAM,
46
- ):
49
+ ) -> str:
47
50
  """
48
51
  Get stream path from the project secret. If wasn't set, take it from the system configurations
49
52
 
@@ -55,8 +58,6 @@ def get_stream_path(
55
58
 
56
59
  stream_uri = mlrun.get_secret_or_env(
57
60
  mlrun.common.schemas.model_monitoring.ProjectSecretKeys.STREAM_PATH
58
- if function_name is mm_constants.MonitoringFunctionNames.STREAM
59
- else ""
60
61
  ) or mlrun.mlconf.get_model_monitoring_file_target_path(
61
62
  project=project,
62
63
  kind=mlrun.common.schemas.model_monitoring.FileTargetKind.STREAM,
@@ -64,6 +65,8 @@ def get_stream_path(
64
65
  function_name=function_name,
65
66
  )
66
67
 
68
+ if isinstance(stream_uri, list): # ML-6043 - user side gets only the new stream uri
69
+ stream_uri = stream_uri[1] # get new stream path, under projects
67
70
  return mlrun.common.model_monitoring.helpers.parse_monitoring_stream_path(
68
71
  stream_uri=stream_uri, project=project, function_name=function_name
69
72
  )
@@ -112,6 +115,24 @@ def get_connection_string(secret_provider: typing.Callable = None) -> str:
112
115
  )
113
116
 
114
117
 
118
+ def get_tsdb_connection_string(
119
+ secret_provider: typing.Optional[typing.Callable] = None,
120
+ ) -> str:
121
+ """Get TSDB connection string from the project secret. If wasn't set, take it from the system
122
+ configurations.
123
+ :param secret_provider: An optional secret provider to get the connection string secret.
124
+ :return: Valid TSDB connection string.
125
+ """
126
+
127
+ return (
128
+ mlrun.get_secret_or_env(
129
+ key=mlrun.common.schemas.model_monitoring.ProjectSecretKeys.TSDB_CONNECTION,
130
+ secret_provider=secret_provider,
131
+ )
132
+ or mlrun.mlconf.model_endpoint_monitoring.tsdb_connection
133
+ )
134
+
135
+
115
136
  def batch_dict2timedelta(batch_dict: _BatchDict) -> datetime.timedelta:
116
137
  """
117
138
  Convert a batch dictionary to timedelta.
@@ -212,3 +233,75 @@ def update_model_endpoint_last_request(
212
233
  endpoint_id=model_endpoint.metadata.uid,
213
234
  attributes={EventFieldType.LAST_REQUEST: bumped_last_request},
214
235
  )
236
+
237
+
238
+ def calculate_inputs_statistics(
239
+ sample_set_statistics: dict, inputs: pd.DataFrame
240
+ ) -> mlrun.common.model_monitoring.helpers.FeatureStats:
241
+ """
242
+ Calculate the inputs data statistics for drift monitoring purpose.
243
+
244
+ :param sample_set_statistics: The sample set (stored end point's dataset to reference) statistics. The bins of the
245
+ histograms of each feature will be used to recalculate the histograms of the inputs.
246
+ :param inputs: The inputs to calculate their statistics and later on - the drift with respect to the
247
+ sample set.
248
+
249
+ :returns: The calculated statistics of the inputs data.
250
+ """
251
+
252
+ # Use `DFDataInfer` to calculate the statistics over the inputs:
253
+ inputs_statistics = mlrun.data_types.infer.DFDataInfer.get_stats(
254
+ df=inputs,
255
+ options=mlrun.data_types.infer.InferOptions.Histogram,
256
+ )
257
+
258
+ # Recalculate the histograms over the bins that are set in the sample-set of the end point:
259
+ for feature in inputs_statistics.keys():
260
+ if feature in sample_set_statistics:
261
+ counts, bins = np.histogram(
262
+ inputs[feature].to_numpy(),
263
+ bins=sample_set_statistics[feature]["hist"][1],
264
+ )
265
+ inputs_statistics[feature]["hist"] = [
266
+ counts.tolist(),
267
+ bins.tolist(),
268
+ ]
269
+ elif "hist" in inputs_statistics[feature]:
270
+ # Comply with the other common features' histogram length
271
+ mlrun.common.model_monitoring.helpers.pad_hist(
272
+ mlrun.common.model_monitoring.helpers.Histogram(
273
+ inputs_statistics[feature]["hist"]
274
+ )
275
+ )
276
+
277
+ return inputs_statistics
278
+
279
+
280
+ def get_endpoint_record(project: str, endpoint_id: str):
281
+ model_endpoint_store = mlrun.model_monitoring.get_store_object(
282
+ project=project,
283
+ )
284
+ return model_endpoint_store.get_model_endpoint(endpoint_id=endpoint_id)
285
+
286
+
287
+ def get_result_instance_fqn(
288
+ model_endpoint_id: str, app_name: str, result_name: str
289
+ ) -> str:
290
+ return f"{model_endpoint_id}.{app_name}.result.{result_name}"
291
+
292
+
293
+ def get_default_result_instance_fqn(model_endpoint_id: str) -> str:
294
+ return get_result_instance_fqn(
295
+ model_endpoint_id,
296
+ mm_constants.HistogramDataDriftApplicationConstants.NAME,
297
+ mm_constants.HistogramDataDriftApplicationConstants.GENERAL_RESULT_NAME,
298
+ )
299
+
300
+
301
+ def get_invocations_fqn(project: str) -> str:
302
+ return _compose_full_name(
303
+ project=project,
304
+ app=mm_constants.SpecialApps.MLRUN_INFRA,
305
+ name=mm_constants.PredictionsQueryConstants.INVOCATIONS,
306
+ type=ModelEndpointMonitoringMetricType.METRIC,
307
+ )
@@ -17,6 +17,7 @@ from dataclasses import dataclass, field
17
17
  from typing import Any
18
18
 
19
19
  import mlrun.model
20
+ from mlrun.common.model_monitoring.helpers import FeatureStats
20
21
  from mlrun.common.schemas.model_monitoring.constants import (
21
22
  EndpointType,
22
23
  EventKeyMetrics,
@@ -42,8 +43,8 @@ class ModelEndpointSpec(mlrun.model.ModelObj):
42
43
 
43
44
  @dataclass
44
45
  class ModelEndpointStatus(mlrun.model.ModelObj):
45
- feature_stats: dict = field(default_factory=dict)
46
- current_stats: dict = field(default_factory=dict)
46
+ feature_stats: FeatureStats = field(default_factory=dict)
47
+ current_stats: FeatureStats = field(default_factory=dict)
47
48
  first_request: str = ""
48
49
  last_request: str = ""
49
50
  error_count: int = 0