mlrun 1.8.0rc16__py3-none-any.whl → 1.8.0rc18__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.

@@ -47,6 +47,7 @@ class DocumentLoaderSpec(ModelObj):
47
47
  self,
48
48
  loader_class_name: str = "langchain_community.document_loaders.TextLoader",
49
49
  src_name: str = "file_path",
50
+ download_object: bool = False,
50
51
  kwargs: Optional[dict] = None,
51
52
  ):
52
53
  """
@@ -56,7 +57,9 @@ class DocumentLoaderSpec(ModelObj):
56
57
  loader_class_name (str): The name of the loader class to use.
57
58
  src_name (str): The source name for the document.
58
59
  kwargs (Optional[dict]): Additional keyword arguments to pass to the loader class.
59
-
60
+ download_object (bool, optional): If True, the file will be downloaded before launching
61
+ the loader. If False, the loader accepts a link that should not be downloaded.
62
+ Defaults to False.
60
63
  Example:
61
64
  >>> # Create a loader specification for PDF documents
62
65
  >>> loader_spec = DocumentLoaderSpec(
@@ -72,6 +75,7 @@ class DocumentLoaderSpec(ModelObj):
72
75
  """
73
76
  self.loader_class_name = loader_class_name
74
77
  self.src_name = src_name
78
+ self.download_object = download_object
75
79
  self.kwargs = kwargs
76
80
 
77
81
  def make_loader(self, src_path):
@@ -251,6 +255,9 @@ class DocumentArtifact(Artifact):
251
255
  "collections",
252
256
  "original_source",
253
257
  ]
258
+ _exclude_fields_from_uid_hash = ArtifactSpec._exclude_fields_from_uid_hash + [
259
+ "collections",
260
+ ]
254
261
 
255
262
  def __init__(
256
263
  self,
@@ -270,7 +277,6 @@ class DocumentArtifact(Artifact):
270
277
  METADATA_SOURCE_KEY = "source"
271
278
  METADATA_ORIGINAL_SOURCE_KEY = "original_source"
272
279
  METADATA_CHUNK_KEY = "mlrun_chunk"
273
- METADATA_ARTIFACT_URI_KEY = "mlrun_object_uri"
274
280
  METADATA_ARTIFACT_TARGET_PATH_KEY = "mlrun_target_path"
275
281
  METADATA_ARTIFACT_TAG = "mlrun_tag"
276
282
  METADATA_ARTIFACT_KEY = "mlrun_key"
@@ -321,7 +327,7 @@ class DocumentArtifact(Artifact):
321
327
  """
322
328
 
323
329
  loader_spec = DocumentLoaderSpec.from_dict(self.spec.document_loader)
324
- if self.get_target_path():
330
+ if loader_spec.download_object and self.get_target_path():
325
331
  with tempfile.NamedTemporaryFile() as tmp_file:
326
332
  mlrun.datastore.store_manager.object(
327
333
  url=self.get_target_path()
@@ -348,7 +354,6 @@ class DocumentArtifact(Artifact):
348
354
 
349
355
  metadata[self.METADATA_ORIGINAL_SOURCE_KEY] = self.spec.original_source
350
356
  metadata[self.METADATA_SOURCE_KEY] = self.get_source()
351
- metadata[self.METADATA_ARTIFACT_URI_KEY] = self.uri
352
357
  metadata[self.METADATA_ARTIFACT_TAG] = self.tag or "latest"
353
358
  metadata[self.METADATA_ARTIFACT_KEY] = self.key
354
359
  metadata[self.METADATA_ARTIFACT_PROJECT] = self.metadata.project
@@ -38,12 +38,10 @@ def parse_model_endpoint_store_prefix(store_prefix: str):
38
38
 
39
39
  def parse_monitoring_stream_path(
40
40
  stream_uri: str, project: str, function_name: typing.Optional[str] = None
41
- ):
41
+ ) -> str:
42
42
  if stream_uri.startswith("kafka://"):
43
43
  if "?topic" in stream_uri:
44
- raise mlrun.errors.MLRunInvalidArgumentError(
45
- "Custom kafka topic is not allowed"
46
- )
44
+ raise mlrun.errors.MLRunValueError("Custom kafka topic is not allowed")
47
45
  # Add topic to stream kafka uri
48
46
  if (
49
47
  function_name is None
@@ -53,22 +51,6 @@ def parse_monitoring_stream_path(
53
51
  else:
54
52
  stream_uri += f"?topic=monitoring_stream_{project}_{function_name}"
55
53
 
56
- elif stream_uri.startswith("v3io://") and mlrun.mlconf.is_ce_mode():
57
- # V3IO is not supported in CE mode, generating a default http stream path
58
- if function_name is None:
59
- stream_uri = (
60
- mlrun.mlconf.model_endpoint_monitoring.default_http_sink.format(
61
- project=project, namespace=mlrun.mlconf.namespace
62
- )
63
- )
64
- else:
65
- stream_uri = (
66
- mlrun.mlconf.model_endpoint_monitoring.default_http_sink_app.format(
67
- project=project,
68
- application_name=function_name,
69
- namespace=mlrun.mlconf.namespace,
70
- )
71
- )
72
54
  return stream_uri
73
55
 
74
56
 
@@ -238,6 +238,7 @@ class ProjectSecretKeys:
238
238
  STREAM_PATH = "STREAM_PATH"
239
239
  TSDB_CONNECTION = "TSDB_CONNECTION"
240
240
  TSDB_PROFILE_NAME = "TSDB_PROFILE_NAME"
241
+ STREAM_PROFILE_NAME = "STREAM_PROFILE_NAME"
241
242
 
242
243
  @classmethod
243
244
  def mandatory_secrets(cls):
mlrun/config.py CHANGED
@@ -169,6 +169,7 @@ default_config = {
169
169
  "max_chunk_size": 1024 * 1024 * 1, # 1MB
170
170
  "max_preview_size": 1024 * 1024 * 10, # 10MB
171
171
  "max_download_size": 1024 * 1024 * 100, # 100MB
172
+ "max_deletions": 200,
172
173
  },
173
174
  },
174
175
  # FIXME: Adding these defaults here so we won't need to patch the "installing component" (provazio-controller) to
@@ -603,10 +604,6 @@ default_config = {
603
604
  # Offline storage path can be either relative or a full path. This path is used for general offline data
604
605
  # storage such as the parquet file which is generated from the monitoring stream function for the drift analysis
605
606
  "offline_storage_path": "model-endpoints/{kind}",
606
- # Default http path that points to the monitoring stream nuclio function. Will be used as a stream path
607
- # when the user is working in CE environment and has not provided any stream path.
608
- "default_http_sink": "http://nuclio-{project}-model-monitoring-stream.{namespace}.svc.cluster.local:8080",
609
- "default_http_sink_app": "http://nuclio-{project}-{application_name}.{namespace}.svc.cluster.local:8080",
610
607
  "parquet_batching_max_events": 10_000,
611
608
  "parquet_batching_timeout_secs": timedelta(minutes=1).total_seconds(),
612
609
  # See mlrun.model_monitoring.db.tsdb.ObjectTSDBFactory for available options
@@ -11,7 +11,7 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
- #
14
+
15
15
  import ast
16
16
  import base64
17
17
  import json
@@ -549,6 +549,35 @@ class DatastoreProfile2Json(pydantic.v1.BaseModel):
549
549
 
550
550
 
551
551
  def datastore_profile_read(url, project_name="", secrets: typing.Optional[dict] = None):
552
+ """
553
+ Read and retrieve a datastore profile from a given URL.
554
+
555
+ This function retrieves a datastore profile either from temporary client storage,
556
+ or from the MLRun database. It handles both client-side and server-side profile formats
557
+ and performs necessary conversions.
558
+
559
+ Args:
560
+ url (str): A URL with 'ds' scheme pointing to the datastore profile
561
+ (e.g., 'ds://profile-name').
562
+ project_name (str, optional): The project name where the profile is stored.
563
+ Defaults to MLRun's default project.
564
+ secrets (dict, optional): Dictionary containing secrets needed for profile retrieval.
565
+
566
+ Returns:
567
+ DatastoreProfile: The retrieved datastore profile object.
568
+
569
+ Raises:
570
+ MLRunInvalidArgumentError: In the following cases:
571
+ - If the URL scheme is not 'ds'
572
+ - If the profile cannot be retrieved from either server or local environment
573
+
574
+ Note:
575
+ When running from a client environment (outside MLRun pods), private profile information
576
+ is not accessible. In this case, use register_temporary_client_datastore_profile() to
577
+ register the profile with credentials for your local session. When running inside MLRun
578
+ pods, the private information is automatically available and no temporary registration is needed.
579
+ """
580
+
552
581
  parsed_url = urlparse(url)
553
582
  if parsed_url.scheme.lower() != "ds":
554
583
  raise mlrun.errors.MLRunInvalidArgumentError(
mlrun/db/base.py CHANGED
@@ -1079,7 +1079,7 @@ class RunDBInterface(ABC):
1079
1079
  def set_model_monitoring_credentials(
1080
1080
  self,
1081
1081
  project: str,
1082
- credentials: dict[str, str],
1082
+ credentials: dict[str, Optional[str]],
1083
1083
  replace_creds: bool,
1084
1084
  ) -> None:
1085
1085
  pass
mlrun/db/httpdb.py CHANGED
@@ -4018,7 +4018,7 @@ class HTTPRunDB(RunDBInterface):
4018
4018
  def set_model_monitoring_credentials(
4019
4019
  self,
4020
4020
  project: str,
4021
- credentials: dict[str, str],
4021
+ credentials: dict[str, Optional[str]],
4022
4022
  replace_creds: bool,
4023
4023
  ) -> None:
4024
4024
  """
mlrun/db/nopdb.py CHANGED
@@ -872,7 +872,7 @@ class NopDB(RunDBInterface):
872
872
  def set_model_monitoring_credentials(
873
873
  self,
874
874
  project: str,
875
- credentials: dict[str, str],
875
+ credentials: dict[str, Optional[str]],
876
876
  replace_creds: bool,
877
877
  ) -> None:
878
878
  pass
mlrun/execution.py CHANGED
@@ -884,6 +884,7 @@ class MLClientCtx:
884
884
  upload: Optional[bool] = False,
885
885
  labels: Optional[dict[str, str]] = None,
886
886
  target_path: Optional[str] = None,
887
+ db_key: Optional[str] = None,
887
888
  **kwargs,
888
889
  ) -> DocumentArtifact:
