mlrun 1.7.0rc14__py3-none-any.whl → 1.7.0rc22__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 (160) hide show
  1. mlrun/__init__.py +10 -1
  2. mlrun/__main__.py +23 -111
  3. mlrun/alerts/__init__.py +15 -0
  4. mlrun/alerts/alert.py +169 -0
  5. mlrun/api/schemas/__init__.py +4 -3
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +36 -253
  8. mlrun/artifacts/dataset.py +9 -190
  9. mlrun/artifacts/manager.py +46 -42
  10. mlrun/artifacts/model.py +9 -141
  11. mlrun/artifacts/plots.py +14 -375
  12. mlrun/common/constants.py +65 -3
  13. mlrun/common/formatters/__init__.py +19 -0
  14. mlrun/{runtimes/mpijob/v1alpha1.py → common/formatters/artifact.py} +6 -14
  15. mlrun/common/formatters/base.py +113 -0
  16. mlrun/common/formatters/function.py +46 -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 +10 -5
  21. mlrun/common/schemas/alert.py +92 -11
  22. mlrun/common/schemas/api_gateway.py +56 -0
  23. mlrun/common/schemas/artifact.py +15 -5
  24. mlrun/common/schemas/auth.py +2 -0
  25. mlrun/common/schemas/client_spec.py +1 -0
  26. mlrun/common/schemas/frontend_spec.py +1 -0
  27. mlrun/common/schemas/function.py +4 -0
  28. mlrun/common/schemas/model_monitoring/__init__.py +15 -3
  29. mlrun/common/schemas/model_monitoring/constants.py +58 -7
  30. mlrun/common/schemas/model_monitoring/grafana.py +9 -5
  31. mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
  32. mlrun/common/schemas/pipeline.py +0 -9
  33. mlrun/common/schemas/project.py +5 -11
  34. mlrun/common/types.py +1 -0
  35. mlrun/config.py +30 -9
  36. mlrun/data_types/to_pandas.py +9 -9
  37. mlrun/datastore/base.py +41 -9
  38. mlrun/datastore/datastore.py +6 -2
  39. mlrun/datastore/datastore_profile.py +56 -4
  40. mlrun/datastore/inmem.py +2 -2
  41. mlrun/datastore/redis.py +2 -2
  42. mlrun/datastore/s3.py +5 -0
  43. mlrun/datastore/sources.py +147 -7
  44. mlrun/datastore/store_resources.py +7 -7
  45. mlrun/datastore/targets.py +110 -42
  46. mlrun/datastore/utils.py +42 -0
  47. mlrun/db/base.py +54 -10
  48. mlrun/db/httpdb.py +282 -79
  49. mlrun/db/nopdb.py +52 -10
  50. mlrun/errors.py +11 -0
  51. mlrun/execution.py +26 -9
  52. mlrun/feature_store/__init__.py +0 -2
  53. mlrun/feature_store/api.py +12 -47
  54. mlrun/feature_store/feature_set.py +9 -0
  55. mlrun/feature_store/feature_vector.py +8 -0
  56. mlrun/feature_store/ingestion.py +7 -6
  57. mlrun/feature_store/retrieval/base.py +9 -4
  58. mlrun/feature_store/retrieval/conversion.py +9 -9
  59. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  60. mlrun/feature_store/retrieval/job.py +9 -3
  61. mlrun/feature_store/retrieval/local_merger.py +2 -0
  62. mlrun/feature_store/retrieval/spark_merger.py +16 -0
  63. mlrun/frameworks/__init__.py +6 -0
  64. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
  65. mlrun/frameworks/parallel_coordinates.py +2 -1
  66. mlrun/frameworks/tf_keras/__init__.py +4 -1
  67. mlrun/k8s_utils.py +10 -11
  68. mlrun/launcher/base.py +4 -3
  69. mlrun/launcher/client.py +5 -3
  70. mlrun/launcher/local.py +12 -2
  71. mlrun/launcher/remote.py +9 -2
  72. mlrun/lists.py +6 -2
  73. mlrun/model.py +47 -21
  74. mlrun/model_monitoring/__init__.py +1 -1
  75. mlrun/model_monitoring/api.py +42 -18
  76. mlrun/model_monitoring/application.py +5 -305
  77. mlrun/model_monitoring/applications/__init__.py +11 -0
  78. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  79. mlrun/model_monitoring/applications/base.py +280 -0
  80. mlrun/model_monitoring/applications/context.py +214 -0
  81. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  82. mlrun/model_monitoring/applications/histogram_data_drift.py +132 -91
  83. mlrun/model_monitoring/applications/results.py +99 -0
  84. mlrun/model_monitoring/controller.py +3 -1
  85. mlrun/model_monitoring/db/__init__.py +2 -0
  86. mlrun/model_monitoring/db/stores/__init__.py +0 -2
  87. mlrun/model_monitoring/db/stores/base/store.py +22 -37
  88. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +43 -21
  89. mlrun/model_monitoring/db/stores/sqldb/models/base.py +39 -8
  90. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +27 -7
  91. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +5 -0
  92. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +246 -224
  93. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +232 -216
  94. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  95. mlrun/model_monitoring/db/tsdb/base.py +316 -0
  96. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  97. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  98. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  99. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  100. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +401 -0
  101. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  102. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  103. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +658 -0
  104. mlrun/model_monitoring/evidently_application.py +6 -118
  105. mlrun/model_monitoring/helpers.py +63 -1
  106. mlrun/model_monitoring/model_endpoint.py +3 -2
  107. mlrun/model_monitoring/stream_processing.py +57 -216
  108. mlrun/model_monitoring/writer.py +134 -124
  109. mlrun/package/__init__.py +13 -1
  110. mlrun/package/packagers/__init__.py +6 -1
  111. mlrun/package/utils/_formatter.py +2 -2
  112. mlrun/platforms/__init__.py +10 -9
  113. mlrun/platforms/iguazio.py +21 -202
  114. mlrun/projects/operations.py +24 -12
  115. mlrun/projects/pipelines.py +79 -102
  116. mlrun/projects/project.py +271 -103
  117. mlrun/render.py +15 -14
  118. mlrun/run.py +16 -46
  119. mlrun/runtimes/__init__.py +6 -3
  120. mlrun/runtimes/base.py +14 -7
  121. mlrun/runtimes/daskjob.py +1 -0
  122. mlrun/runtimes/databricks_job/databricks_runtime.py +1 -0
  123. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  124. mlrun/runtimes/funcdoc.py +0 -28
  125. mlrun/runtimes/kubejob.py +2 -1
  126. mlrun/runtimes/local.py +12 -3
  127. mlrun/runtimes/mpijob/__init__.py +0 -20
  128. mlrun/runtimes/mpijob/v1.py +1 -1
  129. mlrun/runtimes/nuclio/api_gateway.py +194 -84
  130. mlrun/runtimes/nuclio/application/application.py +170 -8
  131. mlrun/runtimes/nuclio/function.py +39 -49
  132. mlrun/runtimes/pod.py +16 -36
  133. mlrun/runtimes/remotesparkjob.py +9 -3
  134. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  135. mlrun/runtimes/utils.py +6 -45
  136. mlrun/serving/__init__.py +8 -1
  137. mlrun/serving/server.py +2 -1
  138. mlrun/serving/states.py +51 -8
  139. mlrun/serving/utils.py +19 -11
  140. mlrun/serving/v2_serving.py +5 -1
  141. mlrun/track/tracker.py +2 -1
  142. mlrun/utils/async_http.py +25 -5
  143. mlrun/utils/helpers.py +157 -83
  144. mlrun/utils/logger.py +39 -7
  145. mlrun/utils/notifications/notification/__init__.py +14 -9
  146. mlrun/utils/notifications/notification/base.py +1 -1
  147. mlrun/utils/notifications/notification/slack.py +34 -7
  148. mlrun/utils/notifications/notification/webhook.py +1 -1
  149. mlrun/utils/notifications/notification_pusher.py +147 -16
  150. mlrun/utils/regex.py +9 -0
  151. mlrun/utils/v3io_clients.py +0 -1
  152. mlrun/utils/version/version.json +2 -2
  153. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/METADATA +14 -6
  154. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/RECORD +158 -138
  155. mlrun/kfpops.py +0 -865
  156. mlrun/platforms/other.py +0 -305
  157. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/LICENSE +0 -0
  158. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/WHEEL +0 -0
  159. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/entry_points.txt +0 -0
  160. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/top_level.txt +0 -0
