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.
- mlrun/artifacts/document.py +32 -6
- mlrun/common/formatters/artifact.py +1 -1
- mlrun/common/schemas/partition.py +23 -18
- mlrun/common/types.py +1 -0
- mlrun/config.py +3 -2
- mlrun/datastore/vectorstore.py +69 -26
- mlrun/db/base.py +21 -1
- mlrun/db/httpdb.py +53 -17
- mlrun/db/nopdb.py +12 -1
- mlrun/execution.py +43 -11
- mlrun/model_monitoring/applications/_application_steps.py +1 -1
- mlrun/model_monitoring/applications/base.py +2 -3
- mlrun/model_monitoring/applications/context.py +94 -71
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +0 -21
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +3 -3
- mlrun/projects/pipelines.py +13 -6
- mlrun/projects/project.py +80 -2
- mlrun/runtimes/nuclio/function.py +2 -1
- mlrun/runtimes/nuclio/serving.py +10 -5
- mlrun/serving/routers.py +16 -7
- mlrun/serving/states.py +14 -6
- mlrun/serving/v2_serving.py +11 -6
- mlrun/utils/helpers.py +23 -1
- mlrun/utils/notifications/notification/base.py +1 -1
- mlrun/utils/notifications/notification/webhook.py +13 -12
- mlrun/utils/notifications/notification_pusher.py +18 -23
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/METADATA +14 -8
- {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/RECORD +33 -33
- {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/LICENSE +0 -0
- {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/WHEEL +0 -0
- {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/entry_points.txt +0 -0
- {mlrun-1.8.0rc12.dist-info → mlrun-1.8.0rc15.dist-info}/top_level.txt +0 -0
mlrun/artifacts/document.py
CHANGED
|
@@ -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.
|
|
93
|
-
|
|
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
|
-
|
|
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) ->
|
|
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) ->
|
|
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
|
|
@@ -46,24 +46,23 @@ class PartitionInterval(StrEnum):
|
|
|
46
46
|
return timedelta(weeks=1)
|
|
47
47
|
|
|
48
48
|
@classmethod
|
|
49
|
-
def
|
|
49
|
+
def from_expression(cls, partition_expression: str):
|
|
50
50
|
"""
|
|
51
|
-
Returns the corresponding PartitionInterval for a given partition
|
|
51
|
+
Returns the corresponding PartitionInterval for a given partition expression,
|
|
52
52
|
or None if the function is not mapped.
|
|
53
53
|
|
|
54
|
-
:param
|
|
55
|
-
:return: PartitionInterval corresponding to the
|
|
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
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return cls
|
|
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(
|
|
126
|
-
|
|
127
|
-
|
|
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
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": "
|
|
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
|
|
mlrun/datastore/vectorstore.py
CHANGED
|
@@ -19,19 +19,42 @@ from typing import Optional, Union
|
|
|
19
19
|
from mlrun.artifacts import DocumentArtifact
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
def
|
|
23
|
-
#
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
110
|
-
DocumentArtifact.
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
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
|
-
|
|
253
|
+
self._collection_impl.delete(expr=expr)
|
|
211
254
|
elif store_class == "chroma":
|
|
212
255
|
where = {DocumentArtifact.METADATA_SOURCE_KEY: artifact.get_source()}
|
|
213
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
825
|
-
|
|
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:
|
|
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:
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
|
|
3595
|
-
|
|
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/
|
|
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.
|
|
3849
|
-
path=f"projects/{project}/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/
|
|
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.
|
|
3977
|
-
path=f"projects/{project}/model-monitoring/
|
|
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.
|
|
3996
|
-
path=f"projects/{project}/model-monitoring/
|
|
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:
|
|
587
|
+
creation_strategy: Optional[
|
|
588
|
+
mm_constants.ModelEndpointCreationStrategy
|
|
589
|
+
] = mm_constants.ModelEndpointCreationStrategy.INPLACE,
|
|
579
590
|
) -> mlrun.common.schemas.ModelEndpoint:
|
|
580
591
|
pass
|
|
581
592
|
|