889
890
  """
@@ -914,6 +915,8 @@ class MLClientCtx:
914
915
  :param upload: Whether to upload the artifact
915
916
  :param labels: Key-value labels
916
917
  :param target_path: Path to the local file
918
+ :param db_key: The key to use in the artifact DB table, by default its run name + '_' + key
919
+ db_key=False will not register it in the artifacts table
917
920
  :param kwargs: Additional keyword arguments
918
921
  :return: DocumentArtifact object
919
922
 
@@ -943,6 +946,9 @@ class MLClientCtx:
943
946
  tag=tag,
944
947
  upload=upload,
945
948
  labels=labels,
949
+ local_path=local_path,
950
+ target_path=target_path,
951
+ db_key=db_key,
946
952
  )
947
953
  self._update_run()
948
954
  return item
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # for backwards compatibility
16
-
17
15
  from mlrun.common.schemas import ModelEndpoint, ModelEndpointList
18
16
 
19
17
  from .db import get_tsdb_connector
@@ -14,7 +14,8 @@
14
14
 
15
15
  import socket
16
16
  from abc import ABC, abstractmethod
17
- from datetime import datetime
17
+ from collections.abc import Iterator
18
+ from datetime import datetime, timedelta
18
19
  from typing import Any, Optional, Union, cast
19
20
 
20
21
  import pandas as pd
@@ -93,9 +94,10 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
93
94
  context: "mlrun.MLClientCtx",
94
95
  sample_data: Optional[pd.DataFrame] = None,
95
96
  reference_data: Optional[pd.DataFrame] = None,
96
- endpoint_names: Optional[list[str]] = None,
97
+ endpoints: Optional[list[tuple[str, str]]] = None,
97
98
  start: Optional[datetime] = None,
98
99
  end: Optional[datetime] = None,
100
+ base_period: Optional[int] = None,
99
101
  ):
100
102
  """
101
103
  A custom handler that wraps the application's logic implemented in
@@ -121,32 +123,60 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
121
123
  )
122
124
  return self.do_tracking(monitoring_context)
123
125
 
124
- if endpoint_names is not None:
125
- start, end = self._validate_times(start, end)
126
- for endpoint_name in endpoint_names:
127
- result = call_do_tracking(
128
- event={
129
- mm_constants.ApplicationEvent.ENDPOINT_NAME: endpoint_name,
130
- mm_constants.ApplicationEvent.START_INFER_TIME: start,
131
- mm_constants.ApplicationEvent.END_INFER_TIME: end,
132
- }
133
- )
134
- context.log_result(
135
- f"{endpoint_name}_{start.isoformat()}_{end.isoformat()}", result
136
- )
126
+ if endpoints is not None:
127
+ start, end = self._validate_times(start, end, base_period)
128
+ for window_start, window_end in self._window_generator(
129
+ start, end, base_period
130
+ ):
131
+ for endpoint_name, endpoint_id in endpoints:
132
+ result = call_do_tracking(
133
+ event={
134
+ mm_constants.ApplicationEvent.ENDPOINT_NAME: endpoint_name,
135
+ mm_constants.ApplicationEvent.ENDPOINT_ID: endpoint_id,
136
+ mm_constants.ApplicationEvent.START_INFER_TIME: window_start,
137
+ mm_constants.ApplicationEvent.END_INFER_TIME: window_end,
138
+ }
139
+ )
140
+ context.log_result(
141
+ f"{endpoint_name}_{window_start.isoformat()}_{window_end.isoformat()}",
142
+ result,
143
+ )
137
144
  else:
138
145
  return call_do_tracking()
139
146
 
140
147
  @staticmethod
141
148
  def _validate_times(
142
- start: Optional[datetime], end: Optional[datetime]
149
+ start: Optional[datetime],
150
+ end: Optional[datetime],
151
+ base_period: Optional[int],
143
152
  ) -> tuple[datetime, datetime]:
144
153
  if (start is None) or (end is None):
145
154
  raise mlrun.errors.MLRunValueError(
146
155
  "When `endpoint_names` is provided, you must also pass the start and end times"
147
156
  )
157
+ if (base_period is not None) and not (
158
+ isinstance(base_period, int) and base_period > 0
159
+ ):
160
+ raise mlrun.errors.MLRunValueError(
161
+ "`base_period` must be a nonnegative integer - the number of minutes in a monitoring window"
162
+ )
148
163
  return start, end
149
164
 
165
+ @staticmethod
166
+ def _window_generator(
167
+ start: datetime, end: datetime, base_period: Optional[int]
168
+ ) -> Iterator[tuple[datetime, datetime]]:
169
+ if base_period is None:
170
+ yield start, end
171
+ return
172
+
173
+ window_length = timedelta(minutes=base_period)
174
+ current_start_time = start
175
+ while current_start_time < end:
176
+ current_end_time = min(current_start_time + window_length, end)
177
+ yield current_start_time, current_end_time
178
+ current_start_time = current_end_time
179
+
150
180
  @classmethod
151
181
  def deploy(
152
182
  cls,
@@ -199,31 +229,39 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
199
229
  with_repo: Optional[bool] = False,
200
230
  requirements: Optional[Union[str, list[str]]] = None,
201
231
  requirements_file: str = "",
202
- endpoint_names: Optional[list[str]] = None,
232
+ endpoints: Optional[list[tuple[str, str]]] = None,
203
233
  start: Optional[datetime] = None,
204
234
  end: Optional[datetime] = None,
235
+ base_period: Optional[int] = None,
205
236
  ) -> "mlrun.RunObject":