mlrun/projects/project.py CHANGED
@@ -31,23 +31,29 @@ from typing import Callable, Optional, Union
31
31
  import dotenv
32
32
  import git
33
33
  import git.exc
34
- import kfp
34
+ import mlrun_pipelines.common.models
35
+ import mlrun_pipelines.mounts
35
36
  import nuclio.utils
36
37
  import requests
37
38
  import yaml
39
+ from mlrun_pipelines.models import PipelineNodeWrapper
38
40
 
39
41
  import mlrun.common.helpers
42
+ import mlrun.common.runtimes.constants
43
+ import mlrun.common.schemas.artifact
40
44
  import mlrun.common.schemas.model_monitoring.constants as mm_constants
41
45
  import mlrun.db
42
46
  import mlrun.errors
43
47
  import mlrun.k8s_utils
48
+ import mlrun.model_monitoring.applications as mm_app
44
49
  import mlrun.runtimes
45
50
  import mlrun.runtimes.nuclio.api_gateway
46
51
  import mlrun.runtimes.pod
47
52
  import mlrun.runtimes.utils
48
53
  import mlrun.serving
49
54
  import mlrun.utils.regex
50
- from mlrun.common.schemas import AlertConfig
55
+ from mlrun.alerts.alert import AlertConfig
56
+ from mlrun.common.schemas.alert import AlertTemplate
51
57
  from mlrun.datastore.datastore_profile import DatastoreProfile, DatastoreProfile2Json
52
58
  from mlrun.runtimes.nuclio.function import RemoteRuntime
53
59
 
@@ -56,14 +62,10 @@ from ..artifacts.manager import ArtifactManager, dict_to_artifact, extend_artifa
56
62
  from ..datastore import store_manager
57
63
  from ..features import Feature
58
64
  from ..model import EntrypointParam, ImageBuilder, ModelObj
59
- from ..model_monitoring.application import (
60
- ModelMonitoringApplicationBase,
61
- )
62
65
  from ..run import code_to_function, get_object, import_function, new_function
63
66
  from ..secrets import SecretsStore
