mlrun 1.8.0rc12__py3-none-any.whl → 1.8.0rc15__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 (33) hide show
  1. mlrun/artifacts/document.py +32 -6
  2. mlrun/common/formatters/artifact.py +1 -1
  3. mlrun/common/schemas/partition.py +23 -18
  4. mlrun/common/types.py +1 -0
  5. mlrun/config.py +3 -2
  6. mlrun/datastore/vectorstore.py +69 -26
  7. mlrun/db/base.py +21 -1
  8. mlrun/db/httpdb.py +53 -17
  9. mlrun/db/nopdb.py +12 -1
  10. mlrun/execution.py +43 -11
  11. mlrun/model_monitoring/applications/_application_steps.py +1 -1
  12. mlrun/model_monitoring/applications/base.py +2 -3
  13. mlrun/model_monitoring/applications/context.py +94 -71
  14. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +0 -21
  15. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +3 -3
  16. mlrun/projects/pipelines.py +13 -6
  17. mlrun/projects/project.py +80 -2
  18. mlrun/runtimes/nuclio/function.py +2 -1
  19. mlrun/runtimes/nuclio/serving.py +10 -5
  20. mlrun/serving/routers.py +16 -7
  21. mlrun/serving/states.py +14 -6
  22. mlrun/serving/v2_serving.py +11 -6
  23. mlrun/utils/helpers.py +23 -1
  24. mlrun/utils/notifications/notification/base.py +1 -1
  25. mlrun/utils/notifications/notification/webhook.py +13 -12
  26. mlrun/utils/notifications/notification_pusher.py +18 -23
  27. mlrun/utils/version/version.json +2 -2
  28. {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/METADATA +14 -8
  29. {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/RECORD +33 -33
  30. {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/LICENSE +0 -0
  31. {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/WHEEL +0 -0
  32. {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/entry_points.txt +0 -0
  33. {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/top_level.txt +0 -0
@@ -89,12 +89,17 @@ class MLRunLoader:
89
89
  A factory class for creating instances of a dynamically defined document loader.
90
90
 
91
91
  Args:
92
- artifact_key (str): The key for the artifact to be logged.It can include '%%' which will be replaced
93
- by a hex-encoded version of the source path.
92
+ artifact_key (str, optional): The key for the artifact to be logged. Special characters and symbols
93
+ not valid in artifact names will be encoded as their hexadecimal representation. The '%%' pattern
94
+ in the key will be replaced by the hex-encoded version of the source path. Defaults to "doc%%".
94
95
  local_path (str): The source path of the document to be loaded.
95
96
  loader_spec (DocumentLoaderSpec): Specification for the document loader.
96
- producer (Optional[Union[MlrunProject, str, MLClientCtx]], optional): The producer of the document
97
+ producer (Optional[Union[MlrunProject, str, MLClientCtx]], optional): The producer of the document.
98
+ If not specified, will try to get the current MLRun context or project.
99
+ Defaults to None.
97
100
  upload (bool, optional): Flag indicating whether to upload the document.
101
+ labels (Optional[Dict[str, str]], optional): Key-value labels to attach to the artifact. Defaults to None.
102
+ tag (str, optional): Version tag for the artifact. Defaults to "".
98
103
 
99
104
  Returns:
100
105
  DynamicDocumentLoader: An instance of a dynamically defined subclass of BaseLoader.
@@ -146,6 +151,8 @@ class MLRunLoader:
146
151
  artifact_key="doc%%",
147
152
  producer: Optional[Union["MlrunProject", str, "MLClientCtx"]] = None, # noqa: F821
148
153
  upload: bool = False,
154
+ tag: str = "",
155
+ labels: Optional[dict[str, str]] = None,
149
156
  ):
150
157
  # Dynamically import BaseLoader
151
158
  from langchain_community.document_loaders.base import BaseLoader
@@ -158,6 +165,8 @@ class MLRunLoader:
158
165
  artifact_key,
159
166
  producer,
160
167
  upload,
168
+ tag,
169
+ labels,
161
170
  ):
162
171
  self.producer = producer
163
172
  self.artifact_key = (
@@ -168,6 +177,8 @@ class MLRunLoader:
168
177
  self.loader_spec = loader_spec
169
178
  self.local_path = local_path
170
179
  self.upload = upload
180
+ self.tag = tag
181
+ self.labels = labels
171
182
 
172
183
  # Resolve the producer
173
184
  if not self.producer:
@@ -181,9 +192,11 @@ class MLRunLoader:
181
192
  document_loader_spec=self.loader_spec,
182
193
  local_path=self.local_path,
183
194
  upload=self.upload,
195
+ labels=self.labels,
196
+ tag=self.tag,
184
197
  )
185
198
  res = artifact.to_langchain_documents()
186
- yield res[0]
199
+ return res
187
200
 
188
201
  # Return an instance of the dynamically defined subclass
189
202
  instance = DynamicDocumentLoader(
@@ -192,6 +205,8 @@ class MLRunLoader:
192
205
  loader_spec=loader_spec,
193
206
  producer=producer,
194
207
  upload=upload,
208
+ tag=tag,
209
+ labels=labels,
195
210
  )
196
211
  return instance
197
212
 
@@ -257,6 +272,9 @@ class DocumentArtifact(Artifact):
257
272
  METADATA_CHUNK_KEY = "mlrun_chunk"
258
273
  METADATA_ARTIFACT_URI_KEY = "mlrun_object_uri"
259
274
  METADATA_ARTIFACT_TARGET_PATH_KEY = "mlrun_target_path"
275
+ METADATA_ARTIFACT_TAG = "mlrun_tag"
276
+ METADATA_ARTIFACT_KEY = "mlrun_key"
277
+ METADATA_ARTIFACT_PROJECT = "mlrun_project"
260
278
 
261
279
  def __init__(
262
280
  self,
@@ -331,6 +349,10 @@ class DocumentArtifact(Artifact):
331
349
  metadata[self.METADATA_ORIGINAL_SOURCE_KEY] = self.spec.original_source
332
350
  metadata[self.METADATA_SOURCE_KEY] = self.get_source()
333
351
  metadata[self.METADATA_ARTIFACT_URI_KEY] = self.uri
352
+ metadata[self.METADATA_ARTIFACT_TAG] = self.tag or "latest"
353
+ metadata[self.METADATA_ARTIFACT_KEY] = self.key
354
+ metadata[self.METADATA_ARTIFACT_PROJECT] = self.metadata.project
355
+
334
356
  if self.get_target_path():
335
357
  metadata[self.METADATA_ARTIFACT_TARGET_PATH_KEY] = (
336
358
  self.get_target_path()
@@ -346,7 +368,7 @@ class DocumentArtifact(Artifact):
346
368
  idx = idx + 1
347
369
  return results
348
370
 
349
- def collection_add(self, collection_id: str) -> None:
371
+ def collection_add(self, collection_id: str) -> bool:
350
372
  """
351
373
  Add a collection ID to the artifact's collection list.
352
374
 
@@ -361,8 +383,10 @@ class DocumentArtifact(Artifact):
361
383
  """
362
384
  if collection_id not in self.spec.collections:
363
385
  self.spec.collections[collection_id] = "1"
386
+ return True
387
+ return False
364
388
 
365
- def collection_remove(self, collection_id: str) -> None:
389
+ def collection_remove(self, collection_id: str) -> bool:
366
390
  """
367
391
  Remove a collection ID from the artifact's collection list.
368
392
 
@@ -376,3 +400,5 @@ class DocumentArtifact(Artifact):
376
400
  """
377
401
  if collection_id in self.spec.collections:
378
402
  self.spec.collections.pop(collection_id)
403
+ return True
404
+ return False
@@ -32,7 +32,7 @@ class ArtifactFormat(ObjectFormat, mlrun.common.types.StrEnum):
32
32
  [
33
33
  "kind",
34
34
  "metadata",
35
- "status",
35
+ "status.state",
36
36
  "project",
37
37
  "spec.producer",
38
38
  "spec.db_key",
@@ -46,24 +46,23 @@ class PartitionInterval(StrEnum):
46
46
  return timedelta(weeks=1)
47
47
 
48
48
  @classmethod
49
- def from_function(cls, partition_function: str):
49
+ def from_expression(cls, partition_expression: str):
50
50
  """
51
- Returns the corresponding PartitionInterval for a given partition function,
51
+ Returns the corresponding PartitionInterval for a given partition expression,
52
52
  or None if the function is not mapped.
53
53
 
54
- :param partition_function: The partition function to map to an interval.
55
- :return: PartitionInterval corresponding to the function, or None if no match is found.
54
+ :param partition_expression: The partition expression to map to an interval.
55
+ :return: PartitionInterval corresponding to the expression, or `month` if no match is found.
56
56
  """
57
- partition_function_to_partitions_interval = {
58
- "DAY": "DAY",
59
- "DAYOFMONTH": "DAY",
60
- "MONTH": "MONTH",
61
- "YEARWEEK": "YEARWEEK",
62
- }
63
- interval = partition_function_to_partitions_interval.get(partition_function)
64
- if interval and cls.is_valid(interval):
65
- return cls[interval]
66
- raise KeyError(f"Partition function: {partition_function} isn't supported")
57
+
58
+ # Match the provided function string to the correct interval
59
+ partition_expression = partition_expression.upper()
60
+ if "YEARWEEK" in partition_expression:
61
+ return cls.YEARWEEK
62
+ elif "DAYOFMONTH" in partition_expression:
63
+ return cls.DAY
64
+ else:
65
+ return cls.MONTH
67
66
 
68
67
  def get_partition_info(
69
68
  self,
@@ -120,11 +119,17 @@ class PartitionInterval(StrEnum):
120
119
  year, week, _ = current_datetime.isocalendar()
121
120
  return f"{year}{week:02d}"
122
121
 
123
- def get_partition_expression(self):
122
+ def get_partition_expression(self, column_name: str):
124
123
  if self == PartitionInterval.YEARWEEK:
125
- return "YEARWEEK(activation_time, 1)"
126
- else:
127
- return f"{self}(activation_time)"
124
+ return f"YEARWEEK({column_name}, 1)"
125
+ elif self == PartitionInterval.DAY:
126
+ # generates value in format %Y%m%d in mysql
127
+ # mysql query example: `select YEAR(NOW())*10000 + MONTH(NOW())*100 + DAY(NOW());`
128
+ return f"YEAR({column_name}) * 10000 + MONTH({column_name}) * 100 + DAY({column_name})"
129
+ elif self == PartitionInterval.MONTH:
130
+ # generates value in format %Y%m in mysql
131
+ # mysql query example: `select YEAR(NOW())*100 + MONTH(NOW());`
132
+ return f"YEAR({column_name}) * 100 + MONTH({column_name})"
128
133
 
129
134
  def get_number_of_partitions(self, days: int) -> int:
130
135
  # Calculate the number partitions based on given number of days
mlrun/common/types.py CHANGED
@@ -31,6 +31,7 @@ class HTTPMethod(StrEnum):
31
31
  POST = "POST"
32
32
  DELETE = "DELETE"
33
33
  PATCH = "PATCH"
34
+ PUT = "PUT"
34
35
 
35
36
 
36
37
  class Operation(StrEnum):
mlrun/config.py CHANGED
@@ -83,7 +83,7 @@ default_config = {
83
83
  "images_to_enrich_registry": "^mlrun/*,python:3.9",
84
84
  "kfp_url": "",
85
85
  "kfp_ttl": "14400", # KFP ttl in sec, after that completed PODs will be deleted
86
- "kfp_image": "mlrun/mlrun", # image to use for KFP runner (defaults to mlrun/mlrun)
86
+ "kfp_image": "mlrun/mlrun-kfp", # image to use for KFP runner (defaults to mlrun/mlrun-kfp)
87
87
  "dask_kfp_image": "mlrun/ml-base", # image to use for dask KFP runner (defaults to mlrun/ml-base)
88
88
  "igz_version": "", # the version of the iguazio system the API is running on
89
89
  "iguazio_api_url": "", # the url to iguazio api
@@ -645,7 +645,7 @@ default_config = {
645
645
  "auto_add_project_secrets": True,
646
646
  "project_secret_name": "mlrun-project-secrets-{project}",
647
647
  "auth_secret_name": "mlrun-auth-secrets.{hashed_access_key}",
648
- "env_variable_prefix": "MLRUN_K8S_SECRET__",
648
+ "env_variable_prefix": "",
649
649
  "global_function_env_secret_name": None,
650
650
  },
651
651
  },
@@ -825,6 +825,7 @@ default_config = {
825
825
  "refresh_interval": "30",
826
826
  }
827
827
  },
828
+ "system_id": "",
828
829
  }
829
830
  _is_running_as_api = None
830
831
 
@@ -19,19 +19,42 @@ from typing import Optional, Union
19
19
  from mlrun.artifacts import DocumentArtifact
20
20
 
21
21
 
22
- def _extract_collection_name(vectorstore: "VectorStore") -> str: # noqa: F821
23
- # List of possible attribute names for collection name
24
- possible_attributes = ["collection_name", "_collection_name"]
22
+ def find_existing_attribute(obj, base_name="name", parent_name="collection"):
23
+ # Define all possible patterns
24
+
25
+ return None
26
+
25
27
 
26
- for attr in possible_attributes:
27
- if hasattr(vectorstore, attr):
28
- collection_name = getattr(vectorstore, attr)
29
- if collection_name:
30
- return collection_name
28
+ def _extract_collection_name(vectorstore: "VectorStore") -> str: # noqa: F821
29
+ patterns = [
30
+ "collection.name",
31
+ "collection._name",
32
+ "_collection.name",
33
+ "_collection._name",
34
+ "collection_name",
35
+ "_collection_name",
36
+ ]
37
+
38
+ def resolve_attribute(obj, pattern):
39
+ if "." in pattern:
40
+ parts = pattern.split(".")
41
+ current = vectorstore
42
+ for part in parts:
43
+ if hasattr(current, part):
44
+ current = getattr(current, part)
45
+ else:
46
+ return None
47
+ return current
48
+ else:
49
+ return getattr(obj, pattern, None)
31
50
 
32
- store_class = vectorstore.__class__.__name__.lower()
33
- if store_class == "mongodbatlasvectorsearch":
34
- return vectorstore.collection.name
51
+ for pattern in patterns:
52
+ try:
53
+ value = resolve_attribute(vectorstore, pattern)
54
+ if value is not None:
55
+ return value
56
+ except (AttributeError, TypeError):
57
+ continue
35
58
 
36
59
  # If we get here, we couldn't find a valid collection name
37
60
  raise ValueError(
@@ -82,6 +105,19 @@ class VectorStoreCollection:
82
105
  # Forward the attribute setting to _collection_impl
83
106
  setattr(self._collection_impl, name, value)
84
107
 
108
+ def _get_mlrun_project_name(self):
109
+ import mlrun
110
+
111
+ if self._mlrun_context and isinstance(
112
+ self._mlrun_context, mlrun.projects.MlrunProject
113
+ ):
114
+ return self._mlrun_context.name
115
+ if self._mlrun_context and isinstance(
116
+ self._mlrun_context, mlrun.execution.MLClientCtx
117
+ ):
118
+ return self._mlrun_context.get_project_object().name
119
+ return None
120
+
85
121
  def delete(self, *args, **kwargs):
86
122
  self._collection_impl.delete(*args, **kwargs)
87
123
 
@@ -106,13 +142,22 @@ class VectorStoreCollection:
106
142
  """
107
143
  if self._mlrun_context:
108
144
  for document in documents:
109
- mlrun_uri = document.metadata.get(
110
- DocumentArtifact.METADATA_ARTIFACT_URI_KEY
145
+ mlrun_key = document.metadata.get(
146
+ DocumentArtifact.METADATA_ARTIFACT_KEY, None
147
+ )
148
+ mlrun_project = document.metadata.get(
149
+ DocumentArtifact.METADATA_ARTIFACT_PROJECT, None
111
150
  )
112
- if mlrun_uri:
113
- artifact = self._mlrun_context.get_store_resource(mlrun_uri)
114
- artifact.collection_add(self.collection_name)
115
- self._mlrun_context.update_artifact(artifact)
151
+
152
+ if mlrun_key and mlrun_project == self._get_mlrun_project_name():
153
+ mlrun_tag = document.metadata.get(
154
+ DocumentArtifact.METADATA_ARTIFACT_TAG, None
155
+ )
156
+ artifact = self._mlrun_context.get_artifact(
157
+ key=mlrun_key, tag=mlrun_tag
158
+ )
159
+ if artifact.collection_add(self.collection_name):
160
+ self._mlrun_context.update_artifact(artifact)
116
161
 
117
162
  return self._collection_impl.add_documents(documents, **kwargs)
118
163
 
@@ -159,8 +204,7 @@ class VectorStoreCollection:
159
204
  )
160
205
  for index, artifact in enumerate(artifacts):
161
206
  documents = artifact.to_langchain_documents(splitter)
162
- artifact.collection_add(self.collection_name)
163
- if self._mlrun_context:
207
+ if artifact.collection_add(self.collection_name) and self._mlrun_context:
164
208
  self._mlrun_context.update_artifact(artifact)
165
209
  if user_ids:
166
210
  num_of_documents = len(documents)
@@ -182,8 +226,8 @@ class VectorStoreCollection:
182
226
  Args:
183
227
  artifact (DocumentArtifact): The artifact from which the current object should be removed.
184
228
  """
185
- artifact.collection_remove(self.collection_name)
186
- if self._mlrun_context:
229
+
230
+ if artifact.collection_remove(self.collection_name) and self._mlrun_context:
187
231
  self._mlrun_context.update_artifact(artifact)
188
232
 
189
233
  def delete_artifacts(self, artifacts: list[DocumentArtifact]):
@@ -201,16 +245,15 @@ class VectorStoreCollection:
201
245
  """
202
246
  store_class = self._collection_impl.__class__.__name__.lower()
203
247
  for artifact in artifacts:
204
- artifact.collection_remove(self.collection_name)
205
- if self._mlrun_context:
248
+ if artifact.collection_remove(self.collection_name) and self._mlrun_context:
206
249
  self._mlrun_context.update_artifact(artifact)
207
250
 
208
251
  if store_class == "milvus":
209
252
  expr = f"{DocumentArtifact.METADATA_SOURCE_KEY} == '{artifact.get_source()}'"
210
- return self._collection_impl.delete(expr=expr)
253
+ self._collection_impl.delete(expr=expr)
211
254
  elif store_class == "chroma":
212
255
  where = {DocumentArtifact.METADATA_SOURCE_KEY: artifact.get_source()}
213
- return self._collection_impl.delete(where=where)
256
+ self._collection_impl.delete(where=where)
214
257
 
215
258
  elif (
216
259
  hasattr(self._collection_impl, "delete")
@@ -222,7 +265,7 @@ class VectorStoreCollection:
222
265
  DocumentArtifact.METADATA_SOURCE_KEY: artifact.get_source()
223
266
  }
224
267
  }
225
- return self._collection_impl.delete(filter=filter)
268
+ self._collection_impl.delete(filter=filter)
226
269
  else:
227
270
  raise NotImplementedError(
228
271
  f"delete_artifacts() operation not supported for {store_class}"
mlrun/db/base.py CHANGED
@@ -23,6 +23,7 @@ import mlrun.common
23
23
  import mlrun.common.formatters
24
24
  import mlrun.common.runtimes.constants
25
25
  import mlrun.common.schemas
26
+ import mlrun.common.schemas.model_monitoring.constants as mm_constants
26
27
  import mlrun.common.schemas.model_monitoring.model_endpoints as mm_endpoints
27
28
  import mlrun.model_monitoring
28
29
 
@@ -58,6 +59,15 @@ class RunDBInterface(ABC):
58
59
  def abort_run(self, uid, project="", iter=0, timeout=45, status_text=""):
59
60
  pass
60
61
 
62
+ @abstractmethod
63
+ def push_run_notifications(
64
+ self,
65
+ uid,
66
+ project="",
67
+ timeout=45,
68
+ ):
69
+ pass
70
+
61
71
  @abstractmethod
62
72
  def read_run(
63
73
  self,
@@ -666,7 +676,9 @@ class RunDBInterface(ABC):
666
676
  def create_model_endpoint(
667
677
  self,
668
678
  model_endpoint: mlrun.common.schemas.ModelEndpoint,
669
- creation_strategy: mlrun.common.schemas.ModelEndpointCreationStrategy = "inplace",
679
+ creation_strategy: Optional[
680
+ mm_constants.ModelEndpointCreationStrategy
681
+ ] = mm_constants.ModelEndpointCreationStrategy.INPLACE,
670
682
  ) -> mlrun.common.schemas.ModelEndpoint:
671
683
  pass
672
684
 
@@ -896,6 +908,14 @@ class RunDBInterface(ABC):
896
908
  ):
897
909
  pass
898
910
 
911
+ def update_alert_activation(
912
+ self,
913
+ activation_id: int,
914
+ activation_time: datetime.datetime,
915
+ notifications_states,
916
+ ):
917
+ pass
918
+
899
919
  @abstractmethod
900
920
  def get_builder_status(
901
921
  self,
mlrun/db/httpdb.py CHANGED
@@ -35,6 +35,7 @@ import mlrun.common.constants
35
35
  import mlrun.common.formatters
36
36
  import mlrun.common.runtimes
37
37
  import mlrun.common.schemas
38
+ import mlrun.common.schemas.model_monitoring.constants as mm_constants
38
39
  import mlrun.common.schemas.model_monitoring.model_endpoints as mm_endpoints
39
40
  import mlrun.common.types
40
41
  import mlrun.platforms
@@ -755,6 +756,34 @@ class HTTPRunDB(RunDBInterface):
755
756
  )
756
757
  return None
757
758
 
759
+ def push_run_notifications(
760
+ self,
761
+ uid,
762
+ project="",
763
+ timeout=45,
764
+ ):
765
+ """
766
+ Push notifications for a run.
767
+
768
+ :param uid: Unique ID of the run.
769
+ :param project: Project that the run belongs to.
770
+ :returns: :py:class:`~mlrun.common.schemas.BackgroundTask`.
771
+ """
772
+ project = project or config.default_project
773
+
774
+ response = self.api_call(
775
+ "POST",
776
+ path=f"projects/{project}/runs/{uid}/push_notifications",
777
+ error="Failed push notifications",
778
+ timeout=timeout,
779
+ )
780
+ if response.status_code == http.HTTPStatus.ACCEPTED:
781
+ background_task = mlrun.common.schemas.BackgroundTask(**response.json())
782
+ return self._wait_for_background_task_to_reach_terminal_state(
783
+ background_task.metadata.name, project=project
784
+ )
785
+ return None
786
+
758
787
  def read_run(
759
788
  self,
760
789
  uid,
@@ -821,8 +850,9 @@ class HTTPRunDB(RunDBInterface):
821
850
  with_notifications: bool = False,
822
851
  ) -> RunList:
823
852
  """
824
- Retrieve a list of runs, filtered by various options.
825
- If no filter is provided, will return runs from the last week.
853
+ Retrieve a list of runs.
854
+ The default returns the runs from the last week, partitioned by project/name.
855
+ To override the default, specify any filter.
826
856
 
827
857
  Example::
828
858
 
@@ -3582,18 +3612,24 @@ class HTTPRunDB(RunDBInterface):
3582
3612
  def create_model_endpoint(
3583
3613
  self,
3584
3614
  model_endpoint: mlrun.common.schemas.ModelEndpoint,
3585
- creation_strategy: mlrun.common.schemas.ModelEndpointCreationStrategy = "inplace",
3615
+ creation_strategy: Optional[
3616
+ mm_constants.ModelEndpointCreationStrategy
3617
+ ] = mm_constants.ModelEndpointCreationStrategy.INPLACE,
3586
3618
  ) -> mlrun.common.schemas.ModelEndpoint:
3587
3619
  """
3588
3620
  Creates a DB record with the given model_endpoint record.
3589
3621
 
3590
3622
  :param model_endpoint: An object representing the model endpoint.
3591
- :param creation_strategy: model endpoint creation strategy :
3592
- * overwrite - Create a new model endpoint and delete the last old one if it exists.
3593
- * inplace - Use the existing model endpoint if it already exists (default).
3594
- * archive - Preserve the old model endpoint and create a new one,
3595
- tagging it as the latest.
3596
-
3623
+ :param creation_strategy: Strategy for creating or updating the model endpoint:
3624
+ * **overwrite**:
3625
+ 1. If model endpoints with the same name exist, delete the `latest` one.
3626
+ 2. Create a new model endpoint entry and set it as `latest`.
3627
+ * **inplace** (default):
3628
+ 1. If model endpoints with the same name exist, update the `latest` entry.
3629
+ 2. Otherwise, create a new entry.
3630
+ * **archive**:
3631
+ 1. If model endpoints with the same name exist, preserve them.
3632
+ 2. Create a new model endpoint with the same name and set it to `latest`.
3597
3633
  :return: The created model endpoint object.
3598
3634
  """
3599
3635
 
@@ -3809,7 +3845,7 @@ class HTTPRunDB(RunDBInterface):
3809
3845
  """
3810
3846
  self.api_call(
3811
3847
  method=mlrun.common.types.HTTPMethod.PATCH,
3812
- path=f"projects/{project}/model-monitoring/model-monitoring-controller",
3848
+ path=f"projects/{project}/model-monitoring/controller",
3813
3849
  params={
3814
3850
  "base_period": base_period,
3815
3851
  "image": image,
@@ -3845,8 +3881,8 @@ class HTTPRunDB(RunDBInterface):
3845
3881
 
3846
3882
  """
3847
3883
  self.api_call(
3848
- method=mlrun.common.types.HTTPMethod.POST,
3849
- path=f"projects/{project}/model-monitoring/enable-model-monitoring",
3884
+ method=mlrun.common.types.HTTPMethod.PUT,
3885
+ path=f"projects/{project}/model-monitoring/",
3850
3886
  params={
3851
3887
  "base_period": base_period,
3852
3888
  "image": image,
@@ -3890,7 +3926,7 @@ class HTTPRunDB(RunDBInterface):
3890
3926
  """
3891
3927
  response = self.api_call(
3892
3928
  method=mlrun.common.types.HTTPMethod.DELETE,
3893
- path=f"projects/{project}/model-monitoring/disable-model-monitoring",
3929
+ path=f"projects/{project}/model-monitoring/",
3894
3930
  params={
3895
3931
  "delete_resources": delete_resources,
3896
3932
  "delete_stream_function": delete_stream_function,
@@ -3973,8 +4009,8 @@ class HTTPRunDB(RunDBInterface):
3973
4009
  :param image: The image on which the application will run.
3974
4010
  """
3975
4011
  self.api_call(
3976
- method=mlrun.common.types.HTTPMethod.POST,
3977
- path=f"projects/{project}/model-monitoring/deploy-histogram-data-drift-app",
4012
+ method=mlrun.common.types.HTTPMethod.PUT,
4013
+ path=f"projects/{project}/model-monitoring/histogram-data-drift-app",
3978
4014
  params={"image": image},
3979
4015
  )
3980
4016
 
@@ -3992,8 +4028,8 @@ class HTTPRunDB(RunDBInterface):
3992
4028
  :param replace_creds: If True, will override the existing credentials.
3993
4029
  """
3994
4030
  self.api_call(
3995
- method=mlrun.common.types.HTTPMethod.POST,
3996
- path=f"projects/{project}/model-monitoring/set-model-monitoring-credentials",
4031
+ method=mlrun.common.types.HTTPMethod.PUT,
4032
+ path=f"projects/{project}/model-monitoring/credentials",
3997
4033
  params={**credentials, "replace_creds": replace_creds},
3998
4034
  )
3999
4035
 
mlrun/db/nopdb.py CHANGED
@@ -20,6 +20,7 @@ import mlrun.alerts
20
20
  import mlrun.common.formatters
21
21
  import mlrun.common.runtimes.constants
22
22
  import mlrun.common.schemas
23
+ import mlrun.common.schemas.model_monitoring.constants as mm_constants
23
24
  import mlrun.errors
24
25
  import mlrun.lists
25
26
  import mlrun.model_monitoring
@@ -75,6 +76,14 @@ class NopDB(RunDBInterface):
75
76
  def abort_run(self, uid, project="", iter=0, timeout=45, status_text=""):
76
77
  pass
77
78
 
79
+ def push_run_notifications(
80
+ self,
81
+ uid,
82
+ project="",
83
+ timeout=45,
84
+ ):
85
+ pass
86
+
78
87
  def list_runtime_resources(
79
88
  self,
80
89
  project: Optional[str] = None,
@@ -575,7 +584,9 @@ class NopDB(RunDBInterface):
575
584
  def create_model_endpoint(
576
585
  self,
577
586
  model_endpoint: mlrun.common.schemas.ModelEndpoint,
578
- creation_strategy: mlrun.common.schemas.ModelEndpointCreationStrategy = "inplace",
587
+ creation_strategy: Optional[
588
+ mm_constants.ModelEndpointCreationStrategy
589
+ ] = mm_constants.ModelEndpointCreationStrategy.INPLACE,
579
590
  ) -> mlrun.common.schemas.ModelEndpoint:
580
591
  pass
581
592