206
237
  """
207
238
  Call this function to run the application's
208
239
  :py:meth:`~mlrun.model_monitoring.applications.ModelMonitoringApplicationBase.do_tracking`
209
240
  model monitoring logic as a :py:class:`~mlrun.runtimes.KubejobRuntime`, which is an MLRun function.
210
241
 
211
- :param func_path: The path to the function. If not passed, the current notebook is used.
212
- :param func_name: The name of the function. If not passed, the class name is used.
213
- :param tag: An optional tag for the function.
214
- :param run_local: Whether to run the function locally or remotely.
215
- :param sample_data: Optional - pandas data-frame as the current dataset.
242
+ This method has default values for all of its arguments. You should be change them when you want to pass
243
+ data to the application.
244
+
245
+ :param func_path: The path to the function. If ``None``, the current notebook is used.
246
+ :param func_name: The name of the function. If not ``None``, the class name is used.
247
+ :param tag: Tag for the function.
248
+ :param run_local: Whether to run the function locally or remotely.
249
+ :param sample_data: Pandas data-frame as the current dataset.
216
250
  When set, it replaces the data read from the model endpoint's offline source.
217
- :param reference_data: Optional - pandas data-frame of the reference dataset.
251
+ :param reference_data: Pandas data-frame of the reference dataset.
218
252
  When set, its statistics override the model endpoint's feature statistics.
219
253
  :param image: Docker image to run the job on.
220
254
  :param with_repo: Whether to clone the current repo to the build source.
221
255
  :param requirements: List of Python requirements to be installed in the image.
222
256
  :param requirements_file: Path to a Python requirements file to be installed in the image.
223
- :param endpoint_names: The model endpoint names to get the data from. When the names are passed,
224
- you have to provide also the start and end times of the data to analyze.
257
+ :param endpoints: A list of tuples of the model endpoint (name, uid) to get the data from.
258
+ If provided, you have to provide also the start and end times of the data to analyze.
225
259
  :param start: The start time of the sample data.
226
260
  :param end: The end time of the sample data.
261
+ :param base_period: The window length in minutes. If ``None``, the whole window from ``start`` to ``end``
262
+ is taken. If an integer is specified, the application is run from ``start`` to ``end``
263
+ in ``base_period`` length windows, except for the last window that ends at ``end`` and
264
+ therefore may be shorter.
227
265
 
228
266
  :returns: The output of the
229
267
  :py:meth:`~mlrun.model_monitoring.applications.ModelMonitoringApplicationBase.do_tracking`
@@ -249,12 +287,17 @@ class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
249
287
  ),
250
288
  )
251
289
 
252
- params: dict[str, Union[list[str], datetime]] = {}
253
- if endpoint_names:
254
- start, end = cls._validate_times(start, end)
255
- params["endpoint_names"] = endpoint_names
290
+ params: dict[str, Union[list[tuple[str, str]], datetime, int, None]] = {}
291
+ if endpoints:
292
+ start, end = cls._validate_times(start, end, base_period)
293
+ params["endpoints"] = endpoints
256
294
  params["start"] = start
257
295
  params["end"] = end
296
+ params["base_period"] = base_period
297
+ elif start or end or base_period:
298
+ raise mlrun.errors.MLRunValueError(
299
+ "Custom start and end times or base_period are supported only with endpoints data"
300
+ )
258
301
 
259
302
  inputs: dict[str, str] = {}
260
303
  for data, identifier in [
@@ -190,18 +190,13 @@ class MonitoringApplicationContext:
190
190
  )
191
191
 
192
192
  def _get_default_labels(self) -> dict[str, str]:
193
- labels = {
193
+ return {
194
194
  mlrun_constants.MLRunInternalLabels.runner_pod: socket.gethostname(),
195
195
  mlrun_constants.MLRunInternalLabels.producer_type: "model-monitoring-app",
196
196
  mlrun_constants.MLRunInternalLabels.app_name: self.application_name,
197
+ mlrun_constants.MLRunInternalLabels.endpoint_id: self.endpoint_id,
198
+ mlrun_constants.MLRunInternalLabels.endpoint_name: self.endpoint_name,
197
199
  }
198
- for key, value in [
199
- (mlrun_constants.MLRunInternalLabels.endpoint_id, self.endpoint_id),
200
- (mlrun_constants.MLRunInternalLabels.endpoint_name, self.endpoint_name),
201
- ]:
202
- if value:
203
- labels[key] = value
204
- return labels
205
200
 
206
201
  def _add_default_labels(self, labels: Optional[dict[str, str]]) -> dict[str, str]:
207
202
  """Add the default labels to logged artifacts labels"""
@@ -13,20 +13,14 @@
13
13
  # limitations under the License.
14
14
 
15
15
  import datetime
16
+ import functools
16
17
  import os
17
- import typing
18
+ from fnmatch import fnmatchcase
19
+ from typing import TYPE_CHECKING, Callable, Optional, TypedDict, cast
18
20
 
19
21
  import numpy as np
20
22
  import pandas as pd
21
23
 
22
- if typing.TYPE_CHECKING:
23
- from mlrun.datastore import DataItem
24
- from mlrun.db.base import RunDBInterface
25
- from mlrun.projects import MlrunProject
26
-
27
- from fnmatch import fnmatchcase
28
- from typing import Optional
29
-
30
24
  import mlrun
31
25
  import mlrun.artifacts
32
26
  import mlrun.common.model_monitoring.helpers
@@ -42,8 +36,13 @@ from mlrun.common.schemas.model_monitoring.model_endpoints import (
42
36
  )
43
37
  from mlrun.utils import logger
44
38
 
39
+ if TYPE_CHECKING:
40
+ from mlrun.datastore import DataItem
41
+ from mlrun.db.base import RunDBInterface
42
+ from mlrun.projects import MlrunProject
43
+
45
44
 
46
- class _BatchDict(typing.TypedDict):
45
+ class _BatchDict(TypedDict):
47
46
  minutes: int
48
47
  hours: int
49
48
  days: int
@@ -116,20 +115,30 @@ def filter_results_by_regex(
116
115
  def get_stream_path(
117
116
  project: str,
118
117
  function_name: str = mm_constants.MonitoringFunctionNames.STREAM,
119
- stream_uri: typing.Optional[str] = None,
118
+ stream_uri: Optional[str] = None,
119
+ secret_provider: Optional[Callable[[str], str]] = None,
120
120
  ) -> str:
121
121
  """
122
122
  Get stream path from the project secret. If wasn't set, take it from the system configurations
123
123
 
124
124
  :param project: Project name.
125
125
  :param function_name: Application name. Default is model_monitoring_stream.
126
- :param stream_uri: Stream URI. If provided, it will be used instead of the one from the project secret.
127
-
126
+ :param stream_uri: Stream URI. If provided, it will be used instead of the one from the project's secret.
127
+ :param secret_provider: Optional secret provider to get the connection string secret.
128
+ If not set, the env vars are used.
128
129
  :return: Monitoring stream path to the relevant application.
129
130
  """
130
131
 
132
+ try:
133
+ profile = _get_stream_profile(project=project, secret_provider=secret_provider)
134
+ except mlrun.errors.MLRunNotFoundError:
135
+ profile = None
136
+
137
+ if isinstance(profile, mlrun.datastore.datastore_profile.DatastoreProfileV3io):
138
+ stream_uri = "v3io"
139
+
131
140
  stream_uri = stream_uri or mlrun.get_secret_or_env(
132
- mm_constants.ProjectSecretKeys.STREAM_PATH
141
+ key=mm_constants.ProjectSecretKeys.STREAM_PATH, secret_provider=secret_provider
133
142
  )
134
143
 
135
144
  if not stream_uri or stream_uri == "v3io":
@@ -231,7 +240,7 @@ def get_monitoring_drift_measures_data(project: str, endpoint_id: str) -> "DataI
231
240
 
232
241
 
233
242
  def get_tsdb_connection_string(
234
- secret_provider: typing.Optional[typing.Callable[[str], str]] = None,
243
+ secret_provider: Optional[Callable[[str], str]] = None,
235
244
  ) -> str:
236
245
  """Get TSDB connection string from the project secret. If wasn't set, take it from the system
237
246
  configurations.
@@ -245,29 +254,40 @@ def get_tsdb_connection_string(
245
254
  )
246
255
 
247
256
 