64
67
  from ..utils import (
65
68
  is_ipython,
66
- is_legacy_artifact,
67
69
  is_relative_path,
68
70
  is_yaml_path,
69
71
  logger,
@@ -76,7 +78,10 @@ from ..utils.clones import (
76
78
  clone_zip,
77
79
  get_repo_url,
78
80
  )
79
- from ..utils.helpers import ensure_git_branch, resolve_git_reference_from_source
81
+ from ..utils.helpers import (
82
+ ensure_git_branch,
83
+ resolve_git_reference_from_source,
84
+ )
80
85
  from ..utils.notifications import CustomNotificationPusher, NotificationTypes
81
86
  from .operations import (
82
87
  BuildStatus,
@@ -991,13 +996,9 @@ class ProjectSpec(ModelObj):
991
996
  if not isinstance(artifact, dict) and not hasattr(artifact, "to_dict"):
992
997
  raise ValueError("artifacts must be a dict or class")
993
998
  if isinstance(artifact, dict):
994
- # Support legacy artifacts
995
- if is_legacy_artifact(artifact) or _is_imported_artifact(artifact):
996
- key = artifact.get("key")
997
- else:
998
- key = artifact.get("metadata").get("key", "")
999
+ key = artifact.get("metadata", {}).get("key", "")
999
1000
  if not key:
1000
- raise ValueError('artifacts "key" must be specified')
1001
+ raise ValueError('artifacts "metadata.key" must be specified')
1001
1002
  else:
1002
1003
  key = artifact.key
1003
1004
  artifact = artifact.to_dict()
@@ -1274,6 +1275,14 @@ class MlrunProject(ModelObj):
1274
1275
  def description(self, description):
1275
1276
  self.spec.description = description
1276
1277
 
1278
+ @property
1279
+ def default_function_node_selector(self) -> dict:
1280
+ return self.spec.default_function_node_selector
1281
+
1282
+ @default_function_node_selector.setter
1283
+ def default_function_node_selector(self, default_function_node_selector):
1284
+ self.spec.default_function_node_selector = default_function_node_selector
1285
+
1277
1286
  @property
1278
1287
  def default_image(self) -> str:
1279
1288
  return self.spec.default_image
@@ -1593,6 +1602,23 @@ class MlrunProject(ModelObj):
1593
1602
  )
1594
1603
  return item
1595
1604
 
1605
+ def delete_artifact(
1606
+ self,
1607
+ item: Artifact,
1608
+ deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
1609
+ mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
1610
+ ),
1611
+ secrets: dict = None,
1612
+ ):
1613
+ """Delete an artifact object in the DB and optionally delete the artifact data
1614
+
1615
+ :param item: Artifact object (can be any type, such as dataset, model, feature store).
1616
+ :param deletion_strategy: The artifact deletion strategy types.
1617
+ :param secrets: Credentials needed to access the artifact data.
1618
+ """
1619
+ am = self._get_artifact_manager()
1620
+ am.delete_artifact(item, deletion_strategy, secrets)
1621
+
1596
1622
  def log_dataset(
1597
1623
  self,
1598
1624
  key,
@@ -1885,7 +1911,11 @@ class MlrunProject(ModelObj):
1885
1911
  def set_model_monitoring_function(
1886
1912
  self,
1887
1913
  func: typing.Union[str, mlrun.runtimes.BaseRuntime, None] = None,
1888
- application_class: typing.Union[str, ModelMonitoringApplicationBase] = None,
1914
+ application_class: typing.Union[
1915
+ str,
1916
+ mm_app.ModelMonitoringApplicationBase,
1917
+ mm_app.ModelMonitoringApplicationBaseV2,
1918
+ ] = None,
1889
1919
  name: str = None,
1890
1920
  image: str = None,
1891
1921
  handler=None,
@@ -1901,6 +1931,7 @@ class MlrunProject(ModelObj):
1901
1931
  call `fn.deploy()` where `fn` is the object returned by this method.
1902
1932
 
1903
1933
  examples::
1934
+
1904
1935
  project.set_model_monitoring_function(
1905
1936
  name="myApp", application_class="MyApp", image="mlrun/mlrun"
1906
1937
  )
@@ -1923,11 +1954,6 @@ class MlrunProject(ModelObj):
1923
1954
  monitoring application's constructor.
1924
1955
  """
1925
1956
 
1926
- if name in mm_constants.MonitoringFunctionNames.list():
1927
- raise mlrun.errors.MLRunInvalidArgumentError(
1928
- f"An application cannot have the following names: "
1929
- f"{mm_constants.MonitoringFunctionNames.list()}"
1930
- )
1931
1957
  function_object: RemoteRuntime = None
1932
1958
  (
1933
1959
  resolved_function_name,
@@ -1953,7 +1979,11 @@ class MlrunProject(ModelObj):
1953
1979
  def create_model_monitoring_function(
1954
1980
  self,
1955
1981
  func: str = None,
1956
- application_class: typing.Union[str, ModelMonitoringApplicationBase] = None,
1982
+ application_class: typing.Union[
1983
+ str,
1984
+ mm_app.ModelMonitoringApplicationBase,
1985
+ mm_app.ModelMonitoringApplicationBaseV2,
1986
+ ] = None,
1957
1987
  name: str = None,
1958
1988
  image: str = None,
1959
1989
  handler: str = None,
@@ -1967,6 +1997,7 @@ class MlrunProject(ModelObj):
1967
1997
  Create a monitoring function object without setting it to the project
1968
1998
 
1969
1999
  examples::
2000
+
1970
2001
  project.create_model_monitoring_function(
1971
2002
  application_class_name="MyApp", image="mlrun/mlrun", name="myApp"
1972
2003
  )
@@ -1988,6 +2019,7 @@ class MlrunProject(ModelObj):
1988
2019
  :param application_kwargs: Additional keyword arguments to be passed to the
1989
2020
  monitoring application's constructor.
1990
2021
  """
2022
+
1991
2023
  _, function_object, _ = self._instantiate_model_monitoring_function(
1992
2024
  func,
1993
2025
  application_class,
@@ -2006,7 +2038,10 @@ class MlrunProject(ModelObj):
2006
2038
  self,
2007
2039
  func: typing.Union[str, mlrun.runtimes.BaseRuntime, None] = None,
2008
2040
  application_class: typing.Union[
2009
- str, ModelMonitoringApplicationBase, None
2041
+ str,
2042
+ mm_app.ModelMonitoringApplicationBase,
2043
+ mm_app.ModelMonitoringApplicationBaseV2,
2044
+ None,
2010
2045
  ] = None,
2011
2046
  name: typing.Optional[str] = None,
2012
2047
  image: typing.Optional[str] = None,
@@ -2180,23 +2215,67 @@ class MlrunProject(ModelObj):
2180
2215
  )
2181
2216
 
2182
2217
  def disable_model_monitoring(
2183
- self, *, delete_histogram_data_drift_app: bool = True
2218
+ self,
2219
+ *,
2220
+ delete_resources: bool = True,
2221
+ delete_stream_function: bool = False,
2222
+ delete_histogram_data_drift_app: bool = True,
2223
+ delete_user_applications: bool = False,
2224
+ user_application_list: list[str] = None,
2184
2225
  ) -> None:
2185
2226
  """
2186
- Note: This method is currently not advised for use. See ML-3432.
2187
- Disable model monitoring by deleting the underlying functions infrastructure from MLRun database.
2188
-
2189
- :param delete_histogram_data_drift_app: Whether to delete the histogram data drift app.
2227
+ Disable model monitoring application controller, writer, stream, histogram data drift application
2228
+ and the user's applications functions, according to the given params.
2229
+
2230
+ :param delete_resources: If True, it would delete the model monitoring controller & writer
2231
+ functions. Default True
2232
+ :param delete_stream_function: If True, it would delete model monitoring stream function,
2233
+ need to use wisely because if you're deleting this function
2234
+ this can cause data loss in case you will want to
2235
+ enable the model monitoring capability to the project.
2236
+ Default False.
2237
+ :param delete_histogram_data_drift_app: If True, it would delete the default histogram-based data drift
2238
+ application. Default False.
2239
+ :param delete_user_applications: If True, it would delete the user's model monitoring
2240
+ application according to user_application_list, Default False.
2241
+ :param user_application_list: List of the user's model monitoring application to disable.
2242
+ Default all the applications.
2243
+ Note: you have to set delete_user_applications to True
2244
+ in order to delete the desired application.
2190
2245
  """
2191
- db = mlrun.db.get_run_db(secrets=self._secrets)
2192
- for fn_name in mm_constants.MonitoringFunctionNames.list():
2193
- db.delete_function(project=self.name, name=fn_name)
2194
- if delete_histogram_data_drift_app:
2195
- db.delete_function(
2196
- project=self.name,
2197
- name=mm_constants.HistogramDataDriftApplicationConstants.NAME,
2246
+ if not delete_user_applications and user_application_list:
2247
+ raise mlrun.errors.MLRunInvalidArgumentError(
2248
+ "user_application_list can be specified only if delete_user_applications is set to True"
2198
2249
  )
2199
2250
 
2251
+ db = mlrun.db.get_run_db(secrets=self._secrets)
2252
+ succeed = db.disable_model_monitoring(
2253
+ project=self.name,
2254
+ delete_resources=delete_resources,
2255
+ delete_stream_function=delete_stream_function,
2256
+ delete_histogram_data_drift_app=delete_histogram_data_drift_app,
2257
+ delete_user_applications=delete_user_applications,
2258
+ user_application_list=user_application_list,
2259
+ )
2260
+ if succeed and delete_resources:
2261
+ if delete_resources:
2262
+ logger.info("Model Monitoring disabled", project=self.name)
2263
+ if delete_user_applications:
2264
+ logger.info(
2265
+ "All the desired monitoring application were deleted",
2266
+ project=self.name,
2267
+ )
2268
+ else:
2269
+ if delete_resources:
2270
+ logger.info(
2271
+ "Model Monitoring was not disabled properly", project=self.name
2272
+ )
2273
+ if delete_user_applications:
2274
+ logger.info(
2275
+ "Some of the desired monitoring application were not deleted",
2276
+ project=self.name,
2277
+ )
2278
+
2200
2279
  def set_function(
2201
2280
  self,
2202
2281
  func: typing.Union[str, mlrun.runtimes.BaseRuntime] = None,
@@ -2391,22 +2470,47 @@ class MlrunProject(ModelObj):
2391
2470
  """
2392
2471
  self.spec.remove_function(name)
2393
2472
 
2394
- def remove_model_monitoring_function(self, name):
2395
- """remove the specified model-monitoring-app function from the project and from the db
2473
+ def remove_model_monitoring_function(self, name: Union[str, list[str]]):
2474
+ """remove the specified model-monitoring-app function/s from the project spec
2396
2475
 
2397
- :param name: name of the model-monitoring-app function (under the project)
2476
+ :param name: name of the model-monitoring-function/s (under the project)
2398
2477
  """
2399
- function = self.get_function(key=name)
2400
- if (
2401
- function.metadata.labels.get(mm_constants.ModelMonitoringAppLabel.KEY)
2402
- == mm_constants.ModelMonitoringAppLabel.VAL
2403
- ):
2404
- self.remove_function(name=name)
2405
- mlrun.db.get_run_db().delete_function(name=name.lower())
2406
- logger.info(f"{name} function has been removed from {self.name} project")
2478
+ names = name if isinstance(name, list) else [name]
2479
+ for func_name in names:
2480
+ function = self.get_function(key=func_name)
2481
+ if (
2482
+ function.metadata.labels.get(mm_constants.ModelMonitoringAppLabel.KEY)
2483
+ == mm_constants.ModelMonitoringAppLabel.VAL
2484
+ ):
2485
+ self.remove_function(name=func_name)
2486
+ logger.info(
2487
+ f"{func_name} function has been removed from {self.name} project"
2488
+ )
2489
+ else:
2490
+ raise logger.warn(
2491
+ f"There is no model monitoring function with {func_name} name"
2492
+ )
2493
+
2494
+ def delete_model_monitoring_function(self, name: Union[str, list[str]]):
2495
+ """delete the specified model-monitoring-app function/s
2496
+
2497
+ :param name: name of the model-monitoring-function/s (under the project)
2498
+ """
2499
+ db = mlrun.db.get_run_db(secrets=self._secrets)
2500
+ succeed = db.delete_model_monitoring_function(
2501
+ project=self.name,
2502
+ functions=name if isinstance(name, list) else [name],
2503
+ )
2504
+ if succeed:
2505
+ logger.info(
2506
+ "All the desired monitoring functions were deleted",
2507
+ project=self.name,
2508
+ functions=name,
2509
+ )
2407
2510
  else:
2408
- raise logger.error(
2409
- f"There is no model monitoring function with {name} name"
2511
+ logger.info(
2512
+ "Some of the desired monitoring functions were not deleted",
2513
+ project=self.name,
2410
2514
  )
2411
2515
 
2412
2516
  def get_function(
@@ -2514,10 +2618,10 @@ class MlrunProject(ModelObj):
2514
2618
  def create_remote(self, url, name="origin", branch=None):
2515
2619
  """Create remote for the project git
2516
2620
 
2517
- This method creates a new remote repository associated with the project's Git repository.
2518
- If a remote with the specified name already exists, it will not be overwritten.
2621
+ This method creates a new remote repository associated with the project's Git repository.
2622
+ If a remote with the specified name already exists, it will not be overwritten.
2519
2623
 
2520
- If you wish to update the URL of an existing remote, use the `set_remote` method instead.
2624
+ If you wish to update the URL of an existing remote, use the `set_remote` method instead.
2521
2625
 
2522
2626
  :param url: remote git url
2523
2627
  :param name: name for the remote (default is 'origin')
@@ -2869,21 +2973,23 @@ class MlrunProject(ModelObj):
2869
2973
  (which will be converted to the class using its `from_crontab` constructor),
2870
2974
  see this link for help:
2871
2975
  https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html#module-apscheduler.triggers.cron
2872
- for using the pre-defined workflow's schedule, set `schedule=True`
2976
+ For using the pre-defined workflow's schedule, set `schedule=True`
2873
2977
  :param timeout: Timeout in seconds to wait for pipeline completion (watch will be activated)
2874
2978
  :param source: Source to use instead of the actual `project.spec.source` (used when engine is remote).
2875
- Can be a one of:
2876
- 1. Remote URL which is loaded dynamically to the workflow runner.
2877
- 2. A path to the project's context on the workflow runner's image.
2979
+ Can be one of:
2980
+
2981
+ * Remote URL which is loaded dynamically to the workflow runner.
2982
+ * A path to the project's context on the workflow runner's image.
2878
2983
  Path can be absolute or relative to `project.spec.build.source_code_target_dir` if defined
2879
2984
  (enriched when building a project image with source, see `MlrunProject.build_image`).
2880
2985
  For other engines the source is used to validate that the code is up-to-date.
2881
2986
  :param cleanup_ttl:
2882
2987
  Pipeline cleanup ttl in secs (time to wait after workflow completion, at which point the
2883
- Workflow and all its resources are deleted)
2988
+ workflow and all its resources are deleted)
2884
2989
  :param notifications:
2885
2990
  List of notifications to send for workflow completion
2886
- :returns: Run id
2991
+
2992
+ :returns: ~py:class:`~mlrun.projects.pipelines._PipelineRunStatus` instance
2887
2993
  """
2888
2994
 
2889
2995
  arguments = arguments or {}
@@ -2941,8 +3047,12 @@ class MlrunProject(ModelObj):
2941
3047
  engine = "remote"
2942
3048
  # The default engine is kfp if not given:
2943
3049
  workflow_engine = get_workflow_engine(engine or workflow_spec.engine, local)
2944
- if not inner_engine and engine == "remote":
2945
- inner_engine = get_workflow_engine(workflow_spec.engine, local).engine
3050
+ if not inner_engine and workflow_engine.engine == "remote":
3051
+ # if inner engine is set to remote, assume kfp as the default inner engine with remote as the runner
3052
+ engine_kind = (
3053
+ workflow_spec.engine if workflow_spec.engine != "remote" else "kfp"
3054
+ )
3055
+ inner_engine = get_workflow_engine(engine_kind, local).engine
2946
3056
  workflow_spec.engine = inner_engine or workflow_engine.engine
2947
3057
 
2948
3058
  run = workflow_engine.run(
@@ -2957,7 +3067,7 @@ class MlrunProject(ModelObj):
2957
3067
  notifications=notifications,
2958
3068
  )
2959
3069
  # run is None when scheduling
2960
- if run and run.state == mlrun.run.RunStatuses.failed:
3070
+ if run and run.state == mlrun_pipelines.common.models.RunStatuses.failed:
2961
3071
  return run
2962
3072
  if not workflow_spec.schedule:
2963
3073
  # Failure and schedule messages already logged
@@ -2966,14 +3076,17 @@ class MlrunProject(ModelObj):
2966
3076
  )
2967
3077
  workflow_spec.clear_tmp()
2968
3078
  if (timeout or watch) and not workflow_spec.schedule:
3079
+ run_status_kwargs = {}
2969
3080
  status_engine = run._engine
2970
3081
  # run's engine gets replaced with inner engine if engine is remote,
2971
3082
  # so in that case we need to get the status from the remote engine manually
2972
- # TODO: support watch for remote:local
2973
- if engine == "remote" and status_engine.engine != "local":
3083
+ if workflow_engine.engine == "remote":
2974
3084
  status_engine = _RemoteRunner
3085
+ run_status_kwargs["inner_engine"] = run._engine
2975
3086
 
2976
- status_engine.get_run_status(project=self, run=run, timeout=timeout)
3087
+ status_engine.get_run_status(
3088
+ project=self, run=run, timeout=timeout, **run_status_kwargs
3089
+ )
2977
3090
  return run
2978
3091
 
2979
3092
  def save_workflow(self, name, target, artifact_path=None, ttl=None):
@@ -3073,17 +3186,18 @@ class MlrunProject(ModelObj):
3073
3186
 
3074
3187
  def set_model_monitoring_credentials(
3075
3188
  self,
3076
- access_key: str = None,
3077
- endpoint_store_connection: str = None,
3078
- stream_path: str = None,
3189
+ access_key: Optional[str] = None,
3190
+ endpoint_store_connection: Optional[str] = None,
3191
+ stream_path: Optional[str] = None,
3192
+ tsdb_connection: Optional[str] = None,
3079
3193
  ):
3080
3194
  """Set the credentials that will be used by the project's model monitoring
3081
3195
  infrastructure functions.
3082
3196
 
3083
- :param access_key: Model Monitoring access key for managing user permissions
3084
3197
  :param access_key: Model Monitoring access key for managing user permissions
3085
3198
  :param endpoint_store_connection: Endpoint store connection string
3086
3199
  :param stream_path: Path to the model monitoring stream
3200
+ :param tsdb_connection: Connection string to the time series database
3087
3201
  """
3088
3202
 
3089
3203
  secrets_dict = {}
@@ -3106,6 +3220,16 @@ class MlrunProject(ModelObj):
3106
3220
  mlrun.common.schemas.model_monitoring.ProjectSecretKeys.STREAM_PATH
3107
3221
  ] = stream_path
3108
3222
 
3223
+ if tsdb_connection:
3224
+ if not tsdb_connection.startswith("taosws://"):
3225
+ raise mlrun.errors.MLRunInvalidArgumentError(
3226
+ "Currently only TDEngine websocket connection is supported for non-v3io TSDB,"
3227
+ "please provide a full URL (e.g. taosws://user:password@host:port)"
3228
+ )
3229
+ secrets_dict[
3230
+ mlrun.common.schemas.model_monitoring.ProjectSecretKeys.TSDB_CONNECTION
3231
+ ] = tsdb_connection
3232
+
3109
3233
  self.set_secrets(
3110
3234
  secrets=secrets_dict,
3111
3235
  provider=mlrun.common.schemas.SecretProviderName.kubernetes,
@@ -3134,7 +3258,8 @@ class MlrunProject(ModelObj):
3134
3258
  notifications: list[mlrun.model.Notification] = None,
3135
3259
  returns: Optional[list[Union[str, dict[str, str]]]] = None,
3136
3260
  builder_env: Optional[dict] = None,
3137
- ) -> typing.Union[mlrun.model.RunObject, kfp.dsl.ContainerOp]:
3261
+ reset_on_run: bool = None,
3262
+ ) -> typing.Union[mlrun.model.RunObject, PipelineNodeWrapper]:
3138
3263
  """Run a local or remote task as part of a local/kubeflow pipeline
3139
3264
 
3140
3265
  example (use with project)::
@@ -3190,7 +3315,11 @@ class MlrunProject(ModelObj):
3190
3315
  artifact type can be given there. The artifact key must appear in the dictionary as
3191
3316
  "key": "the_key".
3192
3317
  :param builder_env: env vars dict for source archive config/credentials e.g. builder_env={"GIT_TOKEN": token}
3193
- :return: MLRun RunObject or KubeFlow containerOp
3318
+ :param reset_on_run: When True, function python modules would reload prior to code execution.
3319
+ This ensures latest code changes are executed. This argument must be used in
3320
+ conjunction with the local=True argument.
3321
+
3322
+ :return: MLRun RunObject or PipelineNodeWrapper
3194
3323
  """
3195
3324
  return run_function(
3196
3325
  function,
@@ -3215,6 +3344,7 @@ class MlrunProject(ModelObj):
3215
3344
  notifications=notifications,
3216
3345
  returns=returns,
3217
3346
  builder_env=builder_env,
3347
+ reset_on_run=reset_on_run,
3218
3348
  )
3219
3349
 
3220
3350
  def build_function(
@@ -3233,7 +3363,7 @@ class MlrunProject(ModelObj):
3233
3363
  requirements_file: str = None,
3234
3364
  extra_args: str = None,
3235
3365
  force_build: bool = False,
3236
- ) -> typing.Union[BuildStatus, kfp.dsl.ContainerOp]:
3366
+ ) -> typing.Union[BuildStatus, PipelineNodeWrapper]:
3237
3367
  """deploy ML function, build container with its dependencies
3238
3368
 
3239
3369
  :param function: name of the function (in the project) or function object
@@ -3344,7 +3474,6 @@ class MlrunProject(ModelObj):
3344
3474
  image: str = None,
3345
3475
  set_as_default: bool = True,
3346
3476
  with_mlrun: bool = None,
3347
- skip_deployed: bool = False,
3348
3477
  base_image: str = None,
3349
3478
  commands: list = None,
3350
3479
  secret_name: str = None,
@@ -3355,7 +3484,7 @@ class MlrunProject(ModelObj):
3355
3484
  requirements_file: str = None,
3356
3485
  extra_args: str = None,
3357
3486
  target_dir: str = None,
3358
- ) -> typing.Union[BuildStatus, kfp.dsl.ContainerOp]:
3487
+ ) -> typing.Union[BuildStatus, PipelineNodeWrapper]:
3359
3488
  """Builder docker image for the project, based on the project's build config. Parameters allow to override
3360
3489
  the build config.
3361
3490
  If the project has a source configured and pull_at_runtime is not configured, this source will be cloned to the
@@ -3365,7 +3494,6 @@ class MlrunProject(ModelObj):
3365
3494
  used. If not set, the `mlconf.default_project_image_name` value will be used
3366
3495
  :param set_as_default: set `image` to be the project's default image (default False)
3367
3496
  :param with_mlrun: add the current mlrun package to the container build
3368
- :param skip_deployed: *Deprecated* parameter is ignored
3369
3497
  :param base_image: base image name/path (commands and source code will be added to it) defaults to
3370
3498
  mlrun.mlconf.default_base_image
3371
3499
  :param commands: list of docker build (RUN) commands e.g. ['pip install pandas']
@@ -3390,14 +3518,6 @@ class MlrunProject(ModelObj):
3390
3518
  base_image=base_image,
3391
3519
  )
3392
3520
 
3393
- if skip_deployed:
3394
- warnings.warn(
3395
- "The 'skip_deployed' parameter is deprecated and will be removed in 1.7.0. "
3396
- "This parameter is ignored.",
3397
- # TODO: remove in 1.7.0
3398
- FutureWarning,
3399
- )
3400
-
3401
3521
  if not overwrite_build_params:
3402
3522
  # TODO: change overwrite_build_params default to True in 1.8.0
3403
3523
  warnings.warn(
@@ -3475,7 +3595,7 @@ class MlrunProject(ModelObj):
3475
3595
  verbose: bool = None,
3476
3596
  builder_env: dict = None,
3477
3597
  mock: bool = None,
3478
- ) -> typing.Union[DeployStatus, kfp.dsl.ContainerOp]:
3598
+ ) -> typing.Union[DeployStatus, PipelineNodeWrapper]:
3479
3599
  """deploy real-time (nuclio based) functions
3480
3600
 
3481
3601
  :param function: name of the function (in the project) or function object
@@ -3660,9 +3780,7 @@ class MlrunProject(ModelObj):
3660
3780
  :returns: List of function objects.
3661
3781
  """
