mlrun 1.7.0rc35__py3-none-any.whl → 1.7.0rc36__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/common/schemas/api_gateway.py +1 -1
- mlrun/config.py +1 -0
- mlrun/datastore/spark_utils.py +30 -0
- mlrun/feature_store/api.py +19 -1
- mlrun/feature_store/steps.py +8 -0
- mlrun/model_monitoring/api.py +23 -6
- mlrun/model_monitoring/applications/_application_steps.py +4 -0
- mlrun/model_monitoring/applications/base.py +8 -0
- mlrun/model_monitoring/applications/evidently_base.py +23 -22
- mlrun/model_monitoring/controller.py +5 -1
- mlrun/model_monitoring/stream_processing.py +20 -0
- mlrun/runtimes/nuclio/api_gateway.py +1 -1
- mlrun/runtimes/utils.py +18 -0
- mlrun/serving/states.py +7 -2
- mlrun/serving/v2_serving.py +5 -2
- mlrun/utils/db.py +15 -0
- mlrun/utils/http.py +1 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc35.dist-info → mlrun-1.7.0rc36.dist-info}/METADATA +1 -1
- {mlrun-1.7.0rc35.dist-info → mlrun-1.7.0rc36.dist-info}/RECORD +24 -24
- {mlrun-1.7.0rc35.dist-info → mlrun-1.7.0rc36.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc35.dist-info → mlrun-1.7.0rc36.dist-info}/WHEEL +0 -0
- {mlrun-1.7.0rc35.dist-info → mlrun-1.7.0rc36.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc35.dist-info → mlrun-1.7.0rc36.dist-info}/top_level.txt +0 -0
mlrun/config.py
CHANGED
|
@@ -1166,6 +1166,7 @@ class Config:
|
|
|
1166
1166
|
)
|
|
1167
1167
|
elif kind == "stream": # return list for mlrun<1.6.3 BC
|
|
1168
1168
|
return [
|
|
1169
|
+
# TODO: remove the first stream in 1.9.0
|
|
1169
1170
|
mlrun.mlconf.model_endpoint_monitoring.store_prefixes.default.format(
|
|
1170
1171
|
project=project,
|
|
1171
1172
|
kind=kind,
|
mlrun/datastore/spark_utils.py
CHANGED
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
16
18
|
import mlrun
|
|
19
|
+
from mlrun.features import Entity
|
|
17
20
|
|
|
18
21
|
|
|
19
22
|
def spark_session_update_hadoop_options(session, spark_options) -> dict[str, str]:
|
|
@@ -35,3 +38,30 @@ def spark_session_update_hadoop_options(session, spark_options) -> dict[str, str
|
|
|
35
38
|
else:
|
|
36
39
|
non_hadoop_spark_options[key] = value
|
|
37
40
|
return non_hadoop_spark_options
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def check_special_columns_exists(
|
|
44
|
+
spark_df, entities: list[Union[Entity, str]], timestamp_key: str, label_column: str
|
|
45
|
+
):
|
|
46
|
+
columns = spark_df.columns
|
|
47
|
+
entities = entities or []
|
|
48
|
+
entities = [
|
|
49
|
+
entity.name if isinstance(entity, Entity) else entity for entity in entities
|
|
50
|
+
]
|
|
51
|
+
missing_entities = [entity for entity in entities if entity not in columns]
|
|
52
|
+
cases_message = "Please check the letter cases (uppercase or lowercase)"
|
|
53
|
+
if missing_entities:
|
|
54
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
55
|
+
f"There are missing entities from dataframe during ingestion. missing_entities: {missing_entities}."
|
|
56
|
+
f" {cases_message}"
|
|
57
|
+
)
|
|
58
|
+
if timestamp_key and timestamp_key not in columns:
|
|
59
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
60
|
+
f"timestamp_key is missing from dataframe during ingestion. timestamp_key: {timestamp_key}."
|
|
61
|
+
f" {cases_message}"
|
|
62
|
+
)
|
|
63
|
+
if label_column and label_column not in columns:
|
|
64
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
65
|
+
f"label_column is missing from dataframe during ingestion. label_column: {label_column}. "
|
|
66
|
+
f"{cases_message}"
|
|
67
|
+
)
|
mlrun/feature_store/api.py
CHANGED
|
@@ -1032,6 +1032,8 @@ def _ingest_with_spark(
|
|
|
1032
1032
|
try:
|
|
1033
1033
|
import pyspark.sql
|
|
1034
1034
|
|
|
1035
|
+
from mlrun.datastore.spark_utils import check_special_columns_exists
|
|
1036
|
+
|
|
1035
1037
|
if spark is None or spark is True:
|
|
1036
1038
|
# create spark context
|
|
1037
1039
|
|
|
@@ -1050,7 +1052,6 @@ def _ingest_with_spark(
|
|
|
1050
1052
|
created_spark_context = True
|
|
1051
1053
|
|
|
1052
1054
|
timestamp_key = featureset.spec.timestamp_key
|
|
1053
|
-
|
|
1054
1055
|
if isinstance(source, pd.DataFrame):
|
|
1055
1056
|
df = spark.createDataFrame(source)
|
|
1056
1057
|
elif isinstance(source, pyspark.sql.DataFrame):
|
|
@@ -1080,6 +1081,12 @@ def _ingest_with_spark(
|
|
|
1080
1081
|
target = get_target_driver(target, featureset)
|
|
1081
1082
|
target.set_resource(featureset)
|
|
1082
1083
|
if featureset.spec.passthrough and target.is_offline:
|
|
1084
|
+
check_special_columns_exists(
|
|
1085
|
+
spark_df=df,
|
|
1086
|
+
entities=featureset.spec.entities,
|
|
1087
|
+
timestamp_key=timestamp_key,
|
|
1088
|
+
label_column=featureset.spec.label_column,
|
|
1089
|
+
)
|
|
1083
1090
|
continue
|
|
1084
1091
|
spark_options = target.get_spark_options(
|
|
1085
1092
|
key_columns, timestamp_key, overwrite
|
|
@@ -1090,6 +1097,17 @@ def _ingest_with_spark(
|
|
|
1090
1097
|
df_to_write, key_columns, timestamp_key, spark_options
|
|
1091
1098
|
)
|
|
1092
1099
|
write_format = spark_options.pop("format", None)
|
|
1100
|
+
# We can get to this point if the column exists in different letter cases,
|
|
1101
|
+
# so PySpark will be able to read it, but we still have to raise an exception for it.
|
|
1102
|
+
|
|
1103
|
+
# This check is here and not in to_spark_df because in spark_merger we can have a target
|
|
1104
|
+
# that has different letter cases than the source, like in SnowflakeTarget.
|
|
1105
|
+
check_special_columns_exists(
|
|
1106
|
+
spark_df=df_to_write,
|
|
1107
|
+
entities=featureset.spec.entities,
|
|
1108
|
+
timestamp_key=timestamp_key,
|
|
1109
|
+
label_column=featureset.spec.label_column,
|
|
1110
|
+
)
|
|
1093
1111
|
if overwrite:
|
|
1094
1112
|
write_spark_dataframe_with_options(
|
|
1095
1113
|
spark_options, df_to_write, "overwrite", write_format=write_format
|
mlrun/feature_store/steps.py
CHANGED
|
@@ -743,3 +743,11 @@ class DropFeatures(StepToDict, MLRunStep):
|
|
|
743
743
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
744
744
|
f"DropFeatures can only drop features, not entities: {dropped_entities}"
|
|
745
745
|
)
|
|
746
|
+
if feature_set.spec.label_column in features:
|
|
747
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
748
|
+
f"DropFeatures can not drop label_column: {feature_set.spec.label_column}"
|
|
749
|
+
)
|
|
750
|
+
if feature_set.spec.timestamp_key in features:
|
|
751
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
752
|
+
f"DropFeatures can not drop timestamp_key: {feature_set.spec.timestamp_key}"
|
|
753
|
+
)
|
mlrun/model_monitoring/api.py
CHANGED
|
@@ -252,14 +252,31 @@ def _model_endpoint_validations(
|
|
|
252
252
|
In case of discrepancy between the provided `sample_set_statistics` and the
|
|
253
253
|
`model_endpoints.spec.feature_stats`, a warning will be presented to the user.
|
|
254
254
|
"""
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
255
|
+
|
|
256
|
+
# Model Path
|
|
257
|
+
if model_path:
|
|
258
|
+
# Generate the parsed model uri that is based on hash, key, iter, and tree
|
|
259
|
+
model_obj = mlrun.datastore.get_store_resource(model_path)
|
|
260
|
+
|
|
261
|
+
model_artifact_uri = mlrun.utils.helpers.generate_artifact_uri(
|
|
262
|
+
project=model_endpoint.metadata.project,
|
|
263
|
+
key=model_obj.key,
|
|
264
|
+
iter=model_obj.iter,
|
|
265
|
+
tree=model_obj.tree,
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Enrich the uri schema with the store prefix
|
|
269
|
+
model_artifact_uri = mlrun.datastore.get_store_uri(
|
|
270
|
+
kind=mlrun.utils.helpers.StorePrefix.Model, uri=model_artifact_uri
|
|
261
271
|
)
|
|
262
272
|
|
|
273
|
+
if model_endpoint.spec.model_uri != model_artifact_uri:
|
|
274
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
275
|
+
f"provided model store path {model_path} does not match "
|
|
276
|
+
f"the path that is stored under the existing model "
|
|
277
|
+
f"endpoint record: {model_endpoint.spec.model_uri}"
|
|
278
|
+
)
|
|
279
|
+
|
|
263
280
|
# Feature stats
|
|
264
281
|
if (
|
|
265
282
|
sample_set_statistics
|
|
@@ -19,6 +19,7 @@ import mlrun.common.helpers
|
|
|
19
19
|
import mlrun.common.model_monitoring.helpers
|
|
20
20
|
import mlrun.common.schemas.model_monitoring.constants as mm_constant
|
|
21
21
|
import mlrun.datastore
|
|
22
|
+
import mlrun.serving
|
|
22
23
|
import mlrun.utils.v3io_clients
|
|
23
24
|
from mlrun.model_monitoring.helpers import get_stream_path
|
|
24
25
|
from mlrun.serving.utils import StepToDict
|
|
@@ -151,6 +152,9 @@ class _PrepareMonitoringEvent(StepToDict):
|
|
|
151
152
|
def _create_mlrun_context(app_name: str):
|
|
152
153
|
context = mlrun.get_or_create_ctx(
|
|
153
154
|
f"{app_name}-logger",
|
|
155
|
+
spec={
|
|
156
|
+
"metadata": {"labels": {"kind": mlrun.runtimes.RuntimeKinds.serving}}
|
|
157
|
+
},
|
|
154
158
|
upload_artifacts=True,
|
|
155
159
|
)
|
|
156
160
|
context.__class__ = MonitoringApplicationContext
|
|
@@ -17,6 +17,7 @@ from typing import Any, Union, cast
|
|
|
17
17
|
|
|
18
18
|
import numpy as np
|
|
19
19
|
import pandas as pd
|
|
20
|
+
from deprecated import deprecated
|
|
20
21
|
|
|
21
22
|
import mlrun
|
|
22
23
|
import mlrun.model_monitoring.applications.context as mm_context
|
|
@@ -112,6 +113,13 @@ class ModelMonitoringApplicationBaseV2(MonitoringApplicationToDict, ABC):
|
|
|
112
113
|
raise NotImplementedError
|
|
113
114
|
|
|
114
115
|
|
|
116
|
+
# TODO: Remove in 1.9.0
|
|
117
|
+
@deprecated(
|
|
118
|
+
version="1.7.0",
|
|
119
|
+
reason="The `ModelMonitoringApplicationBase` class is deprecated from "
|
|
120
|
+
"version 1.7.0 and will be removed in version 1.9.0. "
|
|
121
|
+
"Use `ModelMonitoringApplicationBaseV2` as your application's base class.",
|
|
122
|
+
)
|
|
115
123
|
class ModelMonitoringApplicationBase(MonitoringApplicationToDict, ABC):
|
|
116
124
|
"""
|
|
117
125
|
A base class for a model monitoring application.
|
|
@@ -14,10 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
import uuid
|
|
16
16
|
import warnings
|
|
17
|
-
from
|
|
17
|
+
from abc import ABC
|
|
18
18
|
|
|
19
19
|
import pandas as pd
|
|
20
20
|
import semver
|
|
21
|
+
from deprecated import deprecated
|
|
21
22
|
|
|
22
23
|
import mlrun.model_monitoring.applications.base as mm_base
|
|
23
24
|
import mlrun.model_monitoring.applications.context as mm_context
|
|
@@ -57,14 +58,22 @@ except ModuleNotFoundError:
|
|
|
57
58
|
|
|
58
59
|
|
|
59
60
|
if _HAS_EVIDENTLY:
|
|
60
|
-
from evidently.
|
|
61
|
-
from evidently.suite.base_suite import Suite
|
|
61
|
+
from evidently.suite.base_suite import Display
|
|
62
62
|
from evidently.ui.type_aliases import STR_UUID
|
|
63
63
|
from evidently.ui.workspace import Workspace
|
|
64
64
|
from evidently.utils.dashboard import TemplateParams, file_html_template
|
|
65
65
|
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
# TODO: Remove in 1.9.0
|
|
68
|
+
@deprecated(
|
|
69
|
+
version="1.7.0",
|
|
70
|
+
reason="The `EvidentlyModelMonitoringApplicationBase` class is deprecated from "
|
|
71
|
+
"version 1.7.0 and will be removed in version 1.9.0. "
|
|
72
|
+
"Use `EvidentlyModelMonitoringApplicationBaseV2` as your application's base class.",
|
|
73
|
+
)
|
|
74
|
+
class EvidentlyModelMonitoringApplicationBase(
|
|
75
|
+
mm_base.ModelMonitoringApplicationBase, ABC
|
|
76
|
+
):
|
|
68
77
|
def __init__(
|
|
69
78
|
self, evidently_workspace_path: str, evidently_project_id: "STR_UUID"
|
|
70
79
|
) -> None:
|
|
@@ -86,12 +95,12 @@ class EvidentlyModelMonitoringApplicationBase(mm_base.ModelMonitoringApplication
|
|
|
86
95
|
)
|
|
87
96
|
|
|
88
97
|
def log_evidently_object(
|
|
89
|
-
self, evidently_object:
|
|
90
|
-
):
|
|
98
|
+
self, evidently_object: "Display", artifact_name: str
|
|
99
|
+
) -> None:
|
|
91
100
|
"""
|
|
92
101
|
Logs an Evidently report or suite as an artifact.
|
|
93
102
|
|
|
94
|
-
:param evidently_object: (
|
|
103
|
+
:param evidently_object: (Display) The Evidently display to log, e.g. a report or a test suite object.
|
|
95
104
|
:param artifact_name: (str) The name for the logged artifact.
|
|
96
105
|
"""
|
|
97
106
|
evidently_object_html = evidently_object.get_html()
|
|
@@ -122,18 +131,14 @@ class EvidentlyModelMonitoringApplicationBase(mm_base.ModelMonitoringApplication
|
|
|
122
131
|
additional_graphs={},
|
|
123
132
|
)
|
|
124
133
|
|
|
125
|
-
dashboard_html =
|
|
134
|
+
dashboard_html = file_html_template(params=template_params)
|
|
126
135
|
self.context.log_artifact(
|
|
127
136
|
artifact_name, body=dashboard_html.encode("utf-8"), format="html"
|
|
128
137
|
)
|
|
129
138
|
|
|
130
|
-
@staticmethod
|
|
131
|
-
def _render(temple_func, template_params: "TemplateParams"):
|
|
132
|
-
return temple_func(params=template_params)
|
|
133
|
-
|
|
134
139
|
|
|
135
140
|
class EvidentlyModelMonitoringApplicationBaseV2(
|
|
136
|
-
mm_base.ModelMonitoringApplicationBaseV2
|
|
141
|
+
mm_base.ModelMonitoringApplicationBaseV2, ABC
|
|
137
142
|
):
|
|
138
143
|
def __init__(
|
|
139
144
|
self, evidently_workspace_path: str, evidently_project_id: "STR_UUID"
|
|
@@ -160,14 +165,14 @@ class EvidentlyModelMonitoringApplicationBaseV2(
|
|
|
160
165
|
@staticmethod
|
|
161
166
|
def log_evidently_object(
|
|
162
167
|
monitoring_context: mm_context.MonitoringApplicationContext,
|
|
163
|
-
evidently_object:
|
|
168
|
+
evidently_object: "Display",
|
|
164
169
|
artifact_name: str,
|
|
165
|
-
):
|
|
170
|
+
) -> None:
|
|
166
171
|
"""
|
|
167
172
|
Logs an Evidently report or suite as an artifact.
|
|
168
173
|
|
|
169
174
|
:param monitoring_context: (MonitoringApplicationContext) The monitoring context to process.
|
|
170
|
-
:param evidently_object: (
|
|
175
|
+
:param evidently_object: (Display) The Evidently display to log, e.g. a report or a test suite object.
|
|
171
176
|
:param artifact_name: (str) The name for the logged artifact.
|
|
172
177
|
"""
|
|
173
178
|
evidently_object_html = evidently_object.get_html()
|
|
@@ -181,7 +186,7 @@ class EvidentlyModelMonitoringApplicationBaseV2(
|
|
|
181
186
|
timestamp_start: pd.Timestamp,
|
|
182
187
|
timestamp_end: pd.Timestamp,
|
|
183
188
|
artifact_name: str = "dashboard",
|
|
184
|
-
):
|
|
189
|
+
) -> None:
|
|
185
190
|
"""
|
|
186
191
|
Logs an Evidently project dashboard.
|
|
187
192
|
|
|
@@ -200,11 +205,7 @@ class EvidentlyModelMonitoringApplicationBaseV2(
|
|
|
200
205
|
additional_graphs={},
|
|
201
206
|
)
|
|
202
207
|
|
|
203
|
-
dashboard_html =
|
|
208
|
+
dashboard_html = file_html_template(params=template_params)
|
|
204
209
|
monitoring_context.log_artifact(
|
|
205
210
|
artifact_name, body=dashboard_html.encode("utf-8"), format="html"
|
|
206
211
|
)
|
|
207
|
-
|
|
208
|
-
@staticmethod
|
|
209
|
-
def _render(temple_func, template_params: "TemplateParams"):
|
|
210
|
-
return temple_func(params=template_params)
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import concurrent.futures
|
|
16
16
|
import datetime
|
|
17
17
|
import json
|
|
18
|
+
import multiprocessing
|
|
18
19
|
import os
|
|
19
20
|
import re
|
|
20
21
|
from collections.abc import Iterator
|
|
@@ -363,7 +364,10 @@ class MonitoringApplicationController:
|
|
|
363
364
|
return
|
|
364
365
|
# Initialize a process pool that will be used to run each endpoint applications on a dedicated process
|
|
365
366
|
with concurrent.futures.ProcessPoolExecutor(
|
|
366
|
-
max_workers=min(len(endpoints), 10)
|
|
367
|
+
max_workers=min(len(endpoints), 10),
|
|
368
|
+
# On Linux, the default is "fork" (this is set to change in Python 3.14), which inherits the current heap
|
|
369
|
+
# and resources (such as sockets), which is not what we want (ML-7160)
|
|
370
|
+
mp_context=multiprocessing.get_context("spawn"),
|
|
367
371
|
) as pool:
|
|
368
372
|
for endpoint in endpoints:
|
|
369
373
|
if (
|
|
@@ -557,6 +557,26 @@ class ProcessEndpointEvent(mlrun.feature_store.steps.MapClass):
|
|
|
557
557
|
|
|
558
558
|
# Separate each model invocation into sub events that will be stored as dictionary
|
|
559
559
|
# in list of events. This list will be used as the body for the storey event.
|
|
560
|
+
if not isinstance(features, list):
|
|
561
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
562
|
+
"Model's inputs must be a list"
|
|
563
|
+
)
|
|
564
|
+
features = (
|
|
565
|
+
features
|
|
566
|
+
if not any(not isinstance(feat, list) for feat in features)
|
|
567
|
+
else [features]
|
|
568
|
+
)
|
|
569
|
+
if not isinstance(predictions, list):
|
|
570
|
+
predictions = [[predictions]]
|
|
571
|
+
elif isinstance(predictions, list) and len(predictions) == len(features):
|
|
572
|
+
pass # predictions are already in the right format
|
|
573
|
+
else:
|
|
574
|
+
predictions = (
|
|
575
|
+
predictions
|
|
576
|
+
if not any(not isinstance(pred, list) for pred in predictions)
|
|
577
|
+
else [predictions]
|
|
578
|
+
)
|
|
579
|
+
|
|
560
580
|
events = []
|
|
561
581
|
for i, (feature, prediction) in enumerate(zip(features, predictions)):
|
|
562
582
|
if not isinstance(prediction, list):
|
|
@@ -657,7 +657,7 @@ class APIGateway(ModelObj):
|
|
|
657
657
|
host = self.spec.host
|
|
658
658
|
if not self.spec.host.startswith("http"):
|
|
659
659
|
host = f"https://{self.spec.host}"
|
|
660
|
-
return urljoin(host, self.spec.path)
|
|
660
|
+
return urljoin(host, self.spec.path).rstrip("/")
|
|
661
661
|
|
|
662
662
|
@staticmethod
|
|
663
663
|
def _generate_basic_auth(username: str, password: str):
|
mlrun/runtimes/utils.py
CHANGED
|
@@ -445,3 +445,21 @@ def enrich_run_labels(
|
|
|
445
445
|
if label.value not in labels and enrichment:
|
|
446
446
|
labels[label.value] = enrichment
|
|
447
447
|
return labels
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
def resolve_node_selectors(
|
|
451
|
+
project_node_selector: dict, instance_node_selector: dict
|
|
452
|
+
) -> dict:
|
|
453
|
+
config_node_selector = mlrun.mlconf.get_default_function_node_selector()
|
|
454
|
+
if project_node_selector or config_node_selector:
|
|
455
|
+
mlrun.utils.logger.debug(
|
|
456
|
+
"Enriching node selector from project and mlrun config",
|
|
457
|
+
project_node_selector=project_node_selector,
|
|
458
|
+
config_node_selector=config_node_selector,
|
|
459
|
+
)
|
|
460
|
+
return mlrun.utils.helpers.merge_dicts_with_precedence(
|
|
461
|
+
config_node_selector,
|
|
462
|
+
project_node_selector,
|
|
463
|
+
instance_node_selector,
|
|
464
|
+
)
|
|
465
|
+
return instance_node_selector
|
mlrun/serving/states.py
CHANGED
|
@@ -872,7 +872,8 @@ class QueueStep(BaseStep):
|
|
|
872
872
|
return event
|
|
873
873
|
|
|
874
874
|
if self._stream:
|
|
875
|
-
|
|
875
|
+
full_event = self.options.get("full_event")
|
|
876
|
+
if full_event or full_event is None and self.next:
|
|
876
877
|
data = storey.utils.wrap_event_for_serialization(event, data)
|
|
877
878
|
self._stream.push(data)
|
|
878
879
|
event.terminated = True
|
|
@@ -1630,7 +1631,11 @@ def _init_async_objects(context, steps):
|
|
|
1630
1631
|
if step.path and not skip_stream:
|
|
1631
1632
|
stream_path = step.path
|
|
1632
1633
|
endpoint = None
|
|
1633
|
-
|
|
1634
|
+
# in case of a queue, we default to a full_event=True
|
|
1635
|
+
full_event = step.options.get("full_event")
|
|
1636
|
+
options = {
|
|
1637
|
+
"full_event": full_event or full_event is None and step.next
|
|
1638
|
+
}
|
|
1634
1639
|
options.update(step.options)
|
|
1635
1640
|
|
|
1636
1641
|
kafka_brokers = get_kafka_brokers_from_dict(options, pop=True)
|
mlrun/serving/v2_serving.py
CHANGED
|
@@ -335,6 +335,7 @@ class V2ModelServer(StepToDict):
|
|
|
335
335
|
else:
|
|
336
336
|
track_request = {"id": event_id, "inputs": inputs or []}
|
|
337
337
|
track_response = {"outputs": outputs or []}
|
|
338
|
+
# TODO : check dict/list
|
|
338
339
|
self._model_logger.push(start, track_request, track_response, op)
|
|
339
340
|
event.body = _update_result_body(self._result_path, original_body, response)
|
|
340
341
|
return event
|
|
@@ -376,8 +377,10 @@ class V2ModelServer(StepToDict):
|
|
|
376
377
|
"""postprocess, before returning response"""
|
|
377
378
|
return request
|
|
378
379
|
|
|
379
|
-
def predict(self, request: dict) ->
|
|
380
|
-
"""model prediction operation
|
|
380
|
+
def predict(self, request: dict) -> list:
|
|
381
|
+
"""model prediction operation
|
|
382
|
+
:return: list with the model prediction results (can be multi-port) or list of lists for multiple predictions
|
|
383
|
+
"""
|
|
381
384
|
raise NotImplementedError()
|
|
382
385
|
|
|
383
386
|
def explain(self, request: dict) -> dict:
|
mlrun/utils/db.py
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
|
+
import abc
|
|
15
16
|
import pickle
|
|
16
17
|
from datetime import datetime
|
|
17
18
|
|
|
@@ -37,6 +38,13 @@ class BaseModel:
|
|
|
37
38
|
|
|
38
39
|
return dict(map(get_key_value, columns))
|
|
39
40
|
|
|
41
|
+
@abc.abstractmethod
|
|
42
|
+
def get_identifier_string(self):
|
|
43
|
+
"""
|
|
44
|
+
This method must be implemented by any subclass.
|
|
45
|
+
"""
|
|
46
|
+
pass
|
|
47
|
+
|
|
40
48
|
|
|
41
49
|
class HasStruct(BaseModel):
|
|
42
50
|
@property
|
|
@@ -54,3 +62,10 @@ class HasStruct(BaseModel):
|
|
|
54
62
|
exclude = exclude or []
|
|
55
63
|
exclude.append("body")
|
|
56
64
|
return super().to_dict(exclude, strip=strip)
|
|
65
|
+
|
|
66
|
+
@abc.abstractmethod
|
|
67
|
+
def get_identifier_string(self):
|
|
68
|
+
"""
|
|
69
|
+
This method must be implemented by any subclass.
|
|
70
|
+
"""
|
|
71
|
+
pass
|
mlrun/utils/http.py
CHANGED
|
@@ -95,7 +95,7 @@ class HTTPSessionWithRetry(requests.Session):
|
|
|
95
95
|
total=self.max_retries,
|
|
96
96
|
backoff_factor=self.retry_backoff_factor,
|
|
97
97
|
status_forcelist=config.http_retry_defaults.status_codes,
|
|
98
|
-
|
|
98
|
+
allowed_methods=self._retry_methods,
|
|
99
99
|
# we want to retry but not to raise since we do want that last response (to parse details on the
|
|
100
100
|
# error from response body) we'll handle raising ourselves
|
|
101
101
|
raise_on_status=False,
|
mlrun/utils/version/version.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
mlrun/__init__.py,sha256=y08M1JcKXy5-9_5WaI9fn5aV5BxIQ5QkbduJK0OxWbA,7470
|
|
2
2
|
mlrun/__main__.py,sha256=iAifncsrQQx6ozXXmz7GH1OiNl8PA7KS3TnwlxnHGeo,45890
|
|
3
|
-
mlrun/config.py,sha256=
|
|
3
|
+
mlrun/config.py,sha256=F8lKjS57FlodLbZawg2eyGjRjzDRR-K53n_bIbq9aD8,66129
|
|
4
4
|
mlrun/errors.py,sha256=VpC_imeSz2twRMZZb7u90Zj29z6aO-tCxUHD3ZA_Axw,7465
|
|
5
5
|
mlrun/execution.py,sha256=Gv7mzzaf5y8fIEF0VVu8dSJYQp2uCezXDUiE60cGxWU,41970
|
|
6
6
|
mlrun/features.py,sha256=m17K_3l9Jktwb9dOwlHLTAPTlemsWrRF7dJhXUX0iJU,15429
|
|
@@ -38,7 +38,7 @@ mlrun/common/model_monitoring/helpers.py,sha256=1CpxIDQPumFnpUB1eqcvCpLlyPFVeW2s
|
|
|
38
38
|
mlrun/common/runtimes/constants.py,sha256=Rl0Sd8n_L7Imo-uF1LL9CJ5Szi0W1gUm36yrF8PXfSc,10989
|
|
39
39
|
mlrun/common/schemas/__init__.py,sha256=CUX4F6VeowqX5PzakB7xgGs2lJZAN42RMm1asB-kf1c,5227
|
|
40
40
|
mlrun/common/schemas/alert.py,sha256=Gb2eSjZLTkm-lGy_rQ_D4crEjCTdyf1N90bnIJmQ1H8,6574
|
|
41
|
-
mlrun/common/schemas/api_gateway.py,sha256=
|
|
41
|
+
mlrun/common/schemas/api_gateway.py,sha256=aEQ4rO5WyjAGIH7QJohctpftJi_SP4cTAfbmRi1ATwE,6920
|
|
42
42
|
mlrun/common/schemas/artifact.py,sha256=V3ngobnzI1v2eoOroWBEedjAZu0ntCSIQ-LzsOK1Z9k,3570
|
|
43
43
|
mlrun/common/schemas/auth.py,sha256=5c4WSn3KdX1v04ttSQblkF_gyjdjuJSHG7BTCx4_LWM,6336
|
|
44
44
|
mlrun/common/schemas/background_task.py,sha256=2qZxib2qrF_nPZj0ncitCG-2jxz2hg1qj0hFc8eswWQ,1707
|
|
@@ -92,7 +92,7 @@ mlrun/datastore/s3.py,sha256=YXLIcsODJJuIuTTp4MTPjJqbvxzPRMeXpbImV9_q8Y8,8449
|
|
|
92
92
|
mlrun/datastore/snowflake_utils.py,sha256=Wohvnlmq8j1d98RCaknll-iWdZZpSlCrKhUOEy0_-CA,1483
|
|
93
93
|
mlrun/datastore/sources.py,sha256=Mxn2aS42kSv7I6GrNixUHMjE8taEvs6-YQZE2L4Lsxg,46564
|
|
94
94
|
mlrun/datastore/spark_udf.py,sha256=NnnB3DZxZb-rqpRy7b-NC7QWXuuqFn3XkBDc86tU4mQ,1498
|
|
95
|
-
mlrun/datastore/spark_utils.py,sha256=
|
|
95
|
+
mlrun/datastore/spark_utils.py,sha256=_AsVoU5Ix_-W7Gyq8io8V-2GTk0m8THJNDP3WGGaWJY,2865
|
|
96
96
|
mlrun/datastore/store_resources.py,sha256=rcLoG506AMmR8qPJU_gE-G5d34VJVV_vNlZ3VHqho6c,6869
|
|
97
97
|
mlrun/datastore/targets.py,sha256=JbffgF3yct9FSJ2LaKR--iUNCDq5Qzbd5mYqq1yPmeg,81178
|
|
98
98
|
mlrun/datastore/utils.py,sha256=l9dLZb_VCbHs_htqMFRv4qiestZ8z8K-4eY1MxHS8wE,7720
|
|
@@ -106,12 +106,12 @@ mlrun/db/factory.py,sha256=ibIrE5QkIIyzDU1FXKrfbc31cZiRLYKDZb8dqCpQwyU,2397
|
|
|
106
106
|
mlrun/db/httpdb.py,sha256=UW-vVFS5xAavHtZi1GmiEhGr9P2s3O8b9OkqgpcY7-o,183981
|
|
107
107
|
mlrun/db/nopdb.py,sha256=d7vSk_2sfwZGY24w7ucSkoq88fLPDLF137IXabongXU,20791
|
|
108
108
|
mlrun/feature_store/__init__.py,sha256=FhHRc8NdqL_HWpCs7A8dKruxJS5wEm55Gs3dcgBiRUg,1522
|
|
109
|
-
mlrun/feature_store/api.py,sha256=
|
|
109
|
+
mlrun/feature_store/api.py,sha256=czYTgN3zUx7j6n57z-T0btW0-PI1OxegL0o3kUUqMa8,49664
|
|
110
110
|
mlrun/feature_store/common.py,sha256=DKmoRk04NCS1gv7qZuEUa2-g8WsfR6IWjYctcrqKVlg,12853
|
|
111
111
|
mlrun/feature_store/feature_set.py,sha256=qD8RqkeoJFbJMMK5-zjs-27DC4UXQiQSokkt4pdMzkw,56027
|
|
112
112
|
mlrun/feature_store/feature_vector.py,sha256=A29-yCsFgvFU_Qw53CgDjn8t_okh7Nm6FZuvcEaKci0,44134
|
|
113
113
|
mlrun/feature_store/ingestion.py,sha256=kT3Hbz1PBjsJd-GPBm2ap0sg9-fiXxaSXoEIo-dOXpU,11361
|
|
114
|
-
mlrun/feature_store/steps.py,sha256=
|
|
114
|
+
mlrun/feature_store/steps.py,sha256=kdOrYh3fAdamV-RYNr86cFg445h_pgSWlb1EHOsAZUM,29297
|
|
115
115
|
mlrun/feature_store/retrieval/__init__.py,sha256=bwA4copPpLQi8fyoUAYtOyrlw0-6f3-Knct8GbJSvRg,1282
|
|
116
116
|
mlrun/feature_store/retrieval/base.py,sha256=zgDsRsYQz8eqReKBEeTP0O4UoLoVYjWpO1o1gtvbjRA,30230
|
|
117
117
|
mlrun/feature_store/retrieval/dask_merger.py,sha256=t60xciYp6StUQLEyFyI4JK5NpWkdBy2MGCs6beimaWU,5575
|
|
@@ -210,21 +210,21 @@ mlrun/launcher/factory.py,sha256=RW7mfzEFi8fR0M-4W1JQg1iq3_muUU6OTqT_3l4Ubrk,233
|
|
|
210
210
|
mlrun/launcher/local.py,sha256=pP9-ZrNL8OnNDEiXTAKAZQnmLpS_mCc2v-mJw329eks,11269
|
|
211
211
|
mlrun/launcher/remote.py,sha256=tGICSfWtvUHeR31mbzy6gqHejmDxjPUgjtxXTWhRubg,7699
|
|
212
212
|
mlrun/model_monitoring/__init__.py,sha256=dm5_j0_pwqrdzFwTaEtGnKfv2nVpNaM56nBI-oqLbNU,879
|
|
213
|
-
mlrun/model_monitoring/api.py,sha256=
|
|
213
|
+
mlrun/model_monitoring/api.py,sha256=nLfDFWgitVpdt2nCY1FGFp4nc4szO5OGFQXPFE7PRJU,28440
|
|
214
214
|
mlrun/model_monitoring/application.py,sha256=RJ8HeAPfGO3P2A_dEZYNg60c1wKTADh2YSv8BQ5embg,745
|
|
215
|
-
mlrun/model_monitoring/controller.py,sha256=
|
|
215
|
+
mlrun/model_monitoring/controller.py,sha256=kIwWgmUqVvh1qPWalibzIf0crYsDYYDEEYyagIEYqms,27890
|
|
216
216
|
mlrun/model_monitoring/evidently_application.py,sha256=iOc42IVjj8m6PDBmVcKIMWm46Bu0EdO9SDcH40Eqhyo,769
|
|
217
217
|
mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
|
|
218
218
|
mlrun/model_monitoring/helpers.py,sha256=jD9m_Dte16kDZc1GCXvv-0z-MCel1LRg_6Pn1nwqk7A,11599
|
|
219
219
|
mlrun/model_monitoring/model_endpoint.py,sha256=7VX0cBATqLsA4sSinDzouf41ndxqh2mf5bO9BW0G5Z4,4017
|
|
220
|
-
mlrun/model_monitoring/stream_processing.py,sha256=
|
|
220
|
+
mlrun/model_monitoring/stream_processing.py,sha256=QLnqVgPWNJT_ydZU1yhwIiEl1gtNASqG4B_c5xCFbm4,37916
|
|
221
221
|
mlrun/model_monitoring/tracking_policy.py,sha256=sQq956akAQpntkrJwIgFWcEq-JpyVcg0FxgNa4h3V70,5502
|
|
222
222
|
mlrun/model_monitoring/writer.py,sha256=aQ1DAi5XUi1WXXfcSgBQGKiTANT6E61I74abiu_5s8s,9824
|
|
223
223
|
mlrun/model_monitoring/applications/__init__.py,sha256=i793GqYee01mRh_KD6GShvX7UbPBgdJDO4qf9Z3BXEQ,970
|
|
224
|
-
mlrun/model_monitoring/applications/_application_steps.py,sha256
|
|
225
|
-
mlrun/model_monitoring/applications/base.py,sha256=
|
|
224
|
+
mlrun/model_monitoring/applications/_application_steps.py,sha256=diQ4RGWFx3gX-TfWopVP0LFB5Ofg09ZfOxu3gaUgL1Q,6169
|
|
225
|
+
mlrun/model_monitoring/applications/base.py,sha256=snr3xYdqv6Po19yS0Z1VktyoLrbl88lljSFQyjnKjR0,11616
|
|
226
226
|
mlrun/model_monitoring/applications/context.py,sha256=LGRJdI1eyyssFzjE4W_rk2VAUV8KpOkUZUX3xCmnC9g,8537
|
|
227
|
-
mlrun/model_monitoring/applications/evidently_base.py,sha256=
|
|
227
|
+
mlrun/model_monitoring/applications/evidently_base.py,sha256=6hzfO6s0jEVHj4R_pujcn_p6LvdkKUDb9S4B6j2XEUY,8024
|
|
228
228
|
mlrun/model_monitoring/applications/histogram_data_drift.py,sha256=TE6995h2PyO4lytVngH2HidhXFY7reLupWi4cHmdZdw,13163
|
|
229
229
|
mlrun/model_monitoring/applications/results.py,sha256=VVlu9Si7Tj2LNJzPQrp4_Qeyh9mxOVMu1Jwb5K2LfvY,3577
|
|
230
230
|
mlrun/model_monitoring/db/__init__.py,sha256=6Ic-X3Fh9XLPYMytmevGNSs-Hii1rAjLLoFTSPwTguw,736
|
|
@@ -284,7 +284,7 @@ mlrun/runtimes/kubejob.py,sha256=ptBnMTIjukbEznkdixmbGvBqzujXrRzqNfP7ze6M76M,866
|
|
|
284
284
|
mlrun/runtimes/local.py,sha256=h_w0tzCfF1_tZZEjw-FJHqYmoxK-AhN2skpK7cdU1JI,22611
|
|
285
285
|
mlrun/runtimes/pod.py,sha256=j0zsnbZq1p_RuK5u9re7iAX-E-UVnhm3Nx9JFfHFy9U,63184
|
|
286
286
|
mlrun/runtimes/remotesparkjob.py,sha256=9DPxDK8x08t9nReMo083TBxJiiqA83mHCbdtxrjj7AU,7426
|
|
287
|
-
mlrun/runtimes/utils.py,sha256=
|
|
287
|
+
mlrun/runtimes/utils.py,sha256=kX4SpO3zymxa8bXPJg5eSb0tfPi5NlZRl1IJCahTQuc,15004
|
|
288
288
|
mlrun/runtimes/databricks_job/__init__.py,sha256=kXGBqhLN0rlAx0kTXhozGzFsIdSqW0uTSKMmsLgq_is,569
|
|
289
289
|
mlrun/runtimes/databricks_job/databricks_cancel_task.py,sha256=sIqIg5DQAf4j0wCPA-G0GoxY6vacRddxCy5KDUZszek,2245
|
|
290
290
|
mlrun/runtimes/databricks_job/databricks_runtime.py,sha256=p80j2_jHzlH20dHT-avjfcbaDBTY2re1WjlJjbg5uSQ,12794
|
|
@@ -293,7 +293,7 @@ mlrun/runtimes/mpijob/__init__.py,sha256=V_1gQD1VHa0Qvjqgyv8RLouH27Sy9YTwj2ZG62o
|
|
|
293
293
|
mlrun/runtimes/mpijob/abstract.py,sha256=kDWo-IY1FKLZhI30j38Xx9HMhlUvHezfd1DT2ShoxZY,9161
|
|
294
294
|
mlrun/runtimes/mpijob/v1.py,sha256=1XQZC7AIMGX_AQCbApcwpH8I7y39-v0v2O35MvxjXoo,3213
|
|
295
295
|
mlrun/runtimes/nuclio/__init__.py,sha256=gx1kizzKv8pGT5TNloN1js1hdbxqDw3rM90sLVYVffY,794
|
|
296
|
-
mlrun/runtimes/nuclio/api_gateway.py,sha256=
|
|
296
|
+
mlrun/runtimes/nuclio/api_gateway.py,sha256=lSqHspGhXuf53_JiEg_vBgWo-Ykkh2jUzzFqJ_Gd_lQ,25793
|
|
297
297
|
mlrun/runtimes/nuclio/function.py,sha256=Eor5qem-nn64JFynwg-BShFkNRpleQWamjIY0_70Pdg,50538
|
|
298
298
|
mlrun/runtimes/nuclio/nuclio.py,sha256=sLK8KdGO1LbftlL3HqPZlFOFTAAuxJACZCVl1c0Ha6E,2942
|
|
299
299
|
mlrun/runtimes/nuclio/serving.py,sha256=eUMqtIU6NYIVgKtxfxKN7pd9_QCo_V0aurrjUSU3s08,29754
|
|
@@ -308,10 +308,10 @@ mlrun/serving/remote.py,sha256=MrFByphQWmIsKXqw-MOwl2Q1hbtWReYVRKvlcKj9pfw,17980
|
|
|
308
308
|
mlrun/serving/routers.py,sha256=tjTAiLkV-BcRnUfbTqfrKB0j2LMTMygG_2oV_eQ26bs,55470
|
|
309
309
|
mlrun/serving/server.py,sha256=LUf38ArOvs1cUbqxr3ZT015DTr4G5GIlToRaKqbhamc,21512
|
|
310
310
|
mlrun/serving/serving_wrapper.py,sha256=R670-S6PX_d5ER6jiHtRvacuPyFzQH0mEf2K0sBIIOM,836
|
|
311
|
-
mlrun/serving/states.py,sha256=
|
|
311
|
+
mlrun/serving/states.py,sha256=UX0rn1QR3YsO-KbHCnPRoO_y4RvsGSjenNMauV_1iPg,59975
|
|
312
312
|
mlrun/serving/utils.py,sha256=lej7XcUPX1MmHkEOi_0KZRGSpfbmpnE0GK_Sn4zLkHY,4025
|
|
313
313
|
mlrun/serving/v1_serving.py,sha256=by4myxlnwyZ0ijQ5fURilGCK1sUpdQL2Il1VR3Xqpxg,11805
|
|
314
|
-
mlrun/serving/v2_serving.py,sha256=
|
|
314
|
+
mlrun/serving/v2_serving.py,sha256=5h24wa_S4akkoPQvdN4yz_KJpr_-zU9JoKPTafZGZ60,24664
|
|
315
315
|
mlrun/track/__init__.py,sha256=LWRUHJt8JyFW17FyNPOVyWd-NXTf1iptzsK9KFj5fuY,765
|
|
316
316
|
mlrun/track/tracker.py,sha256=hSi9sMxB7hhZalt6Q8GXDnK4UoCbXHzKTrpUPC9hZv4,3555
|
|
317
317
|
mlrun/track/tracker_manager.py,sha256=IYBl99I62IC6VCCmG1yt6JoHNOQXa53C4DURJ2sWgio,5726
|
|
@@ -322,9 +322,9 @@ mlrun/utils/async_http.py,sha256=CZY8hNBMQaWrT6PLplyocCFbzaKrJnknFUP0e6kcDBw,117
|
|
|
322
322
|
mlrun/utils/azure_vault.py,sha256=IEFizrDGDbAaoWwDr1WoA88S_EZ0T--vjYtY-i0cvYQ,3450
|
|
323
323
|
mlrun/utils/clones.py,sha256=mJpx4nyFiY6jlBCvFABsNuyi_mr1mvfPWn81vlafpOU,7361
|
|
324
324
|
mlrun/utils/condition_evaluator.py,sha256=-nGfRmZzivn01rHTroiGY4rqEv8T1irMyhzxEei-sKc,1897
|
|
325
|
-
mlrun/utils/db.py,sha256=
|
|
325
|
+
mlrun/utils/db.py,sha256=blQgkWMfFH9lcN4sgJQcPQgEETz2Dl_zwbVA0SslpFg,2186
|
|
326
326
|
mlrun/utils/helpers.py,sha256=ZBLxZ0rJV-rRsM3lwmIG92KT2rFLpkJyPS9-8Loh3Lg,57703
|
|
327
|
-
mlrun/utils/http.py,sha256=
|
|
327
|
+
mlrun/utils/http.py,sha256=t6FrXQstZm9xVVjxqIGiLzrwZNCR4CSienSOuVgNIcI,8706
|
|
328
328
|
mlrun/utils/logger.py,sha256=cag2J30-jynIHmHZ2J8RYmVMNhYBGgAoimc5sbk-A1U,10016
|
|
329
329
|
mlrun/utils/regex.py,sha256=b0AUa2THS-ELzJj0grl5b8Stq609F2XomTZkD9SB1fQ,4900
|
|
330
330
|
mlrun/utils/retryer.py,sha256=GzDMeATklqxcKSLYaFYcqioh8e5cbWRxA1_XKrGR1A4,7570
|
|
@@ -341,11 +341,11 @@ mlrun/utils/notifications/notification/ipython.py,sha256=ZtVL30B_Ha0VGoo4LxO-voT
|
|
|
341
341
|
mlrun/utils/notifications/notification/slack.py,sha256=wqpFGr5BTvFO5KuUSzFfxsgmyU1Ohq7fbrGeNe9TXOk,7006
|
|
342
342
|
mlrun/utils/notifications/notification/webhook.py,sha256=cb9w1Mc8ENfJBdgan7iiVHK9eVls4-R3tUxmXM-P-8I,4746
|
|
343
343
|
mlrun/utils/version/__init__.py,sha256=7kkrB7hEZ3cLXoWj1kPoDwo4MaswsI2JVOBpbKgPAgc,614
|
|
344
|
-
mlrun/utils/version/version.json,sha256=
|
|
344
|
+
mlrun/utils/version/version.json,sha256=6htdTGo6dQazUoYgASl4PFqjC8v3k5-ECiUpEzlpoLc,89
|
|
345
345
|
mlrun/utils/version/version.py,sha256=eEW0tqIAkU9Xifxv8Z9_qsYnNhn3YH7NRAfM-pPLt1g,1878
|
|
346
|
-
mlrun-1.7.
|
|
347
|
-
mlrun-1.7.
|
|
348
|
-
mlrun-1.7.
|
|
349
|
-
mlrun-1.7.
|
|
350
|
-
mlrun-1.7.
|
|
351
|
-
mlrun-1.7.
|
|
346
|
+
mlrun-1.7.0rc36.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
347
|
+
mlrun-1.7.0rc36.dist-info/METADATA,sha256=3aVlqA_qRr9Q5Va5XKUvMuk24tZp8D67sk1oR_zG0-Q,19681
|
|
348
|
+
mlrun-1.7.0rc36.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
349
|
+
mlrun-1.7.0rc36.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
|
|
350
|
+
mlrun-1.7.0rc36.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
|
|
351
|
+
mlrun-1.7.0rc36.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|