248
- def _get_tsdb_profile(
249
- project: str = "",
250
- secret_provider: typing.Optional[typing.Callable[[str], str]] = None,
257
+ def _get_profile(
258
+ project: str,
259
+ secret_provider: Optional[Callable[[str], str]],
260
+ profile_name_key: str,
251
261
  ) -> mlrun.datastore.datastore_profile.DatastoreProfile:
252
262
  """
253
- Get TSDB datastore profile the project name and secret provider.
263
+ Get the datastore profile from the project name and secret provider, where the profile's name
264
+ is saved as a secret named `profile_name_key`.
254
265
 
255
- :param project: The project name. If not set, the default project name is used.
256
- :param secret_provider: Optional secret provider to get the connection string secret.
257
- If not set, the env vars are used.
258
- :return: TSDB datastore profile.
266
+ :param project: The project name.
267
+ :param secret_provider: Secret provider to get the secrets from, or `None` for env vars.
268
+ :param profile_name_key: The profile name key in the secret store.
269
+ :return: Datastore profile.
259
270
  """
260
271
  profile_name = mlrun.get_secret_or_env(
261
- key=mm_constants.ProjectSecretKeys.TSDB_PROFILE_NAME,
262
- secret_provider=secret_provider,
272
+ key=profile_name_key, secret_provider=secret_provider
263
273
  )
264
274
  if not profile_name:
265
- raise mlrun.errors.MLRunNotFoundError("Not found TSDB profile name")
275
+ raise mlrun.errors.MLRunNotFoundError(
276
+ f"Not found `{profile_name_key}` profile name"
277
+ )
266
278
  return mlrun.datastore.datastore_profile.datastore_profile_read(
267
279
  url=f"ds://{profile_name}", project_name=project, secrets=secret_provider
268
280
  )
269
281
 
270
282
 
283
+ _get_tsdb_profile = functools.partial(
284
+ _get_profile, profile_name_key=mm_constants.ProjectSecretKeys.TSDB_PROFILE_NAME
285
+ )
286
+ _get_stream_profile = functools.partial(
287
+ _get_profile, profile_name_key=mm_constants.ProjectSecretKeys.STREAM_PROFILE_NAME
288
+ )
289
+
290
+
271
291
  def batch_dict2timedelta(batch_dict: _BatchDict) -> datetime.timedelta:
272
292
  """
273
293
  Convert a batch dictionary to timedelta.
@@ -455,7 +475,7 @@ def get_invocations_metric(project: str) -> ModelEndpointMonitoringMetric:
455
475
 
456
476
 
457
477
  def _get_monitoring_schedules_folder_path(project: str) -> str:
458
- return typing.cast(
478
+ return cast(
459
479
  str,
460
480
  mlrun.mlconf.get_model_monitoring_file_target_path(
461
481
  project=project, kind=mm_constants.FileTargetKind.MONITORING_SCHEDULES
@@ -31,7 +31,6 @@ from mlrun.common.schemas.model_monitoring.constants import (
31
31
  WriterEvent,
32
32
  WriterEventKind,
33
33
  )
34
- from mlrun.common.schemas.notification import NotificationKind, NotificationSeverity
35
34
  from mlrun.model_monitoring.db._stats import (
36
35
  ModelMonitoringCurrentStatsFile,
37
36
  ModelMonitoringDriftMeasuresFile,
@@ -39,7 +38,6 @@ from mlrun.model_monitoring.db._stats import (
39
38
  from mlrun.model_monitoring.helpers import get_result_instance_fqn
40
39
  from mlrun.serving.utils import StepToDict
41
40
  from mlrun.utils import logger
42
- from mlrun.utils.notifications.notification_pusher import CustomNotificationPusher
43
41
 
44
42
  _RawEvent = dict[str, Any]
45
43
  _AppResultEvent = NewType("_AppResultEvent", _RawEvent)
@@ -57,50 +55,6 @@ class _WriterEventTypeError(_WriterEventError, TypeError):
57
55
  pass
58
56
 
59
57
 
60
- class _Notifier:
61
- def __init__(
62
- self,
63
- event: _AppResultEvent,
64
- notification_pusher: CustomNotificationPusher,
65
- severity: NotificationSeverity = NotificationSeverity.WARNING,
66
- ) -> None:
67
- """
68
- Event notifier - send push notification when appropriate to the notifiers in
69
- `notification pusher`.
70
- Note that if you use a Slack App webhook, you need to define it as an MLRun secret
71
- `SLACK_WEBHOOK`.
72
- """
73
- self._event = event
74
- self._custom_notifier = notification_pusher
75
- self._severity = severity
76
-
77
- def _should_send_event(self) -> bool:
78
- return self._event[ResultData.RESULT_STATUS] >= ResultStatusApp.detected.value
79
-
80
- def _generate_message(self) -> str:
81
- return f"""\
82
- The monitoring app `{self._event[WriterEvent.APPLICATION_NAME]}` \
83
- of kind `{self._event[ResultData.RESULT_KIND]}` \
84
- detected a problem in model endpoint ID `{self._event[WriterEvent.ENDPOINT_ID]}` \
85
- at time `{self._event[WriterEvent.START_INFER_TIME]}`.
86
-
87
- Result data:
88
- Name: `{self._event[ResultData.RESULT_NAME]}`
89
- Value: `{self._event[ResultData.RESULT_VALUE]}`
90
- Status: `{self._event[ResultData.RESULT_STATUS]}`
91
- Extra data: `{self._event[ResultData.RESULT_EXTRA_DATA]}`\
92
- """
93
-
94
- def notify(self) -> None:
95
- """Send notification if appropriate"""
96
- if not self._should_send_event():
97
- logger.debug("Not sending a notification")
98
- return
99
- message = self._generate_message()
100
- self._custom_notifier.push(message=message, severity=self._severity)
101
- logger.debug("A notification should have been sent")
102
-
103
-
104
58
  class ModelMonitoringWriter(StepToDict):
105
59
  """
106
60
  Write monitoring application results to the target databases
@@ -116,10 +70,6 @@ class ModelMonitoringWriter(StepToDict):
116
70
  self.project = project
117
71
  self.name = project # required for the deployment process
118
72
 
119
- self._custom_notifier = CustomNotificationPusher(
120
- notification_types=[NotificationKind.slack]
121
- )
122
-
123
73
  self._tsdb_connector = mlrun.model_monitoring.get_tsdb_connector(
124
74
  project=self.project, secret_provider=secret_provider
125
75
  )
@@ -250,9 +200,6 @@ class ModelMonitoringWriter(StepToDict):
250
200
 
251
201
  logger.info("Completed event DB writes")
252
202
 
253
- if kind == WriterEventKind.RESULT:
254
- _Notifier(event=event, notification_pusher=self._custom_notifier).notify()
255
-
256
203
  if (
257
204
  mlrun.mlconf.alerts.mode == mlrun.common.schemas.alert.AlertsModes.enabled
258
205
  and kind == WriterEventKind.RESULT
@@ -748,7 +748,8 @@ class _LocalRunner(_PipelineRunner):
748
748
  project.set_source(source=source)
749
749
  pipeline_context.workflow_artifact_path = artifact_path
750
750
 
751
- project.notifiers.push_pipeline_start_message(
751
+ # TODO: we should create endpoint for sending custom notification from BE
752
+ project.notifiers.push_pipeline_start_message_from_client(
752
753
  project.metadata.name, pipeline_id=workflow_id
753
754
  )
754
755
  err = None
mlrun/projects/project.py CHANGED
@@ -1962,6 +1962,11 @@ class MlrunProject(ModelObj):
1962
1962
  ... )
1963
1963
 
1964
1964
  """
1965
+ if not document_loader_spec.download_object and upload:
1966
+ raise ValueError(
1967
+ "This document loader expects direct links/URLs and does not support file uploads. "
1968
+ "Either set download_object=True or set upload=False"
1969
+ )
1965
1970
  doc_artifact = DocumentArtifact(
1966
1971
  key=key,
1967
1972
  original_source=local_path or target_path,
@@ -3603,17 +3608,29 @@ class MlrunProject(ModelObj):
3603
3608
  """
3604
3609
  db = mlrun.db.get_run_db(secrets=self._secrets)
3605
3610
  if tsdb_connection == "v3io":
3606
- profile = mlrun.datastore.datastore_profile.DatastoreProfileV3io(
3611
+ tsdb_profile = mlrun.datastore.datastore_profile.DatastoreProfileV3io(
3607
3612
  name="mm-infra-tsdb"
3608
3613
  )
3609
- self.register_datastore_profile(profile)
3614
+ self.register_datastore_profile(tsdb_profile)
3615
+ tsdb_profile_name = tsdb_profile.name
3616
+ else:
3617
+ tsdb_profile_name = None
3618
+ if stream_path == "v3io":
3619
+ stream_profile = mlrun.datastore.datastore_profile.DatastoreProfileV3io(
3620
+ name="mm-infra-stream"
3621
+ )
3622
+ self.register_datastore_profile(stream_profile)
3623
+ stream_profile_name = stream_profile.name
3624
+ else:
3625
+ stream_profile_name = None
3610
3626
  db.set_model_monitoring_credentials(
3611
3627
  project=self.name,
3612
3628
  credentials={
3613
3629
  "access_key": access_key,
3614
3630
  "stream_path": stream_path,
3615
3631
  "tsdb_connection": tsdb_connection,
3616
- "tsdb_profile_name": profile.name,
3632
+ "tsdb_profile_name": tsdb_profile_name,
3633
+ "stream_profile_name": stream_profile_name,
3617
3634
  },
3618
3635
  replace_creds=replace_creds,
3619
3636
  )
mlrun/serving/states.py CHANGED
@@ -126,6 +126,9 @@ class BaseStep(ModelObj):
126
126
  self.shape = shape
127
127
  self.on_error = None
128
128
  self._on_error_handler = None
129
+ self.model_endpoint_creation_strategy = (
130
+ schemas.ModelEndpointCreationStrategy.SKIP
131
+ )
129
132
 
130
133
  def get_shape(self):
131
134
  """graphviz shape"""
@@ -697,7 +700,7 @@ class RouterStep(TaskStep):
697
700
 
698
701
  kind = "router"
699
702
  default_shape = "doubleoctagon"
700
- _dict_fields = _task_step_fields + ["routes"]
703
+ _dict_fields = _task_step_fields + ["routes", "name"]
701
704
  _default_class = "mlrun.serving.ModelRouter"
702
705
 
703
706
  def __init__(
@@ -715,7 +718,7 @@ class RouterStep(TaskStep):
715
718
  class_name,
716
719
  class_args,
717
720
  handler,
718
- name=name,
721
+ name=get_name(name, class_name or RouterStep.kind),
719
722
  function=function,
720
723
  input_path=input_path,
721
724
  result_path=result_path,
@@ -1704,7 +1707,7 @@ def get_name(name, class_name):
1704
1707
  raise MLRunInvalidArgumentError("name or class_name must be provided")
1705
1708
  if isinstance(class_name, type):
1706
1709
  return class_name.__name__
1707
- return class_name
1710
+ return class_name.split(".")[-1]
1708
1711
 
1709
1712
 
1710
1713
  def params_to_step(
@@ -96,7 +96,7 @@ class V2ModelServer(StepToDict):
96
96
  self.name = name
97
97
  self.version = ""
98
98
  if name and ":" in name:
99
- self.name, self.version = name.split(":", 1)
99
+ self.version = name.split(":", 1)[-1]
100
100
  self.context = context
101
101
  self.ready = False
102
102
  self.error = ""
@@ -277,7 +277,7 @@ class V2ModelServer(StepToDict):
277
277
 
278
278
  response = {
279
279
  "id": event_id,
280
- "model_name": self.name,
280
+ "model_name": self.name.split(":")[0],
281
281
  "outputs": outputs,
282
282
  "timestamp": start.isoformat(sep=" ", timespec="microseconds"),
283
283
  }
@@ -308,7 +308,7 @@ class V2ModelServer(StepToDict):
308
308
  # get model metadata operation
309
309
  setattr(event, "terminated", True)
310
310
  event_body = {
311
- "name": self.name,
311
+ "name": self.name.split(":")[0],
312
312
  "version": self.version or "",
313
313
  "inputs": [],
314
314
  "outputs": [],
@@ -14,6 +14,7 @@
14
14
 
15
15
  import asyncio
16
16
  import datetime
17
+ import os
17
18
  import re
18
19
  import traceback
19
20
  import typing
@@ -30,6 +31,7 @@ import mlrun.model
30
31
  import mlrun.utils.helpers
31
32
  import mlrun.utils.notifications.notification as notification_module
32
33
  import mlrun.utils.notifications.notification.base as base
34
+ import mlrun_pipelines.common.constants
33
35
  import mlrun_pipelines.common.ops
34
36
  import mlrun_pipelines.models
35
37
  import mlrun_pipelines.utils
@@ -499,9 +501,9 @@ class NotificationPusher(_NotificationPusherBase):
499
501
  steps.append(function)
500
502
 
501
503
  step_methods = {
502
- mlrun_pipelines.common.ops.PipelineRunType.run: _add_run_step,
503
- mlrun_pipelines.common.ops.PipelineRunType.build: _add_deploy_function_step,
504
- mlrun_pipelines.common.ops.PipelineRunType.deploy: _add_deploy_function_step,
504
+ mlrun_pipelines.common.constants.PipelineRunType.run: _add_run_step,
505
+ mlrun_pipelines.common.constants.PipelineRunType.build: _add_deploy_function_step,
506
+ mlrun_pipelines.common.constants.PipelineRunType.deploy: _add_deploy_function_step,
505
507
  }
506
508
 
507
509
  workflow_id = run.status.results.get("workflow_id", None)
@@ -684,6 +686,34 @@ class CustomNotificationPusher(_NotificationPusherBase):
684
686
  db = mlrun.get_run_db()
685
687
  db.push_run_notifications(pipeline_id, project)
686
688
 
689
+ def push_pipeline_start_message_from_client(
690
+ self,
691
+ project: str,
692
+ commit_id: typing.Optional[str] = None,
693
+ pipeline_id: typing.Optional[str] = None,
694
+ has_workflow_url: bool = False,
695
+ ):
696
+ message = f"Workflow started in project {project}"
697
+ if pipeline_id:
698
+ message += f" id={pipeline_id}"
699
+ commit_id = (
700
+ commit_id or os.environ.get("GITHUB_SHA") or os.environ.get("CI_COMMIT_SHA")
701
+ )
702
+ if commit_id:
703
+ message += f", commit={commit_id}"
704
+ if has_workflow_url:
705
+ url = mlrun.utils.helpers.get_workflow_url(project, pipeline_id)
706
+ else:
707
+ url = mlrun.utils.helpers.get_ui_url(project)
708
+ html = ""
709
+ if url:
710
+ html = (
711
+ message
712
+ + f'<div><a href="{url}" target="_blank">click here to view progress</a></div>'
713
+ )
714
+ message = message + f", check progress in {url}"
715
+ self.push(message, "info", custom_html=html)
716
+
687
717
  def push_pipeline_run_results(
688
718
  self,
689
719
  runs: typing.Union[mlrun.lists.RunList, list],
@@ -1,4 +1,4 @@
1
1
  {
2
- "git_commit": "91e7d7fface3fc912eced8be04916b5e0628fda4",
3
- "version": "1.8.0-rc16"
2
+ "git_commit": "2d5cc0ee3dacf5d31a3b6a2158cd2e2b4a378b56",
3
+ "version": "1.8.0-rc18"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mlrun
3
- Version: 1.8.0rc16
3
+ Version: 1.8.0rc18
4
4
  Summary: Tracking and config of machine learning runs
5
5
  Home-page: https://github.com/mlrun/mlrun
6
6
  Author: Yaron Haviv
@@ -51,12 +51,10 @@ Requires-Dist: setuptools>=75.2
51
51
  Requires-Dist: deprecated~=1.2
52
52
  Requires-Dist: jinja2>=3.1.3,~=3.1
53
53
  Requires-Dist: orjson<4,>=3.9.15
54
- Requires-Dist: mlrun-pipelines-kfp-common~=0.3.3
55
- Requires-Dist: mlrun-pipelines-kfp-v1-8~=0.3.3; python_version < "3.11"
54
+ Requires-Dist: mlrun-pipelines-kfp-common~=0.3.5
55
+ Requires-Dist: mlrun-pipelines-kfp-v1-8~=0.3.5; python_version < "3.11"
56
56
  Requires-Dist: docstring_parser~=0.16
57
57
  Requires-Dist: aiosmtplib~=3.0
58
- Requires-Dist: grpcio-tools~=1.48.2; python_version < "3.11"
59
- Requires-Dist: grpcio~=1.48.2; python_version < "3.11"
60
58
  Provides-Extra: s3
61
59
  Requires-Dist: boto3<1.36,>=1.28.0; extra == "s3"
62
60
  Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "s3"
@@ -121,7 +119,7 @@ Requires-Dist: timelength~=1.1; extra == "api"
121
119
  Requires-Dist: memray~=1.12; sys_platform != "win32" and extra == "api"
122
120
  Requires-Dist: aiosmtplib~=3.0; extra == "api"
123
121
  Requires-Dist: pydantic<2,>=1; extra == "api"
124
- Requires-Dist: mlrun-pipelines-kfp-v1-8[kfp]~=0.3.3; python_version < "3.11" and extra == "api"
122
+ Requires-Dist: mlrun-pipelines-kfp-v1-8[kfp]~=0.3.5; python_version < "3.11" and extra == "api"
125
123
  Provides-Extra: all
126
124
  Requires-Dist: adlfs==2023.9.0; extra == "all"
127
125
  Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "all"
@@ -210,7 +208,7 @@ Requires-Dist: igz-mgmt~=0.4.1; extra == "complete-api"
210
208
  Requires-Dist: kafka-python~=2.0; extra == "complete-api"
211
209
  Requires-Dist: memray~=1.12; sys_platform != "win32" and extra == "complete-api"
212
210
  Requires-Dist: mlflow~=2.16; extra == "complete-api"
213
- Requires-Dist: mlrun-pipelines-kfp-v1-8[kfp]~=0.3.3; python_version < "3.11" and extra == "complete-api"
211
+ Requires-Dist: mlrun-pipelines-kfp-v1-8[kfp]~=0.3.5; python_version < "3.11" and extra == "complete-api"
214
212
  Requires-Dist: msrest~=0.6.21; extra == "complete-api"
215
213
  Requires-Dist: objgraph~=3.6; extra == "complete-api"
216
214
  Requires-Dist: oss2==2.18.1; extra == "complete-api"
@@ -1,8 +1,8 @@
1
1
  mlrun/__init__.py,sha256=7vuMpUiigXXDrghLRq680LKWy1faC0kQyGCZb_7cwyE,7473
2
2
  mlrun/__main__.py,sha256=o65gXHhmFA9GV_n2mqmAO80nW3MAwo_s7j80IKgCzRE,45949
3
- mlrun/config.py,sha256=cN_o0nSf7SJLi8xxg4kQ-_Kg5ZasUxA8IP6b-pyJJCc,71003
3
+ mlrun/config.py,sha256=jjjpcnTjmYPc5ptvetYMJ-BPWaOiQW1b9Phdh9A8wo0,70605
4
4
  mlrun/errors.py,sha256=5raKb1PXQpTcIvWQ4sr1qn2IS7P_GT_FydBJ0dXkVuc,8097
5
- mlrun/execution.py,sha256=sg3R6m5Vpg5VYMD-1B6-mpxW0ck6m9dmxN2fcGdJ3c8,48713
5
+ mlrun/execution.py,sha256=Up9U6xonTElRIaesF9Vej2JK1Isk2AZNK9ke0XcF5Dg,49030
6
6
  mlrun/features.py,sha256=ReBaNGsBYXqcbgI012n-SO_j6oHIbk_Vpv0CGPXbUmo,15842
7
7
  mlrun/k8s_utils.py,sha256=mRQMs6NzPq36vx1n5_2BfFapXysc8wv3NcrZ77_2ANA,8949
8
8
  mlrun/lists.py,sha256=1hFv3Iyu5DVX1kdBGJmwUoY0CqrzauhKdSq9g3piHb4,8442
@@ -16,7 +16,7 @@ mlrun/api/schemas/__init__.py,sha256=fEWH4I8hr5AdRJ7yoW44RlFB6NHkYDxyomP5J6ct1z4
16
16
  mlrun/artifacts/__init__.py,sha256=ofC2extBCOC1wg1YtdTzWzH3eeG_f-sFBUkHjYtZJpk,1175
17
17
  mlrun/artifacts/base.py,sha256=nz2ZqC74JGfWN0M6_hOXXQj3bXSTxNp4eUgvWHVcdvY,29979
18
18
  mlrun/artifacts/dataset.py,sha256=QTot5vCgLHatlIWwNnKbWdZ8HHTxaZ7wk4gWQDoqQ2k,16655
19
- mlrun/artifacts/document.py,sha256=1JrQWSuASF0EX5tKO4LXAI-gYdjPGJPXVhW1QzCmaME,15230
19
+ mlrun/artifacts/document.py,sha256=mbmos5LPkwOh0kHM0dFSi4RgbnPgfI3eMWiC4fk-ALI,15586
20
20
  mlrun/artifacts/manager.py,sha256=bXb70mKF6wIGs7syCiFfGnjalqx4g9bO_J5DaVzUUKw,16163
21
21
  mlrun/artifacts/model.py,sha256=jeOjUq_iZSHoNqlPyGgOz6acwje1Yqpg1yZwF9GbyG8,21615
22
22
  mlrun/artifacts/plots.py,sha256=dS0mHGt1b20tN2JyEH9H5o5I0oMKZkzn3Uz_3Hf4WjU,4813
@@ -37,7 +37,7 @@ mlrun/common/formatters/pipeline.py,sha256=oATD3znsuq3s7LipPnZivDPelTX0hJ0MFeeXO
37
37
  mlrun/common/formatters/project.py,sha256=0G4lhcTAsxQCxd40dKC4894cMH8nKt03BcGyp9wQO14,2102
38
38
  mlrun/common/formatters/run.py,sha256=Gcf9lVDqxPMNfWcPX0RJasjTC_N_U0yTBkQ02jOPJ7A,1062
39
39
  mlrun/common/model_monitoring/__init__.py,sha256=kXGBqhLN0rlAx0kTXhozGzFsIdSqW0uTSKMmsLgq_is,569
40
- mlrun/common/model_monitoring/helpers.py,sha256=fg56lF3ZP8d5v_vA5OFLAleFw83w35dWrkURYhOng00,3676
40
+ mlrun/common/model_monitoring/helpers.py,sha256=lV86teJYoE3MNDx4yhpbzO1KylWmvDbuNODw5yGZwgs,2943
41
41
  mlrun/common/runtimes/constants.py,sha256=Mok3m9Rv182TTMp7uYNfWalm9Xcz86yva-4fTxfMOPI,10988
42
42
  mlrun/common/schemas/__init__.py,sha256=PBuIAhXSkVEVxxKcv5hR_xvTwNAUqxOXHVPugOoWTyM,5386
43
43
  mlrun/common/schemas/alert.py,sha256=G9lFTXFYDor-RVLpJxMorIPlLWr_-GYCFKRN9DkKwXs,10124
@@ -72,7 +72,7 @@ mlrun/common/schemas/secret.py,sha256=CCxFYiPwJtDxwg2VVJH9nUG9cAZ2a34IjeuaWv-BYl
72
72
  mlrun/common/schemas/tag.py,sha256=HRZi5QZ4vVGaCr2AMk9eJgcNiAIXmH4YDc8a4fvF770,893
73
73
  mlrun/common/schemas/workflow.py,sha256=rwYzDJYxpE9k4kC88j_eUCmqK4ZsWV_h-_nli7Fs7Ow,2078
74
74
  mlrun/common/schemas/model_monitoring/__init__.py,sha256=noj7DPPia59PBWORsQZO20Ym0yhUwyoNJ3EeG8gVxlQ,1875
75
- mlrun/common/schemas/model_monitoring/constants.py,sha256=2U9TvO5vSJJYjzAaUys8PbdFOxhjwXZCdZ5oPuS3be0,11495
75
+ mlrun/common/schemas/model_monitoring/constants.py,sha256=VA1fEETbiyTKGiAG4WBSzo69Revd1_sgr8to6N0rp6U,11543
76
76
  mlrun/common/schemas/model_monitoring/grafana.py,sha256=Rq10KKOyyUYr7qOQFZfwGZtUim0LY9O0LQ5uc9jmIVQ,1562
77
77
  mlrun/common/schemas/model_monitoring/model_endpoints.py,sha256=GVWePSdaKyJm7-QdBiAQdMymlp2QgZIJwXO9EA6Q7AI,11727
78
78
  mlrun/data_types/__init__.py,sha256=unRo9GGwCmj0hBKBRsXJ2P4BzpQaddlQTvIrVQaKluI,984
@@ -85,7 +85,7 @@ mlrun/datastore/alibaba_oss.py,sha256=k-OHVe08HjMewlkpsT657CbOiVFAfSq9_EqhCE-k86
85
85
  mlrun/datastore/azure_blob.py,sha256=SzAcHYSXkm8Zpopz2Ea-rWVClH0URocUazcNK04S9W0,12776
86
86
  mlrun/datastore/base.py,sha256=Dqg8PqX0TFKHZg27Dgguc3RnQ1GABZiLf87p5ErTqJs,26448
87
87
  mlrun/datastore/datastore.py,sha256=frUYYP4i8ZmnY8GNXSgN_3x_exRgRPfxrCtAGEUifEU,9478
88
- mlrun/datastore/datastore_profile.py,sha256=7spsLLmlbilDurHqQoSmK7NxFWGshAc-D5v_KwwbStY,20877
88
+ mlrun/datastore/datastore_profile.py,sha256=QGL4cgnpNDGugIAKkSWldgFxZMMMOcFfXS-k95gwfwQ,22212
89
89
  mlrun/datastore/dbfs_store.py,sha256=QkDRzwFnvm7CgEg4NuGxes6tBgKDyhX0CiBUvK8c9pk,6568
90
90
  mlrun/datastore/filestore.py,sha256=OcykjzhbUAZ6_Cb9bGAXRL2ngsOpxXSb4rR0lyogZtM,3773
91
91
  mlrun/datastore/google_cloud_storage.py,sha256=MnToY6irdhBZ8Wcapqnr1Yq2724LAh2uPO7MAtdWfUY,8716
@@ -107,10 +107,10 @@ mlrun/datastore/wasbfs/__init__.py,sha256=s5Ul-0kAhYqFjKDR2X0O2vDGDbLQQduElb32Ev
107
107
  mlrun/datastore/wasbfs/fs.py,sha256=ge8NK__5vTcFT-krI155_8RDUywQw4SIRX6BWATXy9Q,6299
108
108
  mlrun/db/__init__.py,sha256=WqJ4x8lqJ7ZoKbhEyFqkYADd9P6E3citckx9e9ZLcIU,1163
109
109
  mlrun/db/auth_utils.py,sha256=hpg8D2r82oN0BWabuWN04BTNZ7jYMAF242YSUpK7LFM,5211
110
- mlrun/db/base.py,sha256=dzYvS8mUBShit9UBqgKuu4AJZHx8dQiD8ys7x7jAW90,29845
110
+ mlrun/db/base.py,sha256=ZCvjAN68L4kRZsytkuqqz4JTLROxczmbXjJwU1vaK8c,29855
111
111
  mlrun/db/factory.py,sha256=yP2vVmveUE7LYTCHbS6lQIxP9rW--zdISWuPd_I3d_4,2111
112
- mlrun/db/httpdb.py,sha256=MR-GOZGTpTf8jZ28DGvfDuarQ09nmgd2voaER8CuXpg,226131
113
- mlrun/db/nopdb.py,sha256=CUIhRHxfoSXSgBksOWki0piC-fWNgtQvtZdnmCvH46Y,26663
112
+ mlrun/db/httpdb.py,sha256=eGuQ05kwU8h_DbtuzlPo1aBMU4ZbfIsrRPWxiqb4v_Y,226141
113
+ mlrun/db/nopdb.py,sha256=v285LHP_Onfuo8KRF078IAPHIXTeEhQsU58QoY7x-b0,26673
114
114
  mlrun/feature_store/__init__.py,sha256=AVnY2AFUNc2dKxLLUMx2K3Wo1eGviv0brDcYlDnmtf4,1506
115
115
  mlrun/feature_store/api.py,sha256=qkojZpzqGAn3r9ww0ynBRKOs8ji8URaK4DSYD4SE-CE,50395
116
116
  mlrun/feature_store/common.py,sha256=Z7USI-d1fo0iwBMsqMBtJflJfyuiV3BLoDXQPSAoBAs,12826
@@ -215,18 +215,18 @@ mlrun/launcher/client.py,sha256=FXzQQqrSVE9oapLjjUYvx5qhZPG1r4ynUjUUFZVPekE,6228
215
215
  mlrun/launcher/factory.py,sha256=RW7mfzEFi8fR0M-4W1JQg1iq3_muUU6OTqT_3l4Ubrk,2338
216
216
  mlrun/launcher/local.py,sha256=9zNiuswHnSINDj4yYP2Vd192b5d4FUtSA8O2ICKjsKo,11279
217
217
  mlrun/launcher/remote.py,sha256=rLJW4UAnUT5iUb4BsGBOAV3K4R29a0X4lFtRkVKlyYU,7709
218
- mlrun/model_monitoring/__init__.py,sha256=RgXjrQSN7gZwo-URei3FNo3fE9wWlo1-wNhSVtNXbPA,784
218
+ mlrun/model_monitoring/__init__.py,sha256=ELy7njEtZnz09Dc6PGZSFFEGtnwI15bJNWM3Pj4_YIs,753
219
219
  mlrun/model_monitoring/api.py,sha256=nH5aEUkmUEJF0CurrWJxmxVv1tQed2yzCLhQByG1L00,28561
220
220
  mlrun/model_monitoring/controller.py,sha256=dBfZQswF67vqeUFnmgsm9jU_5sOs9dLwMPEiYHG-Kk8,19786
221
221
  mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
222
- mlrun/model_monitoring/helpers.py,sha256=L92YEzfKRWxoO8-qOsUK0Jrs86Wr8XDYfNnoeqnOZok,17106
222
+ mlrun/model_monitoring/helpers.py,sha256=Ul7-EHqzbf1GprB53Tf4WcbOHdD65sK3BgF2mpPYakg,17938
223
223
  mlrun/model_monitoring/stream_processing.py,sha256=ltCVgo_b3yay16CUbqeGkRfzCHZSn14lVeBng5m9keY,31738
224
224
  mlrun/model_monitoring/tracking_policy.py,sha256=PBIGrUYWrwcE5gwXupBIVzOb0QRRwPJsgQm_yLGQxB4,5595
225
- mlrun/model_monitoring/writer.py,sha256=-47Z7oMr6q2ieJunZgkMK8d0IHZJhC3jxTBIxHgtSOk,10490
225
+ mlrun/model_monitoring/writer.py,sha256=vbL7bqTyNu8q4bNcebX72sUMybVDAoTWg-CXq4fov3Y,8429
226
226
  mlrun/model_monitoring/applications/__init__.py,sha256=QYvzgCutFdAkzqKPD3mvkX_3c1X4tzd-kW8ojUOE9ic,889
227
227
  mlrun/model_monitoring/applications/_application_steps.py,sha256=NvrYJs6N0Kpp3s_t6s9LkCk5hY7kWYmkVoIhz_ZZx_8,7178
228
- mlrun/model_monitoring/applications/base.py,sha256=SLGGhxfeTfaLwLYFW9qLG9ZdoidrfGAFb3QO3xySRoI,12886
229
- mlrun/model_monitoring/applications/context.py,sha256=lbb0Kfh8cOOA382q2IYYQR6eDHsr-lbgxFMSQ9nUnqw,15209
228
+ mlrun/model_monitoring/applications/base.py,sha256=pqmZ67zaslIkcJlsjcUG6TWjbBTD_fYci6rlEvbFttc,15091
229
+ mlrun/model_monitoring/applications/context.py,sha256=kE_8h7eoUES_bFG2s7nENRziMFB72fJvAZ3KpIBWxOo,15084
230
230
  mlrun/model_monitoring/applications/evidently_base.py,sha256=hRjXuXf6xf8sbjGt9yYfGDUGnvS5rV3W7tkJroF3QJA,5098
231
231
  mlrun/model_monitoring/applications/histogram_data_drift.py,sha256=G26_4gQfcwDZe3S6SIZ4Uc_qyrHAJ6lDTFOQGkbfQR8,14455
232
232
  mlrun/model_monitoring/applications/results.py,sha256=oh1z9oacWWP4azVXm_Fx7j8uXSfdkB9T4mtGwyPBveE,5748
@@ -266,8 +266,8 @@ mlrun/platforms/__init__.py,sha256=ZuyeHCHHUxYEoZRmaJqzFSfwhaTyUdBZXMeVp75ql1w,3
266
266
  mlrun/platforms/iguazio.py,sha256=6VBTq8eQ3mzT96tzjYhAtcMQ2VjF4x8LpIPW5DAcX2Q,13749
267
267
  mlrun/projects/__init__.py,sha256=0Krf0WIKfnZa71WthYOg0SoaTodGg3sV_hK3f_OlTPI,1220
268
268
  mlrun/projects/operations.py,sha256=VXUlMrouFTls-I-bMhdN5pPfQ34TR7bFQ-NUSWNvl84,20029
269
- mlrun/projects/pipelines.py,sha256=SOlwMyyPO4jhV61Ja_4yco3OYzhijNQwyoq8g41fTe8,47343
270
- mlrun/projects/project.py,sha256=i_LukfblPoqylLcq73Uw02HDTqM_-npVVMq8Qv5_MWg,227431
269
+ mlrun/projects/pipelines.py,sha256=vZpyiERUzwPMS7NCC5ghI0KB_DItIddr7MMWGTwLawY,47437
270
+ mlrun/projects/project.py,sha256=fApkLLMJKPQi-Q69O-pZP5sh6eVsLmBt1KqZUFwcZoM,228225
271
271
  mlrun/runtimes/__init__.py,sha256=J9Sy2HiyMlztNv6VUurMzF5H2XzttNil8nRsWDsqLyg,8923
272
272
  mlrun/runtimes/base.py,sha256=Yt2l7srrXjK783cunBEKH0yQxQZRH8lkedXNOXuLbbo,37841
273
273
  mlrun/runtimes/daskjob.py,sha256=JwuGvOiPsxEDHHMMUS4Oie4hLlYYIZwihAl6DjroTY0,19521
@@ -303,10 +303,10 @@ mlrun/serving/remote.py,sha256=gxJkj_J3j-sZcVUbUzbAmJafP6t6y4NVFsu0kWmYngA,18818
303
303
  mlrun/serving/routers.py,sha256=A_R34_N6uYw2veK58WpffEp1NsFwq0XbNU9is2Nd7s8,50901
304
304
  mlrun/serving/server.py,sha256=xP88X7_C4mHIk0R7TJBCl-jSl-VomctblipiYepQTaQ,22512
305
305
  mlrun/serving/serving_wrapper.py,sha256=R670-S6PX_d5ER6jiHtRvacuPyFzQH0mEf2K0sBIIOM,836
306
- mlrun/serving/states.py,sha256=VjcP7GToyjH1PDGa1ASANKI1LWu-dgo_rXEVr5zsHxw,67386
306
+ mlrun/serving/states.py,sha256=g6UIeaS6B9v8k4eDMmOxyoB8Gdqm9PiNIkeuzDyTJA8,67565
307
307
  mlrun/serving/utils.py,sha256=k2EIYDWHUGkE-IBI6T0UNT32fw-KySsccIJM_LObI00,4171
308
308
  mlrun/serving/v1_serving.py,sha256=c6J_MtpE-Tqu00-6r4eJOCO6rUasHDal9W2eBIcrl50,11853
309
- mlrun/serving/v2_serving.py,sha256=ViPRigBwb58M6eeRvKa3JyVLd_OVEEtjPVSMRFZ1aPs,21861
309
+ mlrun/serving/v2_serving.py,sha256=B1Vmca2_YidXyit4wuxR6JGooMGdaeZI3Ja90JHCz10,21882
310
310
  mlrun/track/__init__.py,sha256=yVXbT52fXvGKRlc_ByHqIVt7-9L3DRE634RSeQwgXtU,665
311
311
  mlrun/track/tracker.py,sha256=CyTU6Qd3_5GGEJ_hpocOj71wvV65EuFYUjaYEUKAL6Q,3575
312
312
  mlrun/track/tracker_manager.py,sha256=IYBl99I62IC6VCCmG1yt6JoHNOQXa53C4DURJ2sWgio,5726
@@ -327,7 +327,7 @@ mlrun/utils/singleton.py,sha256=p1Y-X0mPSs_At092GS-pZCA8CTR62HOqPU07_ZH6-To,869
327
327
  mlrun/utils/v3io_clients.py,sha256=0aCFiQFBmgdSeLzJr_nEP6SG-zyieSgH8RdtcUq4dc0,1294
328
328
  mlrun/utils/vault.py,sha256=xUiKL17dCXjwQJ33YRzQj0oadUXATlFWPzKKYAESoQk,10447
329
329
  mlrun/utils/notifications/__init__.py,sha256=eUzQDBxSQmMZASRY-YAnYS6tL5801P0wEjycp3Dvoe0,990
330
- mlrun/utils/notifications/notification_pusher.py,sha256=tG1VfdygP2mYe1JkLszufPGeq4zkD27vSqvfMAVMh-M,28172
330
+ mlrun/utils/notifications/notification_pusher.py,sha256=Y30ZG8MDk0oxPPHPjqd9kDxQaOewTuE5uwZhxlM5V-s,29269
331
331
  mlrun/utils/notifications/notification/__init__.py,sha256=9Rfy6Jm8n0LaEDO1VAQb6kIbr7_uVuQhK1pS_abELIY,2581
332
332
  mlrun/utils/notifications/notification/base.py,sha256=VOgrzRakRfjYYBqvkc0cgEC5pl7KMidP7u-TL4HpGCY,5280
333
333
  mlrun/utils/notifications/notification/console.py,sha256=ICbIhOf9fEBJky_3j9TFiKAewDGyDHJr9l4VeT7G2sc,2745
@@ -337,11 +337,11 @@ mlrun/utils/notifications/notification/mail.py,sha256=ZyJ3eqd8simxffQmXzqd3bgbAq
337
337
  mlrun/utils/notifications/notification/slack.py,sha256=NKV4RFiY3gLsS8uPppgniPLyag8zJ9O1VhixoXkM7kw,7108
338
338
  mlrun/utils/notifications/notification/webhook.py,sha256=M-pSBM2VTKVUPRERocjORlH6mKqo1K9ihVL5Qrn2GyM,4789
339
339
  mlrun/utils/version/__init__.py,sha256=7kkrB7hEZ3cLXoWj1kPoDwo4MaswsI2JVOBpbKgPAgc,614
340
- mlrun/utils/version/version.json,sha256=6DN2cKENaaROp7hH2NZfzZAwPDExF5JEb1N0SAOWCvE,89
340
+ mlrun/utils/version/version.json,sha256=fuKq-DQzj4VU91pAfeQ6y9--Wzwya8hmUG1brhepAzQ,89
341
341
  mlrun/utils/version/version.py,sha256=eEW0tqIAkU9Xifxv8Z9_qsYnNhn3YH7NRAfM-pPLt1g,1878
342
- mlrun-1.8.0rc16.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
343
- mlrun-1.8.0rc16.dist-info/METADATA,sha256=L98gsrwODKowDqownhVjnIigGdHJPUF77HNjpzOj4oc,25001
344
- mlrun-1.8.0rc16.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
345
- mlrun-1.8.0rc16.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
346
- mlrun-1.8.0rc16.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
347
- mlrun-1.8.0rc16.dist-info/RECORD,,
342
+ mlrun-1.8.0rc18.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
343
+ mlrun-1.8.0rc18.dist-info/METADATA,sha256=LmjjU6uSheHxPOGP4V2giVzBleaHV45fl9bCB_xqyBo,24885
344
+ mlrun-1.8.0rc18.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
345
+ mlrun-1.8.0rc18.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
346
+ mlrun-1.8.0rc18.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
347
+ mlrun-1.8.0rc18.dist-info/RECORD,,