3662
3782
 
3663
- model_monitoring_labels_list = [
3664
- f"{mm_constants.ModelMonitoringAppLabel.KEY}={mm_constants.ModelMonitoringAppLabel.VAL}"
3665
- ]
3783
+ model_monitoring_labels_list = [str(mm_constants.ModelMonitoringAppLabel())]
3666
3784
  if labels:
3667
3785
  model_monitoring_labels_list += labels
3668
3786
  return self.list_functions(
@@ -3676,7 +3794,10 @@ class MlrunProject(ModelObj):
3676
3794
  name: Optional[str] = None,
3677
3795
  uid: Optional[Union[str, list[str]]] = None,
3678
3796
  labels: Optional[Union[str, list[str]]] = None,
3679
- state: Optional[str] = None,
3797
+ state: Optional[
3798
+ mlrun.common.runtimes.constants.RunStates
3799
+ ] = None, # Backward compatibility
3800
+ states: typing.Optional[list[mlrun.common.runtimes.constants.RunStates]] = None,
3680
3801
  sort: bool = True,
3681
3802
  last: int = 0,
3682
3803
  iter: bool = False,
@@ -3710,10 +3831,11 @@ class MlrunProject(ModelObj):
3710
3831
  :param labels: A list of labels to filter by. Label filters work by either filtering a specific value
3711
3832
  of a label (i.e. list("key=value")) or by looking for the existence of a given
3712
3833
  key (i.e. "key").
3713
- :param state: List only runs whose state is specified.
3834
+ :param state: Deprecated - List only runs whose state is specified.
3835
+ :param states: List only runs whose state is one of the provided states.
3714
3836
  :param sort: Whether to sort the result according to their start time. Otherwise, results will be
3715
3837
  returned by their internal order in the DB (order will not be guaranteed).
3716
- :param last: Deprecated - currently not used (will be removed in 1.8.0).
3838
+ :param last: Deprecated - currently not used (will be removed in 1.9.0).
3717
3839
  :param iter: If ``True`` return runs from all iterations. Otherwise, return only runs whose ``iter`` is 0.
3718
3840
  :param start_time_from: Filter by run start time in ``[start_time_from, start_time_to]``.
3719
3841
  :param start_time_to: Filter by run start time in ``[start_time_from, start_time_to]``.
@@ -3721,13 +3843,22 @@ class MlrunProject(ModelObj):
3721
3843
  last_update_time_to)``.
