mlrun 1.8.0rc48__py3-none-any.whl → 1.8.0rc50__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/config.py +4 -0
- mlrun/datastore/sources.py +2 -7
- mlrun/model_monitoring/applications/context.py +34 -71
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +23 -2
- mlrun/model_monitoring/stream_processing.py +6 -6
- mlrun/runtimes/nuclio/function.py +3 -7
- mlrun/runtimes/nuclio/serving.py +3 -2
- mlrun/serving/states.py +6 -2
- mlrun/utils/helpers.py +76 -13
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.8.0rc48.dist-info → mlrun-1.8.0rc50.dist-info}/METADATA +6 -6
- {mlrun-1.8.0rc48.dist-info → mlrun-1.8.0rc50.dist-info}/RECORD +16 -16
- {mlrun-1.8.0rc48.dist-info → mlrun-1.8.0rc50.dist-info}/WHEEL +0 -0
- {mlrun-1.8.0rc48.dist-info → mlrun-1.8.0rc50.dist-info}/entry_points.txt +0 -0
- {mlrun-1.8.0rc48.dist-info → mlrun-1.8.0rc50.dist-info}/licenses/LICENSE +0 -0
- {mlrun-1.8.0rc48.dist-info → mlrun-1.8.0rc50.dist-info}/top_level.txt +0 -0
mlrun/config.py
CHANGED
|
@@ -486,6 +486,10 @@ default_config = {
|
|
|
486
486
|
"iguazio_client_job_cache_ttl": "20 minutes",
|
|
487
487
|
"nuclio_project_deletion_verification_timeout": "300 seconds",
|
|
488
488
|
"nuclio_project_deletion_verification_interval": "5 seconds",
|
|
489
|
+
"summaries": {
|
|
490
|
+
# Number of days back to include when calculating the project pipeline summary.
|
|
491
|
+
"list_pipelines_time_period_in_days": 7,
|
|
492
|
+
},
|
|
489
493
|
},
|
|
490
494
|
# The API needs to know what is its k8s svc url so it could enrich it in the jobs it creates
|
|
491
495
|
"api_url": "",
|
mlrun/datastore/sources.py
CHANGED
|
@@ -971,13 +971,8 @@ class OnlineSource(BaseSourceDriver):
|
|
|
971
971
|
def set_explicit_ack_mode(function: Function, **extra_arguments) -> dict[str, Any]:
|
|
972
972
|
extra_arguments = extra_arguments or {}
|
|
973
973
|
engine = "sync"
|
|
974
|
-
if (
|
|
975
|
-
function.spec
|
|
976
|
-
and hasattr(function.spec, "graph")
|
|
977
|
-
and function.spec.graph
|
|
978
|
-
and function.spec.graph.engine
|
|
979
|
-
):
|
|
980
|
-
engine = function.spec.graph.engine
|
|
974
|
+
if function.spec and hasattr(function.spec, "graph"):
|
|
975
|
+
engine = getattr(function.spec.graph, "engine", None) or engine
|
|
981
976
|
if mlrun.mlconf.is_explicit_ack_enabled() and engine == "async":
|
|
982
977
|
extra_arguments["explicit_ack_mode"] = extra_arguments.get(
|
|
983
978
|
"explicit_ack_mode", "explicitOnly"
|
|
@@ -23,12 +23,13 @@ import mlrun.common.constants as mlrun_constants
|
|
|
23
23
|
import mlrun.common.schemas.model_monitoring.constants as mm_constants
|
|
24
24
|
import mlrun.errors
|
|
25
25
|
import mlrun.feature_store as fstore
|
|
26
|
+
import mlrun.feature_store.feature_set as fs
|
|
26
27
|
import mlrun.features
|
|
27
28
|
import mlrun.serving
|
|
28
29
|
import mlrun.utils
|
|
29
30
|
from mlrun.artifacts import Artifact, DatasetArtifact, ModelArtifact, get_model
|
|
30
31
|
from mlrun.common.model_monitoring.helpers import FeatureStats
|
|
31
|
-
from mlrun.common.schemas import
|
|
32
|
+
from mlrun.common.schemas import ModelEndpoint
|
|
32
33
|
from mlrun.model_monitoring.helpers import (
|
|
33
34
|
calculate_inputs_statistics,
|
|
34
35
|
)
|
|
@@ -41,7 +42,6 @@ class _ArtifactsLogger(Protocol):
|
|
|
41
42
|
|
|
42
43
|
def log_artifact(self, *args, **kwargs) -> Artifact: ...
|
|
43
44
|
def log_dataset(self, *args, **kwargs) -> DatasetArtifact: ...
|
|
44
|
-
def log_model(self, *args, **kwargs) -> ModelArtifact: ...
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
class MonitoringApplicationContext:
|
|
@@ -59,7 +59,7 @@ class MonitoringApplicationContext:
|
|
|
59
59
|
model_endpoint_dict: Optional[dict[str, ModelEndpoint]] = None,
|
|
60
60
|
sample_df: Optional[pd.DataFrame] = None,
|
|
61
61
|
feature_stats: Optional[FeatureStats] = None,
|
|
62
|
-
feature_sets_dict: Optional[dict[str, FeatureSet]] = None,
|
|
62
|
+
feature_sets_dict: Optional[dict[str, fs.FeatureSet]] = None,
|
|
63
63
|
) -> None:
|
|
64
64
|
"""
|
|
65
65
|
The :code:`MonitoringApplicationContext` object holds all the relevant information for the
|
|
@@ -124,9 +124,13 @@ class MonitoringApplicationContext:
|
|
|
124
124
|
self._model_endpoint: Optional[ModelEndpoint] = (
|
|
125
125
|
model_endpoint_dict.get(self.endpoint_id) if model_endpoint_dict else None
|
|
126
126
|
)
|
|
127
|
-
self._feature_set: Optional[FeatureSet] = (
|
|
127
|
+
self._feature_set: Optional[fs.FeatureSet] = (
|
|
128
128
|
feature_sets_dict.get(self.endpoint_id) if feature_sets_dict else None
|
|
129
129
|
)
|
|
130
|
+
store, _, _ = mlrun.store_manager.get_or_create_store(
|
|
131
|
+
mlrun.mlconf.artifact_path
|
|
132
|
+
)
|
|
133
|
+
self.storage_options = store.get_storage_options()
|
|
130
134
|
|
|
131
135
|
@classmethod
|
|
132
136
|
def _from_ml_ctx(
|
|
@@ -169,7 +173,7 @@ class MonitoringApplicationContext:
|
|
|
169
173
|
model_endpoint_dict: Optional[dict[str, ModelEndpoint]] = None,
|
|
170
174
|
sample_df: Optional[pd.DataFrame] = None,
|
|
171
175
|
feature_stats: Optional[FeatureStats] = None,
|
|
172
|
-
feature_sets_dict: Optional[dict[str, FeatureSet]] = None,
|
|
176
|
+
feature_sets_dict: Optional[dict[str, fs.FeatureSet]] = None,
|
|
173
177
|
) -> "MonitoringApplicationContext":
|
|
174
178
|
nuclio_logger = graph_context.logger
|
|
175
179
|
artifacts_logger = graph_context.project_obj
|
|
@@ -192,13 +196,14 @@ class MonitoringApplicationContext:
|
|
|
192
196
|
)
|
|
193
197
|
|
|
194
198
|
def _get_default_labels(self) -> dict[str, str]:
|
|
195
|
-
|
|
199
|
+
labels = {
|
|
196
200
|
mlrun_constants.MLRunInternalLabels.runner_pod: socket.gethostname(),
|
|
197
201
|
mlrun_constants.MLRunInternalLabels.producer_type: "model-monitoring-app",
|
|
198
202
|
mlrun_constants.MLRunInternalLabels.app_name: self.application_name,
|
|
199
203
|
mlrun_constants.MLRunInternalLabels.endpoint_id: self.endpoint_id,
|
|
200
204
|
mlrun_constants.MLRunInternalLabels.endpoint_name: self.endpoint_name,
|
|
201
205
|
}
|
|
206
|
+
return {key: value for key, value in labels.items() if value is not None}
|
|
202
207
|
|
|
203
208
|
def _add_default_labels(self, labels: Optional[dict[str, str]]) -> dict[str, str]:
|
|
204
209
|
"""Add the default labels to logged artifacts labels"""
|
|
@@ -221,22 +226,13 @@ class MonitoringApplicationContext:
|
|
|
221
226
|
"You can either provide the sample dataframe directly, the model endpoint's details and times, "
|
|
222
227
|
"or adapt the application's logic to not access the sample dataframe."
|
|
223
228
|
)
|
|
224
|
-
|
|
225
|
-
features = [f"{feature_set.metadata.name}.*"]
|
|
226
|
-
vector = fstore.FeatureVector(
|
|
227
|
-
name=f"{self.endpoint_id}_vector",
|
|
228
|
-
features=features,
|
|
229
|
-
with_indexes=True,
|
|
230
|
-
)
|
|
231
|
-
vector.metadata.tag = self.application_name
|
|
232
|
-
vector.feature_set_objects = {feature_set.metadata.name: feature_set}
|
|
233
|
-
|
|
234
|
-
offline_response = vector.get_offline_features(
|
|
229
|
+
df = self.feature_set.to_dataframe(
|
|
235
230
|
start_time=self.start_infer_time,
|
|
236
231
|
end_time=self.end_infer_time,
|
|
237
|
-
|
|
232
|
+
time_column=mm_constants.EventFieldType.TIMESTAMP,
|
|
233
|
+
storage_options=self.storage_options,
|
|
238
234
|
)
|
|
239
|
-
self._sample_df =
|
|
235
|
+
self._sample_df = df.reset_index(drop=True)
|
|
240
236
|
return self._sample_df
|
|
241
237
|
|
|
242
238
|
@property
|
|
@@ -259,7 +255,7 @@ class MonitoringApplicationContext:
|
|
|
259
255
|
return self._model_endpoint
|
|
260
256
|
|
|
261
257
|
@property
|
|
262
|
-
def feature_set(self) -> FeatureSet:
|
|
258
|
+
def feature_set(self) -> fs.FeatureSet:
|
|
263
259
|
if not self._feature_set and self.model_endpoint:
|
|
264
260
|
self._feature_set = fstore.get_feature_set(
|
|
265
261
|
self.model_endpoint.spec.monitoring_feature_set_uri
|
|
@@ -329,13 +325,23 @@ class MonitoringApplicationContext:
|
|
|
329
325
|
upload: Optional[bool] = None,
|
|
330
326
|
labels: Optional[dict[str, str]] = None,
|
|
331
327
|
target_path: Optional[str] = None,
|
|
328
|
+
unique_per_endpoint: bool = True,
|
|
332
329
|
**kwargs,
|
|
333
330
|
) -> Artifact:
|
|
334
331
|
"""
|
|
335
332
|
Log an artifact.
|
|
336
333
|
See :func:`~mlrun.projects.MlrunProject.log_artifact` for the documentation.
|
|
334
|
+
:param unique_per_endpoint: by default True, we will log different artifact for each model endpoint,
|
|
335
|
+
set to False without changing item key will cause artifact override
|
|
337
336
|
"""
|
|
338
337
|
labels = self._add_default_labels(labels)
|
|
338
|
+
# By default, we want to log different artifact for each model endpoint
|
|
339
|
+
endpoint_id = labels.get(mlrun_constants.MLRunInternalLabels.endpoint_id, "")
|
|
340
|
+
if unique_per_endpoint and isinstance(item, str):
|
|
341
|
+
item = f"{item}-{endpoint_id}" if endpoint_id else item
|
|
342
|
+
elif unique_per_endpoint: # isinstance(item, Artifact) is True
|
|
343
|
+
item.key = f"{item.key}-{endpoint_id}" if endpoint_id else item.key
|
|
344
|
+
|
|
339
345
|
return self._artifacts_logger.log_artifact(
|
|
340
346
|
item,
|
|
341
347
|
body=body,
|
|
@@ -364,13 +370,21 @@ class MonitoringApplicationContext:
|
|
|
364
370
|
target_path="",
|
|
365
371
|
extra_data=None,
|
|
366
372
|
label_column: Optional[str] = None,
|
|
373
|
+
unique_per_endpoint: bool = True,
|
|
367
374
|
**kwargs,
|
|
368
375
|
) -> DatasetArtifact:
|
|
369
376
|
"""
|
|
370
377
|
Log a dataset artifact.
|
|
371
378
|
See :func:`~mlrun.projects.MlrunProject.log_dataset` for the documentation.
|
|
379
|
+
:param unique_per_endpoint: by default True, we will log different dataset for each model endpoint,
|
|
380
|
+
set to False without changing item key will cause dataset override
|
|
372
381
|
"""
|
|
373
382
|
labels = self._add_default_labels(labels)
|
|
383
|
+
# By default, we want to log different artifact for each model endpoint
|
|
384
|
+
endpoint_id = labels.get(mlrun_constants.MLRunInternalLabels.endpoint_id, "")
|
|
385
|
+
if unique_per_endpoint and isinstance(key, str):
|
|
386
|
+
key = f"{key}-{endpoint_id}" if endpoint_id else key
|
|
387
|
+
|
|
374
388
|
return self._artifacts_logger.log_dataset(
|
|
375
389
|
key,
|
|
376
390
|
df,
|
|
@@ -387,54 +401,3 @@ class MonitoringApplicationContext:
|
|
|
387
401
|
label_column=label_column,
|
|
388
402
|
**kwargs,
|
|
389
403
|
)
|
|
390
|
-
|
|
391
|
-
def log_model(
|
|
392
|
-
self,
|
|
393
|
-
key,
|
|
394
|
-
body=None,
|
|
395
|
-
framework="",
|
|
396
|
-
tag="",
|
|
397
|
-
model_dir=None,
|
|
398
|
-
model_file=None,
|
|
399
|
-
algorithm=None,
|
|
400
|
-
metrics=None,
|
|
401
|
-
parameters=None,
|
|
402
|
-
artifact_path=None,
|
|
403
|
-
upload=None,
|
|
404
|
-
labels=None,
|
|
405
|
-
inputs: Optional[list[mlrun.features.Feature]] = None,
|
|
406
|
-
outputs: Optional[list[mlrun.features.Feature]] = None,
|
|
407
|
-
feature_vector: Optional[str] = None,
|
|
408
|
-
feature_weights: Optional[list] = None,
|
|
409
|
-
training_set=None,
|
|
410
|
-
label_column=None,
|
|
411
|
-
extra_data=None,
|
|
412
|
-
**kwargs,
|
|
413
|
-
) -> ModelArtifact:
|
|
414
|
-
"""
|
|
415
|
-
Log a model artifact.
|
|
416
|
-
See :func:`~mlrun.projects.MlrunProject.log_model` for the documentation.
|
|
417
|
-
"""
|
|
418
|
-
labels = self._add_default_labels(labels)
|
|
419
|
-
return self._artifacts_logger.log_model(
|
|
420
|
-
key,
|
|
421
|
-
body=body,
|
|
422
|
-
framework=framework,
|
|
423
|
-
tag=tag,
|
|
424
|
-
model_dir=model_dir,
|
|
425
|
-
model_file=model_file,
|
|
426
|
-
algorithm=algorithm,
|
|
427
|
-
metrics=metrics,
|
|
428
|
-
parameters=parameters,
|
|
429
|
-
artifact_path=artifact_path,
|
|
430
|
-
upload=upload,
|
|
431
|
-
labels=labels,
|
|
432
|
-
inputs=inputs,
|
|
433
|
-
outputs=outputs,
|
|
434
|
-
feature_vector=feature_vector,
|
|
435
|
-
feature_weights=feature_weights,
|
|
436
|
-
training_set=training_set,
|
|
437
|
-
label_column=label_column,
|
|
438
|
-
extra_data=extra_data,
|
|
439
|
-
**kwargs,
|
|
440
|
-
)
|
|
@@ -11,10 +11,11 @@
|
|
|
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
|
import asyncio
|
|
15
16
|
from datetime import datetime, timedelta
|
|
16
17
|
from threading import Lock
|
|
17
|
-
from typing import Callable, Literal, Optional, Union
|
|
18
|
+
from typing import Callable, Final, Literal, Optional, Union
|
|
18
19
|
|
|
19
20
|
import pandas as pd
|
|
20
21
|
import taosws
|
|
@@ -24,6 +25,7 @@ from taoswswrap.tdengine_connection import (
|
|
|
24
25
|
)
|
|
25
26
|
|
|
26
27
|
import mlrun.common.schemas.model_monitoring as mm_schemas
|
|
28
|
+
import mlrun.common.types
|
|
27
29
|
import mlrun.model_monitoring.db.tsdb.tdengine.schemas as tdengine_schemas
|
|
28
30
|
import mlrun.model_monitoring.db.tsdb.tdengine.stream_graph_steps
|
|
29
31
|
from mlrun.datastore.datastore_profile import DatastoreProfile
|
|
@@ -35,6 +37,19 @@ _connection = None
|
|
|
35
37
|
_connection_lock = Lock()
|
|
36
38
|
|
|
37
39
|
|
|
40
|
+
class TDEngineTimestampPrecision(mlrun.common.types.StrEnum):
|
|
41
|
+
"""
|
|
42
|
+
The timestamp precision for the TDEngine database.
|
|
43
|
+
For more information, see:
|
|
44
|
+
https://docs.tdengine.com/tdengine-reference/sql-manual/data-types/#timestamp
|
|
45
|
+
https://docs.tdengine.com/tdengine-reference/sql-manual/manage-databases/#create-database
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
MILLISECOND = "ms" # TDEngine's default
|
|
49
|
+
MICROSECOND = "us" # MLRun's default
|
|
50
|
+
NANOSECOND = "ns"
|
|
51
|
+
|
|
52
|
+
|
|
38
53
|
class TDEngineConnector(TSDBConnector):
|
|
39
54
|
"""
|
|
40
55
|
Handles the TSDB operations when the TSDB connector is of type TDEngine.
|
|
@@ -47,12 +62,17 @@ class TDEngineConnector(TSDBConnector):
|
|
|
47
62
|
self,
|
|
48
63
|
project: str,
|
|
49
64
|
profile: DatastoreProfile,
|
|
65
|
+
timestamp_precision: TDEngineTimestampPrecision = TDEngineTimestampPrecision.MICROSECOND,
|
|
50
66
|
**kwargs,
|
|
51
67
|
):
|
|
52
68
|
super().__init__(project=project)
|
|
53
69
|
|
|
54
70
|
self._tdengine_connection_profile = profile
|
|
55
71
|
|
|
72
|
+
self._timestamp_precision: Final = ( # cannot be changed after initialization
|
|
73
|
+
timestamp_precision
|
|
74
|
+
)
|
|
75
|
+
|
|
56
76
|
self._init_super_tables()
|
|
57
77
|
|
|
58
78
|
self._run_directly = (
|
|
@@ -105,7 +125,7 @@ class TDEngineConnector(TSDBConnector):
|
|
|
105
125
|
"""Create the database if it does not exist."""
|
|
106
126
|
self.connection.prefix_statements = []
|
|
107
127
|
self.connection.run(
|
|
108
|
-
statements=f"CREATE DATABASE IF NOT EXISTS {self.database}",
|
|
128
|
+
statements=f"CREATE DATABASE IF NOT EXISTS {self.database} PRECISION '{self._timestamp_precision}'",
|
|
109
129
|
timeout=self._timeout,
|
|
110
130
|
retries=self._retries,
|
|
111
131
|
)
|
|
@@ -180,6 +200,7 @@ class TDEngineConnector(TSDBConnector):
|
|
|
180
200
|
columns=columns,
|
|
181
201
|
subtable=table_name,
|
|
182
202
|
values=event,
|
|
203
|
+
timestamp_precision=self._timestamp_precision,
|
|
183
204
|
)
|
|
184
205
|
|
|
185
206
|
self.connection.run(
|
|
@@ -15,8 +15,6 @@
|
|
|
15
15
|
import datetime
|
|
16
16
|
import typing
|
|
17
17
|
|
|
18
|
-
import storey
|
|
19
|
-
|
|
20
18
|
import mlrun
|
|
21
19
|
import mlrun.common.model_monitoring.helpers
|
|
22
20
|
import mlrun.feature_store as fstore
|
|
@@ -144,7 +142,7 @@ class EventStreamProcessor:
|
|
|
144
142
|
|
|
145
143
|
graph = typing.cast(
|
|
146
144
|
mlrun.serving.states.RootFlowStep,
|
|
147
|
-
fn.set_topology(mlrun.serving.states.StepKinds.flow),
|
|
145
|
+
fn.set_topology(mlrun.serving.states.StepKinds.flow, engine="async"),
|
|
148
146
|
)
|
|
149
147
|
|
|
150
148
|
# split the graph between event with error vs valid event
|
|
@@ -345,7 +343,8 @@ class ProcessEndpointEvent(mlrun.feature_store.steps.MapClass):
|
|
|
345
343
|
logger.debug(
|
|
346
344
|
"Skipped nop event inside of ProcessEndpointEvent", event=event
|
|
347
345
|
)
|
|
348
|
-
|
|
346
|
+
full_event.body = [event]
|
|
347
|
+
return full_event
|
|
349
348
|
# Getting model version and function uri from event
|
|
350
349
|
# and use them for retrieving the endpoint_id
|
|
351
350
|
function_uri = full_event.body.get(EventFieldType.FUNCTION_URI)
|
|
@@ -478,8 +477,9 @@ class ProcessEndpointEvent(mlrun.feature_store.steps.MapClass):
|
|
|
478
477
|
|
|
479
478
|
# Create a storey event object with list of events, based on endpoint_id which will be used
|
|
480
479
|
# in the upcoming steps
|
|
481
|
-
|
|
482
|
-
|
|
480
|
+
full_event.key = endpoint_id
|
|
481
|
+
full_event.body = events
|
|
482
|
+
return full_event
|
|
483
483
|
|
|
484
484
|
def resume_state(self, endpoint_id, endpoint_name):
|
|
485
485
|
# Make sure process is resumable, if process fails for any reason, be able to pick things up close to where we
|
|
@@ -577,13 +577,9 @@ class RemoteRuntime(KubeResource):
|
|
|
577
577
|
access_key = self._resolve_v3io_access_key()
|
|
578
578
|
engine = "sync"
|
|
579
579
|
explicit_ack_mode = kwargs.pop("explicit_ack_mode", None)
|
|
580
|
-
if (
|
|
581
|
-
self.spec
|
|
582
|
-
|
|
583
|
-
and self.spec.graph
|
|
584
|
-
and self.spec.graph.engine
|
|
585
|
-
):
|
|
586
|
-
engine = self.spec.graph.engine
|
|
580
|
+
if self.spec and hasattr(self.spec, "graph"):
|
|
581
|
+
engine = getattr(self.spec.graph, "engine", None) or engine
|
|
582
|
+
|
|
587
583
|
if mlrun.mlconf.is_explicit_ack_enabled() and engine == "async":
|
|
588
584
|
explicit_ack_mode = explicit_ack_mode or "explicitOnly"
|
|
589
585
|
|
mlrun/runtimes/nuclio/serving.py
CHANGED
|
@@ -271,7 +271,8 @@ class ServingRuntime(RemoteRuntime):
|
|
|
271
271
|
can specify special router class and router arguments
|
|
272
272
|
|
|
273
273
|
flow - workflow (DAG) with a chain of states
|
|
274
|
-
flow
|
|
274
|
+
flow supports both "sync" and "async" engines, with "async" being the default.
|
|
275
|
+
Branches are not allowed in sync mode.
|
|
275
276
|
when using async mode calling state.respond() will mark the state as the
|
|
276
277
|
one which generates the (REST) call response
|
|
277
278
|
|
|
@@ -300,7 +301,7 @@ class ServingRuntime(RemoteRuntime):
|
|
|
300
301
|
step = RouterStep(class_name=class_name, class_args=class_args)
|
|
301
302
|
self.spec.graph = step
|
|
302
303
|
elif topology == StepKinds.flow:
|
|
303
|
-
self.spec.graph = RootFlowStep(engine=engine)
|
|
304
|
+
self.spec.graph = RootFlowStep(engine=engine or "async")
|
|
304
305
|
else:
|
|
305
306
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
306
307
|
f"unsupported topology {topology}, use 'router' or 'flow'"
|
mlrun/serving/states.py
CHANGED
|
@@ -1833,7 +1833,7 @@ def params_to_step(
|
|
|
1833
1833
|
class_args = class_args or {}
|
|
1834
1834
|
|
|
1835
1835
|
if isinstance(class_name, QueueStep):
|
|
1836
|
-
if not name or class_name.name:
|
|
1836
|
+
if not (name or class_name.name):
|
|
1837
1837
|
raise MLRunInvalidArgumentError("queue name must be specified")
|
|
1838
1838
|
|
|
1839
1839
|
step = class_name
|
|
@@ -1854,7 +1854,11 @@ def params_to_step(
|
|
|
1854
1854
|
elif class_name and hasattr(class_name, "to_dict"):
|
|
1855
1855
|
struct = class_name.to_dict()
|
|
1856
1856
|
kind = struct.get("kind", StepKinds.task)
|
|
1857
|
-
name =
|
|
1857
|
+
name = (
|
|
1858
|
+
name
|
|
1859
|
+
or struct.get("name", struct.get("class_name"))
|
|
1860
|
+
or class_name.to_dict(["name"]).get("name")
|
|
1861
|
+
)
|
|
1858
1862
|
cls = classes_map.get(kind, RootFlowStep)
|
|
1859
1863
|
step = cls.from_dict(struct)
|
|
1860
1864
|
step.function = function
|
mlrun/utils/helpers.py
CHANGED
|
@@ -41,6 +41,7 @@ import inflection
|
|
|
41
41
|
import numpy as np
|
|
42
42
|
import packaging.version
|
|
43
43
|
import pandas
|
|
44
|
+
import pytz
|
|
44
45
|
import semver
|
|
45
46
|
import yaml
|
|
46
47
|
from dateutil import parser
|
|
@@ -1128,21 +1129,83 @@ def get_workflow_url(
|
|
|
1128
1129
|
return url
|
|
1129
1130
|
|
|
1130
1131
|
|
|
1131
|
-
def
|
|
1132
|
+
def get_kfp_list_runs_filter(
|
|
1133
|
+
project_name: Optional[str] = None,
|
|
1134
|
+
end_date: Optional[str] = None,
|
|
1135
|
+
start_date: Optional[str] = None,
|
|
1136
|
+
) -> str:
|
|
1132
1137
|
"""
|
|
1133
|
-
Generates a filter
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
+
Generates a filter for listing Kubeflow Pipelines (KFP) runs.
|
|
1139
|
+
|
|
1140
|
+
:param project_name: The name of the project. If "*", it won't filter by project.
|
|
1141
|
+
:param end_date: The latest creation date for filtering runs (ISO 8601 format).
|
|
1142
|
+
:param start_date: The earliest creation date for filtering runs (ISO 8601 format).
|
|
1143
|
+
:return: A JSON-formatted filter string for KFP.
|
|
1138
1144
|
"""
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1145
|
+
|
|
1146
|
+
# KFP filter operation codes
|
|
1147
|
+
kfp_less_than_or_equal_op = 7 # '<='
|
|
1148
|
+
kfp_greater_than_or_equal_op = 5 # '>='
|
|
1149
|
+
kfp_substring_op = 9 # Substring match
|
|
1150
|
+
|
|
1151
|
+
filters = {"predicates": []}
|
|
1152
|
+
|
|
1153
|
+
if end_date:
|
|
1154
|
+
filters["predicates"].append(
|
|
1155
|
+
{
|
|
1156
|
+
"key": "created_at",
|
|
1157
|
+
"op": kfp_less_than_or_equal_op,
|
|
1158
|
+
"timestamp_value": end_date,
|
|
1159
|
+
}
|
|
1160
|
+
)
|
|
1161
|
+
|
|
1162
|
+
if project_name and project_name != "*":
|
|
1163
|
+
filters["predicates"].append(
|
|
1164
|
+
{
|
|
1165
|
+
"key": "name",
|
|
1166
|
+
"op": kfp_substring_op,
|
|
1167
|
+
"string_value": project_name,
|
|
1168
|
+
}
|
|
1169
|
+
)
|
|
1170
|
+
if start_date:
|
|
1171
|
+
filters["predicates"].append(
|
|
1172
|
+
{
|
|
1173
|
+
"key": "created_at",
|
|
1174
|
+
"op": kfp_greater_than_or_equal_op,
|
|
1175
|
+
"timestamp_value": start_date,
|
|
1176
|
+
}
|
|
1177
|
+
)
|
|
1178
|
+
return json.dumps(filters)
|
|
1179
|
+
|
|
1180
|
+
|
|
1181
|
+
def validate_and_convert_date(date_input: str) -> str:
|
|
1182
|
+
"""
|
|
1183
|
+
Converts any recognizable date string into a standardized RFC 3339 format.
|
|
1184
|
+
:param date_input: A date string in a recognizable format.
|
|
1185
|
+
"""
|
|
1186
|
+
try:
|
|
1187
|
+
dt_object = parser.parse(date_input)
|
|
1188
|
+
if dt_object.tzinfo is not None:
|
|
1189
|
+
# Convert to UTC if it's in a different timezone
|
|
1190
|
+
dt_object = dt_object.astimezone(pytz.utc)
|
|
1191
|
+
else:
|
|
1192
|
+
# If no timezone info is present, assume it's in local time
|
|
1193
|
+
local_tz = pytz.timezone("UTC")
|
|
1194
|
+
dt_object = local_tz.localize(dt_object)
|
|
1195
|
+
|
|
1196
|
+
# Convert the datetime object to an RFC 3339-compliant string.
|
|
1197
|
+
# RFC 3339 requires timestamps to be in ISO 8601 format with a 'Z' suffix for UTC time.
|
|
1198
|
+
# The isoformat() method adds a "+00:00" suffix for UTC by default,
|
|
1199
|
+
# so we replace it with "Z" to ensure compliance.
|
|
1200
|
+
formatted_date = dt_object.isoformat().replace("+00:00", "Z")
|
|
1201
|
+
formatted_date = formatted_date.rstrip("Z") + "Z"
|
|
1202
|
+
|
|
1203
|
+
return formatted_date
|
|
1204
|
+
except (ValueError, OverflowError) as e:
|
|
1205
|
+
raise ValueError(
|
|
1206
|
+
f"Invalid date format: {date_input}."
|
|
1207
|
+
f" Date format must adhere to the RFC 3339 standard (e.g., 'YYYY-MM-DDTHH:MM:SSZ' for UTC)."
|
|
1208
|
+
) from e
|
|
1146
1209
|
|
|
1147
1210
|
|
|
1148
1211
|
def are_strings_in_exception_chain_messages(
|
mlrun/utils/version/version.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mlrun
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.0rc50
|
|
4
4
|
Summary: Tracking and config of machine learning runs
|
|
5
5
|
Home-page: https://github.com/mlrun/mlrun
|
|
6
6
|
Author: Yaron Haviv
|
|
@@ -44,7 +44,7 @@ Requires-Dist: semver~=3.0
|
|
|
44
44
|
Requires-Dist: dependency-injector~=4.41
|
|
45
45
|
Requires-Dist: fsspec<2024.7,>=2023.9.2
|
|
46
46
|
Requires-Dist: v3iofs~=0.1.17
|
|
47
|
-
Requires-Dist: storey~=1.8.
|
|
47
|
+
Requires-Dist: storey~=1.8.11
|
|
48
48
|
Requires-Dist: inflection~=0.5.0
|
|
49
49
|
Requires-Dist: python-dotenv~=1.0
|
|
50
50
|
Requires-Dist: setuptools>=75.2
|
|
@@ -99,7 +99,7 @@ Requires-Dist: ossfs==2023.12.0; extra == "alibaba-oss"
|
|
|
99
99
|
Requires-Dist: oss2==2.18.1; extra == "alibaba-oss"
|
|
100
100
|
Provides-Extra: tdengine
|
|
101
101
|
Requires-Dist: taos-ws-py==0.3.2; extra == "tdengine"
|
|
102
|
-
Requires-Dist: taoswswrap~=0.3.
|
|
102
|
+
Requires-Dist: taoswswrap~=0.3.5; extra == "tdengine"
|
|
103
103
|
Provides-Extra: snowflake
|
|
104
104
|
Requires-Dist: snowflake-connector-python~=3.7; extra == "snowflake"
|
|
105
105
|
Provides-Extra: kfp18
|
|
@@ -152,7 +152,7 @@ Requires-Dist: s3fs<2024.7,>=2023.9.2; extra == "all"
|
|
|
152
152
|
Requires-Dist: snowflake-connector-python~=3.7; extra == "all"
|
|
153
153
|
Requires-Dist: sqlalchemy~=1.4; extra == "all"
|
|
154
154
|
Requires-Dist: taos-ws-py==0.3.2; extra == "all"
|
|
155
|
-
Requires-Dist: taoswswrap~=0.3.
|
|
155
|
+
Requires-Dist: taoswswrap~=0.3.5; extra == "all"
|
|
156
156
|
Provides-Extra: complete
|
|
157
157
|
Requires-Dist: adlfs==2023.9.0; extra == "complete"
|
|
158
158
|
Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "complete"
|
|
@@ -184,7 +184,7 @@ Requires-Dist: s3fs<2024.7,>=2023.9.2; extra == "complete"
|
|
|
184
184
|
Requires-Dist: snowflake-connector-python~=3.7; extra == "complete"
|
|
185
185
|
Requires-Dist: sqlalchemy~=1.4; extra == "complete"
|
|
186
186
|
Requires-Dist: taos-ws-py==0.3.2; extra == "complete"
|
|
187
|
-
Requires-Dist: taoswswrap~=0.3.
|
|
187
|
+
Requires-Dist: taoswswrap~=0.3.5; extra == "complete"
|
|
188
188
|
Provides-Extra: complete-api
|
|
189
189
|
Requires-Dist: adlfs==2023.9.0; extra == "complete-api"
|
|
190
190
|
Requires-Dist: aiobotocore<2.16,>=2.5.0; extra == "complete-api"
|
|
@@ -229,7 +229,7 @@ Requires-Dist: s3fs<2024.7,>=2023.9.2; extra == "complete-api"
|
|
|
229
229
|
Requires-Dist: snowflake-connector-python~=3.7; extra == "complete-api"
|
|
230
230
|
Requires-Dist: sqlalchemy~=1.4; extra == "complete-api"
|
|
231
231
|
Requires-Dist: taos-ws-py==0.3.2; extra == "complete-api"
|
|
232
|
-
Requires-Dist: taoswswrap~=0.3.
|
|
232
|
+
Requires-Dist: taoswswrap~=0.3.5; extra == "complete-api"
|
|
233
233
|
Requires-Dist: timelength~=1.1; extra == "complete-api"
|
|
234
234
|
Requires-Dist: uvicorn~=0.32.1; extra == "complete-api"
|
|
235
235
|
Dynamic: author
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
mlrun/__init__.py,sha256=Cqm9U9eCEdLpMejhU2BEhubu0mHL71igJJIwYa738EA,7450
|
|
2
2
|
mlrun/__main__.py,sha256=0NDzPf9VFRO8KFfGgb8mkGUPIDS285aASV8Hbxs-ND0,45920
|
|
3
|
-
mlrun/config.py,sha256=
|
|
3
|
+
mlrun/config.py,sha256=yfG69T-Gnu3Nps2tq_xKHM6C4d7ok7ulhHDo-1mJrSk,72126
|
|
4
4
|
mlrun/errors.py,sha256=LkcbXTLANGdsgo2CRX2pdbyNmt--lMsjGv0XZMgP-Nc,8222
|
|
5
5
|
mlrun/execution.py,sha256=FUktsD3puSFjc3LZJU35b-OmFBrBPBNntViCLQVuwnk,50008
|
|
6
6
|
mlrun/features.py,sha256=ReBaNGsBYXqcbgI012n-SO_j6oHIbk_Vpv0CGPXbUmo,15842
|
|
@@ -95,7 +95,7 @@ mlrun/datastore/inmem.py,sha256=IsM83nn-3CqmGdLzim7i9ZmJwG6ZGhBZGN6_hszWZnE,2951
|
|
|
95
95
|
mlrun/datastore/redis.py,sha256=QeNMkSz3zQXiXZhFUZcEtViqqbUysGJditbqe5M-J48,5682
|
|
96
96
|
mlrun/datastore/s3.py,sha256=lD4Fs69rwMeISovZzOxRdz_z9FuffysTdjJA9ybdnLA,9262
|
|
97
97
|
mlrun/datastore/snowflake_utils.py,sha256=Wohvnlmq8j1d98RCaknll-iWdZZpSlCrKhUOEy0_-CA,1483
|
|
98
|
-
mlrun/datastore/sources.py,sha256=
|
|
98
|
+
mlrun/datastore/sources.py,sha256=juPTIDpxHxbRBoTMPEG1V-6bgR3E3ufCir-Dnq_SFyg,48975
|
|
99
99
|
mlrun/datastore/spark_udf.py,sha256=NnnB3DZxZb-rqpRy7b-NC7QWXuuqFn3XkBDc86tU4mQ,1498
|
|
100
100
|
mlrun/datastore/spark_utils.py,sha256=_AsVoU5Ix_-W7Gyq8io8V-2GTk0m8THJNDP3WGGaWJY,2865
|
|
101
101
|
mlrun/datastore/store_resources.py,sha256=PFOMrZ6KH6hBOb0PiO-cHx_kv0UpHu5P2t8_mrR-lS4,6842
|
|
@@ -222,13 +222,13 @@ mlrun/model_monitoring/api.py,sha256=LU58dzE4QZiMH23lgiqfI__3m2E3eEZP-DQe2ioUSwM
|
|
|
222
222
|
mlrun/model_monitoring/controller.py,sha256=m4Zx_NQ0C-A7WtjBoXnqBmS11RRtLvBaFgbFbIgrdVc,36847
|
|
223
223
|
mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
|
|
224
224
|
mlrun/model_monitoring/helpers.py,sha256=8QsoYRPOVSnR3Lcv99m4XYrp_cR6hSqBUflYSOkJmFQ,21019
|
|
225
|
-
mlrun/model_monitoring/stream_processing.py,sha256=
|
|
225
|
+
mlrun/model_monitoring/stream_processing.py,sha256=CEVcIFJ0jYvkIMu8hKsIH0HEkrn5l_NoHsxNLk72D5E,33583
|
|
226
226
|
mlrun/model_monitoring/tracking_policy.py,sha256=PBIGrUYWrwcE5gwXupBIVzOb0QRRwPJsgQm_yLGQxB4,5595
|
|
227
227
|
mlrun/model_monitoring/writer.py,sha256=ibbhvfSHb8Reqlb7RGFEAUNM4iTyK1gk8-2m46mP6VM,8428
|
|
228
228
|
mlrun/model_monitoring/applications/__init__.py,sha256=xDBxkBjl-whHSG_4t1mLkxiypLH-fzn8TmAW9Mjo2uI,759
|
|
229
229
|
mlrun/model_monitoring/applications/_application_steps.py,sha256=PxULZznKW66Oq-fKaraOAbsTuGnV0zgXh6_91wX3KUo,8367
|
|
230
230
|
mlrun/model_monitoring/applications/base.py,sha256=7XL12idItWkoE3CJ_48F6cwVx5pJH3bgfG92hb8LcN8,24872
|
|
231
|
-
mlrun/model_monitoring/applications/context.py,sha256=
|
|
231
|
+
mlrun/model_monitoring/applications/context.py,sha256=l7HculkdcrWbMLjy9tsxEhm-1X6zxJE5Blk-U7yc-5I,16449
|
|
232
232
|
mlrun/model_monitoring/applications/histogram_data_drift.py,sha256=09t0tfC35W0SeJA3fzN29pJiB6G-V_8GlcvULVq6H9Q,15179
|
|
233
233
|
mlrun/model_monitoring/applications/results.py,sha256=_qmj6TWT0SR2bi7gUyRKBU418eGgGoLW2_hTJ7S-ock,5782
|
|
234
234
|
mlrun/model_monitoring/applications/evidently/__init__.py,sha256=-DqdPnBSrjZhFvKOu_Ie3MiFvlur9sPTZpZ1u0_1AE8,690
|
|
@@ -242,7 +242,7 @@ mlrun/model_monitoring/db/tsdb/helpers.py,sha256=0oUXc4aUkYtP2SGP6jTb3uPPKImIUsV
|
|
|
242
242
|
mlrun/model_monitoring/db/tsdb/tdengine/__init__.py,sha256=vgBdsKaXUURKqIf3M0y4sRatmSVA4CQiJs7J5dcVBkQ,620
|
|
243
243
|
mlrun/model_monitoring/db/tsdb/tdengine/schemas.py,sha256=EslhaR65jfeNdD5Ibk-3Hb4e5r5qYPfHb9rTChX3sG0,12689
|
|
244
244
|
mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py,sha256=Uadj0UvAmln2MxDWod-kAzau1uNlqZh981rPhbUH_5M,2857
|
|
245
|
-
mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py,sha256=
|
|
245
|
+
mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py,sha256=rpE-RB5sqe5GAkd9MZB4JFzSP1skxs0loC5hhAkNgKk,38747
|
|
246
246
|
mlrun/model_monitoring/db/tsdb/v3io/__init__.py,sha256=aL3bfmQsUQ-sbvKGdNihFj8gLCK3mSys0qDcXtYOwgc,616
|
|
247
247
|
mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py,sha256=_-zo9relCDtjGgievxAcAP9gVN9nDWs8BzGtFwTjb9M,6284
|
|
248
248
|
mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=IzdThNwWMBWo0D0VzXV-WVvGg-z7Y9e8ke8_LYJTeVA,46214
|
|
@@ -292,9 +292,9 @@ mlrun/runtimes/mpijob/abstract.py,sha256=JGMjcJ4dvpJbctF6psU9UvYyNCutMxTMgBQeTlz
|
|
|
292
292
|
mlrun/runtimes/mpijob/v1.py,sha256=1XQZC7AIMGX_AQCbApcwpH8I7y39-v0v2O35MvxjXoo,3213
|
|
293
293
|
mlrun/runtimes/nuclio/__init__.py,sha256=gx1kizzKv8pGT5TNloN1js1hdbxqDw3rM90sLVYVffY,794
|
|
294
294
|
mlrun/runtimes/nuclio/api_gateway.py,sha256=vH9ClKVP4Mb24rvA67xPuAvAhX-gAv6vVtjVxyplhdc,26969
|
|
295
|
-
mlrun/runtimes/nuclio/function.py,sha256=
|
|
295
|
+
mlrun/runtimes/nuclio/function.py,sha256=8wzAFYCpSs0KoGPSN6DC19smSfYh8dVqDUhpicr8sJ0,54540
|
|
296
296
|
mlrun/runtimes/nuclio/nuclio.py,sha256=sLK8KdGO1LbftlL3HqPZlFOFTAAuxJACZCVl1c0Ha6E,2942
|
|
297
|
-
mlrun/runtimes/nuclio/serving.py,sha256=
|
|
297
|
+
mlrun/runtimes/nuclio/serving.py,sha256=d0nzPALUYXO4fKFFhxW3hY-_NU-ZhBLWXa2vWIetBRI,33434
|
|
298
298
|
mlrun/runtimes/nuclio/application/__init__.py,sha256=rRs5vasy_G9IyoTpYIjYDafGoL6ifFBKgBtsXn31Atw,614
|
|
299
299
|
mlrun/runtimes/nuclio/application/application.py,sha256=VPX-ruYQJ7-7yd5c2sWdF4U5JCGSS3kYjUfOgev6l_Y,29186
|
|
300
300
|
mlrun/runtimes/nuclio/application/reverse_proxy.go,sha256=lEHH74vr2PridIHp1Jkc_NjkrWb5b6zawRrNxHQhwGU,2913
|
|
@@ -306,7 +306,7 @@ mlrun/serving/remote.py,sha256=gxJkj_J3j-sZcVUbUzbAmJafP6t6y4NVFsu0kWmYngA,18818
|
|
|
306
306
|
mlrun/serving/routers.py,sha256=SY6AsaiSnh8ssXq8hQE2z9MYapOxFOFJBx9QomiZMO8,53915
|
|
307
307
|
mlrun/serving/server.py,sha256=KiNhW0nTV5STZPzR6kEAUFVzCCAX8qv0g9AoCopARrM,23429
|
|
308
308
|
mlrun/serving/serving_wrapper.py,sha256=R670-S6PX_d5ER6jiHtRvacuPyFzQH0mEf2K0sBIIOM,836
|
|
309
|
-
mlrun/serving/states.py,sha256=
|
|
309
|
+
mlrun/serving/states.py,sha256=Hh3FBoQbHoO4KiofHfSwi_aUx7mQ26iXpKijcGiDJ6c,73341
|
|
310
310
|
mlrun/serving/utils.py,sha256=k2EIYDWHUGkE-IBI6T0UNT32fw-KySsccIJM_LObI00,4171
|
|
311
311
|
mlrun/serving/v1_serving.py,sha256=c6J_MtpE-Tqu00-6r4eJOCO6rUasHDal9W2eBIcrl50,11853
|
|
312
312
|
mlrun/serving/v2_serving.py,sha256=b3C5Utv2_AOPrH_hPi3NarjNbAK3kRoeIfqMU4qNuUo,25362
|
|
@@ -321,7 +321,7 @@ mlrun/utils/azure_vault.py,sha256=IEFizrDGDbAaoWwDr1WoA88S_EZ0T--vjYtY-i0cvYQ,34
|
|
|
321
321
|
mlrun/utils/clones.py,sha256=yXOeuLtgIiKZdmjeKK0Z_vIrH19ds5JuoJaCeDjhwOo,7516
|
|
322
322
|
mlrun/utils/condition_evaluator.py,sha256=-nGfRmZzivn01rHTroiGY4rqEv8T1irMyhzxEei-sKc,1897
|
|
323
323
|
mlrun/utils/db.py,sha256=blQgkWMfFH9lcN4sgJQcPQgEETz2Dl_zwbVA0SslpFg,2186
|
|
324
|
-
mlrun/utils/helpers.py,sha256=
|
|
324
|
+
mlrun/utils/helpers.py,sha256=PY8MVhqWEB-aF1T31PaIMTYlxiw8_3ywI49QWk8frQQ,76587
|
|
325
325
|
mlrun/utils/http.py,sha256=t6FrXQstZm9xVVjxqIGiLzrwZNCR4CSienSOuVgNIcI,8706
|
|
326
326
|
mlrun/utils/logger.py,sha256=RG0m1rx6gfkJ-2C1r_p41MMpPiaDYqaYM2lYHDlNZEU,14767
|
|
327
327
|
mlrun/utils/regex.py,sha256=jbR7IiOp6OO0mg9Fl_cVZCpWb9fL9nTPONCUxCDNWXg,5201
|
|
@@ -340,11 +340,11 @@ mlrun/utils/notifications/notification/mail.py,sha256=ZyJ3eqd8simxffQmXzqd3bgbAq
|
|
|
340
340
|
mlrun/utils/notifications/notification/slack.py,sha256=eQvmctTh6wIG5xVOesLLV9S1-UUCu5UEQ9JIJOor3ts,7183
|
|
341
341
|
mlrun/utils/notifications/notification/webhook.py,sha256=NeyIMSBojjjTJaUHmPbxMByp34GxYkl1-16NqzU27fU,4943
|
|
342
342
|
mlrun/utils/version/__init__.py,sha256=7kkrB7hEZ3cLXoWj1kPoDwo4MaswsI2JVOBpbKgPAgc,614
|
|
343
|
-
mlrun/utils/version/version.json,sha256=
|
|
343
|
+
mlrun/utils/version/version.json,sha256=RjTCuRy3GfFmwMHEpX2EDiMuT-NVXkkSv3yDkLci76E,89
|
|
344
344
|
mlrun/utils/version/version.py,sha256=eEW0tqIAkU9Xifxv8Z9_qsYnNhn3YH7NRAfM-pPLt1g,1878
|
|
345
|
-
mlrun-1.8.
|
|
346
|
-
mlrun-1.8.
|
|
347
|
-
mlrun-1.8.
|
|
348
|
-
mlrun-1.8.
|
|
349
|
-
mlrun-1.8.
|
|
350
|
-
mlrun-1.8.
|
|
345
|
+
mlrun-1.8.0rc50.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
346
|
+
mlrun-1.8.0rc50.dist-info/METADATA,sha256=YlWNT5wCVmdArEFkjRbixRD0tAY-Kzaz54rgHYdQabY,26009
|
|
347
|
+
mlrun-1.8.0rc50.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
348
|
+
mlrun-1.8.0rc50.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
|
|
349
|
+
mlrun-1.8.0rc50.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
|
|
350
|
+
mlrun-1.8.0rc50.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|