3722
3844
  :param last_update_time_to: Filter by run last update time in ``(last_update_time_from, last_update_time_to)``.
3723
3845
  """
3846
+ if state:
3847
+ # TODO: Remove this in 1.9.0
3848
+ warnings.warn(
3849
+ "'state' is deprecated and will be removed in 1.9.0. Use 'states' instead.",
3850
+ FutureWarning,
3851
+ )
3852
+
3724
3853
  db = mlrun.db.get_run_db(secrets=self._secrets)
3725
3854
  return db.list_runs(
3726
3855
  name,
3727
3856
  uid,
3728
3857
  self.metadata.name,
3729
3858
  labels=labels,
3730
- state=state,
3859
+ states=mlrun.utils.helpers.as_list(state)
3860
+ if state is not None
3861
+ else states or None,
3731
3862
  sort=sort,
3732
3863
  last=last,
3733
3864
  iter=iter,
@@ -3822,15 +3953,15 @@ class MlrunProject(ModelObj):
3822
3953
  on MLRun and Nuclio sides, such as the 'host' attribute.
3823
3954
  Nuclio docs here: https://docs.nuclio.io/en/latest/reference/api-gateway/http.html
3824
3955
 
3825
- :param api_gateway: An instance of :py:class:`~mlrun.runtimes.nuclio.APIGateway` representing the configuration
3826
- of the API Gateway to be created or updated.
3827
- :param wait_for_readiness: (Optional) A boolean indicating whether to wait for the API Gateway to become ready
3828
- after creation or update (default is True)
3829
- :param max_wait_time: (Optional) Maximum time to wait for API Gateway readiness in seconds (default is 90s)
3956
+ :param api_gateway: An instance of :py:class:`~mlrun.runtimes.nuclio.APIGateway` representing the
3957
+ configuration of the API Gateway to be created or updated.
3958
+ :param wait_for_readiness: (Optional) A boolean indicating whether to wait for the API Gateway to become
3959
+ ready after creation or update (default is True).
3960
+ :param max_wait_time: (Optional) Maximum time to wait for API Gateway readiness in seconds (default is 90s)
3830
3961
 
3831
3962
 
3832
- @return: An instance of :py:class:`~mlrun.runtimes.nuclio.APIGateway` with all fields populated based on the
3833
- information retrieved from the Nuclio API
3963
+ :returns: An instance of :py:class:`~mlrun.runtimes.nuclio.APIGateway` with all fields populated based on the
3964
+ information retrieved from the Nuclio API
3834
3965
  """
3835
3966
 
3836
3967
  api_gateway_json = mlrun.db.get_run_db().store_api_gateway(
@@ -3852,8 +3983,8 @@ class MlrunProject(ModelObj):
3852
3983
  """
3853
3984
  Retrieves a list of Nuclio API gateways associated with the project.
3854
3985
 
3855
- @return: List of :py:class:`~mlrun.runtimes.nuclio.api_gateway.APIGateway` objects representing
3856
- the Nuclio API gateways associated with the project.
3986
+ :returns: List of :py:class:`~mlrun.runtimes.nuclio.api_gateway.APIGateway` objects representing
3987
+ the Nuclio API gateways associated with the project.
3857
3988
  """
3858
3989
  gateways_list = mlrun.db.get_run_db().list_api_gateways(self.name)
3859
3990
  return [
@@ -3889,9 +4020,12 @@ class MlrunProject(ModelObj):
3889
4020
 
3890
4021
  mlrun.db.get_run_db().delete_api_gateway(name=name, project=self.name)
3891
4022
 
3892
- def store_alert_config(self, alert_data: AlertConfig, alert_name=None):
4023
+ def store_alert_config(
4024
+ self, alert_data: AlertConfig, alert_name=None
4025
+ ) -> AlertConfig:
3893
4026
  """
3894
4027
  Create/modify an alert.
4028
+
3895
4029
  :param alert_data: The data of the alert.
3896
4030
  :param alert_name: The name of the alert.
3897
4031
  :return: the created/modified alert.
@@ -3899,20 +4033,22 @@ class MlrunProject(ModelObj):
3899
4033
  db = mlrun.db.get_run_db(secrets=self._secrets)
3900
4034
  if alert_name is None:
3901
4035
  alert_name = alert_data.name
3902
- return db.store_alert_config(alert_name, alert_data.dict(), self.metadata.name)
4036
+ return db.store_alert_config(alert_name, alert_data, project=self.metadata.name)
3903
4037
 
3904
4038
  def get_alert_config(self, alert_name: str) -> AlertConfig:
3905
4039
  """
3906
4040
  Retrieve an alert.
4041
+
3907
4042
  :param alert_name: The name of the alert to retrieve.
3908
4043
  :return: The alert object.
3909
4044
  """
3910
4045
  db = mlrun.db.get_run_db(secrets=self._secrets)
3911
4046
  return db.get_alert_config(alert_name, self.metadata.name)
3912
4047
 
3913
- def list_alerts_configs(self):
4048
+ def list_alerts_configs(self) -> list[AlertConfig]:
3914
4049
  """
3915
4050
  Retrieve list of alerts of a project.
4051
+
3916
4052
  :return: All the alerts objects of the project.
3917
4053
  """
3918
4054
  db = mlrun.db.get_run_db(secrets=self._secrets)
@@ -3923,6 +4059,7 @@ class MlrunProject(ModelObj):
3923
4059
  ):
3924
4060
  """
3925
4061
  Delete an alert.
4062
+
3926
4063
  :param alert_data: The data of the alert.
3927
4064
  :param alert_name: The name of the alert to delete.
3928
4065
  """
@@ -3942,6 +4079,7 @@ class MlrunProject(ModelObj):
3942
4079
  ):
3943
4080
  """
3944
4081
  Reset an alert.
4082
+
3945
4083
  :param alert_data: The data of the alert.
3946
4084
  :param alert_name: The name of the alert to reset.
3947
4085
  """
@@ -3956,12 +4094,31 @@ class MlrunProject(ModelObj):
3956
4094
  alert_name = alert_data.name
3957
4095
  db.reset_alert_config(alert_name, self.metadata.name)
3958
4096
 
4097
+ def get_alert_template(self, template_name: str) -> AlertTemplate:
4098
+ """
4099
+ Retrieve a specific alert template.
4100
+
4101
+ :param template_name: The name of the template to retrieve.
4102
+ :return: The template object.
4103
+ """
4104
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4105
+ return db.get_alert_template(template_name)
4106
+
4107
+ def list_alert_templates(self) -> list[AlertTemplate]:
4108
+ """
4109
+ Retrieve list of all alert templates.
4110
+
4111
+ :return: All the alert template objects in the database.
4112
+ """
4113
+ db = mlrun.db.get_run_db(secrets=self._secrets)
4114
+ return db.list_alert_templates()
4115
+
3959
4116
  def _run_authenticated_git_action(
3960
4117
  self,
3961
4118
  action: Callable,
3962
4119
  remote: str,
3963
- args: list = [],
3964
- kwargs: dict = {},
4120
+ args: list = None,
4121
+ kwargs: dict = None,
3965
4122
  secrets: Union[SecretsStore, dict] = None,
3966
4123
  ):
3967
4124
  """Run an arbitrary Git routine while the remote is enriched with secrets
@@ -3981,6 +4138,8 @@ class MlrunProject(ModelObj):
3981
4138
  try:
3982
4139
  if is_remote_enriched:
3983
4140
  self.spec.repo.remotes[remote].set_url(enriched_remote, clean_remote)
4141
+ args = args or []
4142
+ kwargs = kwargs or {}
3984
4143
  action(*args, **kwargs)
3985
4144
  except RuntimeError as e:
3986
4145
  raise mlrun.errors.MLRunRuntimeError(
@@ -4056,12 +4215,21 @@ class MlrunProject(ModelObj):
4056
4215
  else:
4057
4216
  producer_dict = artifact.spec.producer
4058
4217
 
4218
+ producer_tag = producer_dict.get("tag", None)
4219
+ producer_project = producer_dict.get("project", None)
4220
+ if not producer_tag or not producer_project:
4221
+ # try resolving the producer tag from the uri
4222
+ producer_uri = artifact.spec.producer.get("uri", "")
4223
+ producer_project, producer_tag, _ = ArtifactProducer.parse_uri(
4224
+ producer_uri
4225
+ )
4226
+
4059
4227
  if producer_dict.get("kind", "") == "run":
4060
4228
  return ArtifactProducer(
4061
4229
  name=producer_dict.get("name", ""),
4062
4230
  kind=producer_dict.get("kind", ""),
4063
- project=producer_dict.get("project", ""),
4064
- tag=producer_dict.get("tag", ""),
4231
+ project=producer_project,
4232
+ tag=producer_tag,
4065
4233
  ), True
4066
4234
 
4067
4235
  # do not retain the artifact's producer, replace it with the project as the producer