mlrun 1.7.0rc7__py3-none-any.whl → 1.7.0rc11__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/__init__.py +1 -0
- mlrun/__main__.py +2 -0
- mlrun/artifacts/model.py +29 -25
- mlrun/common/schemas/__init__.py +4 -0
- mlrun/common/schemas/alert.py +122 -0
- mlrun/common/schemas/api_gateway.py +8 -1
- mlrun/common/schemas/auth.py +4 -0
- mlrun/common/schemas/client_spec.py +1 -0
- mlrun/common/schemas/hub.py +7 -9
- mlrun/common/schemas/model_monitoring/constants.py +4 -2
- mlrun/{datastore/helpers.py → common/schemas/pagination.py} +11 -3
- mlrun/common/schemas/project.py +15 -10
- mlrun/config.py +35 -13
- mlrun/datastore/__init__.py +3 -7
- mlrun/datastore/base.py +6 -5
- mlrun/datastore/datastore_profile.py +19 -1
- mlrun/datastore/snowflake_utils.py +43 -0
- mlrun/datastore/sources.py +18 -30
- mlrun/datastore/targets.py +140 -12
- mlrun/datastore/utils.py +10 -5
- mlrun/datastore/v3io.py +27 -50
- mlrun/db/base.py +88 -2
- mlrun/db/httpdb.py +314 -41
- mlrun/db/nopdb.py +142 -0
- mlrun/execution.py +21 -14
- mlrun/feature_store/api.py +9 -5
- mlrun/feature_store/feature_set.py +39 -23
- mlrun/feature_store/feature_vector.py +2 -1
- mlrun/feature_store/retrieval/spark_merger.py +27 -23
- mlrun/feature_store/steps.py +30 -19
- mlrun/features.py +4 -13
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
- mlrun/frameworks/lgbm/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/model_handler.py +1 -1
- mlrun/frameworks/pytorch/__init__.py +2 -2
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/tf_keras/__init__.py +1 -1
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
- mlrun/frameworks/xgboost/__init__.py +1 -1
- mlrun/kfpops.py +2 -5
- mlrun/launcher/base.py +1 -1
- mlrun/launcher/client.py +2 -2
- mlrun/model.py +2 -2
- mlrun/model_monitoring/application.py +11 -2
- mlrun/model_monitoring/applications/histogram_data_drift.py +3 -3
- mlrun/model_monitoring/controller.py +2 -3
- mlrun/model_monitoring/helpers.py +3 -1
- mlrun/model_monitoring/stream_processing.py +0 -1
- mlrun/model_monitoring/writer.py +32 -0
- mlrun/package/packagers_manager.py +1 -0
- mlrun/platforms/__init__.py +1 -1
- mlrun/platforms/other.py +1 -1
- mlrun/projects/operations.py +11 -4
- mlrun/projects/pipelines.py +1 -1
- mlrun/projects/project.py +180 -73
- mlrun/run.py +77 -41
- mlrun/runtimes/__init__.py +16 -0
- mlrun/runtimes/base.py +4 -1
- mlrun/runtimes/kubejob.py +26 -121
- mlrun/runtimes/mpijob/abstract.py +8 -8
- mlrun/runtimes/nuclio/api_gateway.py +58 -8
- mlrun/runtimes/nuclio/application/application.py +79 -1
- mlrun/runtimes/nuclio/application/reverse_proxy.go +9 -1
- mlrun/runtimes/nuclio/function.py +20 -13
- mlrun/runtimes/nuclio/serving.py +11 -10
- mlrun/runtimes/pod.py +148 -3
- mlrun/runtimes/utils.py +0 -28
- mlrun/secrets.py +6 -2
- mlrun/serving/remote.py +2 -3
- mlrun/serving/routers.py +7 -4
- mlrun/serving/server.py +1 -1
- mlrun/serving/states.py +14 -38
- mlrun/serving/v2_serving.py +8 -7
- mlrun/utils/helpers.py +1 -1
- mlrun/utils/http.py +1 -1
- mlrun/utils/notifications/notification/base.py +12 -0
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +3 -1
- mlrun/utils/notifications/notification/ipython.py +2 -0
- mlrun/utils/notifications/notification/slack.py +41 -13
- mlrun/utils/notifications/notification/webhook.py +11 -1
- mlrun/utils/retryer.py +3 -2
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/METADATA +15 -15
- {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/RECORD +91 -89
- {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/WHEEL +0 -0
- {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc7.dist-info → mlrun-1.7.0rc11.dist-info}/top_level.txt +0 -0
|
@@ -112,7 +112,7 @@ def train(
|
|
|
112
112
|
|
|
113
113
|
{
|
|
114
114
|
"/.../custom_optimizer.py": "optimizer",
|
|
115
|
-
"/.../custom_layers.py": ["layer1", "layer2"]
|
|
115
|
+
"/.../custom_layers.py": ["layer1", "layer2"],
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
All the paths will be accessed from the given 'custom_objects_directory',
|
|
@@ -264,7 +264,7 @@ def evaluate(
|
|
|
264
264
|
|
|
265
265
|
{
|
|
266
266
|
"/.../custom_optimizer.py": "optimizer",
|
|
267
|
-
"/.../custom_layers.py": ["layer1", "layer2"]
|
|
267
|
+
"/.../custom_layers.py": ["layer1", "layer2"],
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
All the paths will be accessed from the given 'custom_objects_directory', meaning
|
|
@@ -92,7 +92,7 @@ def apply_mlrun(
|
|
|
92
92
|
|
|
93
93
|
{
|
|
94
94
|
"/.../custom_model.py": "MyModel",
|
|
95
|
-
"/.../custom_objects.py": ["object1", "object2"]
|
|
95
|
+
"/.../custom_objects.py": ["object1", "object2"],
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
All the paths will be accessed from the given 'custom_objects_directory', meaning
|
|
@@ -19,7 +19,8 @@ from typing import Union
|
|
|
19
19
|
|
|
20
20
|
import tensorflow as tf
|
|
21
21
|
from tensorflow import keras
|
|
22
|
-
from tensorflow.keras.
|
|
22
|
+
from tensorflow.keras.optimizers import Optimizer
|
|
23
|
+
from tensorflow.python.keras.callbacks import (
|
|
23
24
|
BaseLogger,
|
|
24
25
|
Callback,
|
|
25
26
|
CSVLogger,
|
|
@@ -27,7 +28,6 @@ from tensorflow.keras.callbacks import (
|
|
|
27
28
|
ProgbarLogger,
|
|
28
29
|
TensorBoard,
|
|
29
30
|
)
|
|
30
|
-
from tensorflow.keras.optimizers import Optimizer
|
|
31
31
|
|
|
32
32
|
import mlrun
|
|
33
33
|
|
|
@@ -90,7 +90,7 @@ def apply_mlrun(
|
|
|
90
90
|
|
|
91
91
|
{
|
|
92
92
|
"/.../custom_model.py": "MyModel",
|
|
93
|
-
"/.../custom_objects.py": ["object1", "object2"]
|
|
93
|
+
"/.../custom_objects.py": ["object1", "object2"],
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
All the paths will be accessed from the given 'custom_objects_directory', meaning
|
mlrun/kfpops.py
CHANGED
|
@@ -103,7 +103,7 @@ def write_kfpmeta(struct):
|
|
|
103
103
|
with open(path, "w") as fp:
|
|
104
104
|
fp.write(str(val))
|
|
105
105
|
except Exception as exc:
|
|
106
|
-
logger.warning("Failed writing to temp file. Ignoring", exc=
|
|
106
|
+
logger.warning("Failed writing to temp file. Ignoring", exc=err_to_str(exc))
|
|
107
107
|
pass
|
|
108
108
|
|
|
109
109
|
text = "# Run Report\n"
|
|
@@ -112,10 +112,7 @@ def write_kfpmeta(struct):
|
|
|
112
112
|
|
|
113
113
|
text += "## Metadata\n```yaml\n" + dict_to_yaml(struct) + "```\n"
|
|
114
114
|
|
|
115
|
-
metadata = {
|
|
116
|
-
"outputs": output_artifacts
|
|
117
|
-
+ [{"type": "markdown", "storage": "inline", "source": text}]
|
|
118
|
-
}
|
|
115
|
+
metadata = {"outputs": [{"type": "markdown", "storage": "inline", "source": text}]}
|
|
119
116
|
with open(os.path.join(KFPMETA_DIR, "mlpipeline-ui-metadata.json"), "w") as f:
|
|
120
117
|
json.dump(metadata, f)
|
|
121
118
|
|
mlrun/launcher/base.py
CHANGED
|
@@ -353,7 +353,7 @@ class BaseLauncher(abc.ABC):
|
|
|
353
353
|
or {}
|
|
354
354
|
)
|
|
355
355
|
state_thresholds = (
|
|
356
|
-
mlrun.
|
|
356
|
+
mlrun.mlconf.function.spec.state_thresholds.default.to_dict()
|
|
357
357
|
| state_thresholds
|
|
358
358
|
)
|
|
359
359
|
run.spec.state_thresholds = state_thresholds or run.spec.state_thresholds
|
mlrun/launcher/client.py
CHANGED
|
@@ -47,7 +47,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
|
|
|
47
47
|
If build is needed, set the image as the base_image for the build.
|
|
48
48
|
If image is not given set the default one.
|
|
49
49
|
"""
|
|
50
|
-
if runtime.kind in mlrun.runtimes.RuntimeKinds.
|
|
50
|
+
if runtime.kind in mlrun.runtimes.RuntimeKinds.pure_nuclio_deployed_runtimes():
|
|
51
51
|
return
|
|
52
52
|
|
|
53
53
|
require_build = runtime.requires_build()
|
|
@@ -129,7 +129,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
|
|
|
129
129
|
logger.info("no returned result (job may still be in progress)")
|
|
130
130
|
results_tbl.append(run.to_dict())
|
|
131
131
|
|
|
132
|
-
if mlrun.utils.is_ipython and mlrun.
|
|
132
|
+
if mlrun.utils.is_ipython and mlrun.mlconf.ipython_widget:
|
|
133
133
|
results_tbl.show()
|
|
134
134
|
print()
|
|
135
135
|
ui_url = mlrun.utils.get_ui_url(project, uid)
|
mlrun/model.py
CHANGED
|
@@ -931,7 +931,7 @@ class RunSpec(ModelObj):
|
|
|
931
931
|
|
|
932
932
|
>>> run_spec.inputs = {
|
|
933
933
|
... "my_input": "...",
|
|
934
|
-
... "my_hinted_input : pandas.DataFrame": "..."
|
|
934
|
+
... "my_hinted_input : pandas.DataFrame": "...",
|
|
935
935
|
... }
|
|
936
936
|
|
|
937
937
|
:param inputs: The inputs to set.
|
|
@@ -1275,7 +1275,7 @@ class RunTemplate(ModelObj):
|
|
|
1275
1275
|
|
|
1276
1276
|
example::
|
|
1277
1277
|
|
|
1278
|
-
grid_params = {"p1": [2,4,1], "p2": [10,20]}
|
|
1278
|
+
grid_params = {"p1": [2, 4, 1], "p2": [10, 20]}
|
|
1279
1279
|
task = mlrun.new_task("grid-search")
|
|
1280
1280
|
task.with_hyper_params(grid_params, selector="max.accuracy")
|
|
1281
1281
|
"""
|
|
@@ -93,7 +93,11 @@ class ModelMonitoringApplicationBase(StepToDict, ABC):
|
|
|
93
93
|
endpoint_id: str,
|
|
94
94
|
output_stream_uri: str,
|
|
95
95
|
) -> ModelMonitoringApplicationResult:
|
|
96
|
-
self.context.log_artifact(
|
|
96
|
+
self.context.log_artifact(
|
|
97
|
+
TableArtifact(
|
|
98
|
+
"sample_df_stats", df=self.dict_to_histogram(sample_df_stats)
|
|
99
|
+
)
|
|
100
|
+
)
|
|
97
101
|
return ModelMonitoringApplicationResult(
|
|
98
102
|
name="data_drift_test",
|
|
99
103
|
value=0.5,
|
|
@@ -101,6 +105,7 @@ class ModelMonitoringApplicationBase(StepToDict, ABC):
|
|
|
101
105
|
status=mm_constant.ResultStatusApp.detected,
|
|
102
106
|
)
|
|
103
107
|
|
|
108
|
+
|
|
104
109
|
# mlrun: end-code
|
|
105
110
|
"""
|
|
106
111
|
|
|
@@ -203,7 +208,11 @@ class ModelMonitoringApplicationBase(StepToDict, ABC):
|
|
|
203
208
|
json.loads(event[mm_constant.ApplicationEvent.FEATURE_STATS]),
|
|
204
209
|
ParquetTarget(
|
|
205
210
|
path=event[mm_constant.ApplicationEvent.SAMPLE_PARQUET_PATH]
|
|
206
|
-
).as_df(
|
|
211
|
+
).as_df(
|
|
212
|
+
start_time=start_time,
|
|
213
|
+
end_time=end_time,
|
|
214
|
+
time_column=mm_constant.FeatureSetFeatures.time_stamp(),
|
|
215
|
+
),
|
|
207
216
|
start_time,
|
|
208
217
|
end_time,
|
|
209
218
|
pd.Timestamp(event[mm_constant.ApplicationEvent.LAST_REQUEST]),
|
|
@@ -22,8 +22,8 @@ import mlrun.artifacts
|
|
|
22
22
|
import mlrun.common.model_monitoring.helpers
|
|
23
23
|
import mlrun.model_monitoring.features_drift_table as mm_drift_table
|
|
24
24
|
from mlrun.common.schemas.model_monitoring.constants import (
|
|
25
|
-
MLRUN_HISTOGRAM_DATA_DRIFT_APP_NAME,
|
|
26
25
|
EventFieldType,
|
|
26
|
+
HistogramDataDriftApplicationConstants,
|
|
27
27
|
ResultKindApp,
|
|
28
28
|
ResultStatusApp,
|
|
29
29
|
)
|
|
@@ -94,7 +94,7 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBase):
|
|
|
94
94
|
and the status is returned.
|
|
95
95
|
"""
|
|
96
96
|
|
|
97
|
-
NAME: Final[str] =
|
|
97
|
+
NAME: Final[str] = HistogramDataDriftApplicationConstants.NAME
|
|
98
98
|
METRIC_KIND: Final[ResultKindApp] = ResultKindApp.data_drift
|
|
99
99
|
|
|
100
100
|
_REQUIRED_METRICS = {HellingerDistance, TotalVarianceDistance}
|
|
@@ -148,7 +148,7 @@ class HistogramDataDriftApplication(ModelMonitoringApplicationBase):
|
|
|
148
148
|
status = self._value_classifier.value_to_status(value)
|
|
149
149
|
results.append(
|
|
150
150
|
ModelMonitoringApplicationResult(
|
|
151
|
-
name=
|
|
151
|
+
name=HistogramDataDriftApplicationConstants.GENERAL_RESULT_NAME,
|
|
152
152
|
value=value,
|
|
153
153
|
kind=self.METRIC_KIND,
|
|
154
154
|
status=status,
|
|
@@ -354,7 +354,7 @@ class MonitoringApplicationController:
|
|
|
354
354
|
app.status.state == "ready"
|
|
355
355
|
# workaround for the default app, as its `status.state` is `None`
|
|
356
356
|
or app.metadata.name
|
|
357
|
-
== mm_constants.
|
|
357
|
+
== mm_constants.HistogramDataDriftApplicationConstants.NAME
|
|
358
358
|
)
|
|
359
359
|
}
|
|
360
360
|
)
|
|
@@ -502,8 +502,7 @@ class MonitoringApplicationController:
|
|
|
502
502
|
|
|
503
503
|
# Get the current stats:
|
|
504
504
|
current_stats = calculate_inputs_statistics(
|
|
505
|
-
sample_set_statistics=feature_stats,
|
|
506
|
-
inputs=df,
|
|
505
|
+
sample_set_statistics=feature_stats, inputs=df
|
|
507
506
|
)
|
|
508
507
|
|
|
509
508
|
cls._push_to_applications(
|
|
@@ -42,7 +42,7 @@ class _BatchDict(typing.TypedDict):
|
|
|
42
42
|
def get_stream_path(
|
|
43
43
|
project: str = None,
|
|
44
44
|
function_name: str = mm_constants.MonitoringFunctionNames.STREAM,
|
|
45
|
-
):
|
|
45
|
+
) -> str:
|
|
46
46
|
"""
|
|
47
47
|
Get stream path from the project secret. If wasn't set, take it from the system configurations
|
|
48
48
|
|
|
@@ -61,6 +61,8 @@ def get_stream_path(
|
|
|
61
61
|
function_name=function_name,
|
|
62
62
|
)
|
|
63
63
|
|
|
64
|
+
if isinstance(stream_uri, list): # ML-6043 - user side gets only the new stream uri
|
|
65
|
+
stream_uri = stream_uri[1] # get new stream path, under projects
|
|
64
66
|
return mlrun.common.model_monitoring.helpers.parse_monitoring_stream_path(
|
|
65
67
|
stream_uri=stream_uri, project=project, function_name=function_name
|
|
66
68
|
)
|
mlrun/model_monitoring/writer.py
CHANGED
|
@@ -23,6 +23,7 @@ from v3io_frames.errors import Error as V3IOFramesError
|
|
|
23
23
|
from v3io_frames.frames_pb2 import IGNORE
|
|
24
24
|
|
|
25
25
|
import mlrun.common.model_monitoring
|
|
26
|
+
import mlrun.common.schemas.alert as alert_constants
|
|
26
27
|
import mlrun.model_monitoring
|
|
27
28
|
import mlrun.model_monitoring.db.stores
|
|
28
29
|
import mlrun.utils.v3io_clients
|
|
@@ -171,6 +172,29 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
171
172
|
event=event,
|
|
172
173
|
)
|
|
173
174
|
|
|
175
|
+
@staticmethod
|
|
176
|
+
def _generate_event_on_drift(
|
|
177
|
+
uid: str, drift_status: str, drift_value: float, project_name: str
|
|
178
|
+
):
|
|
179
|
+
if (
|
|
180
|
+
drift_status == ResultStatusApp.detected
|
|
181
|
+
or drift_status == ResultStatusApp.potential_detection
|
|
182
|
+
):
|
|
183
|
+
entity = {
|
|
184
|
+
"kind": alert_constants.EventEntityKind.MODEL,
|
|
185
|
+
"project": project_name,
|
|
186
|
+
"id": uid,
|
|
187
|
+
}
|
|
188
|
+
event_kind = (
|
|
189
|
+
alert_constants.EventKind.DRIFT_DETECTED
|
|
190
|
+
if drift_status == ResultStatusApp.detected
|
|
191
|
+
else alert_constants.EventKind.DRIFT_SUSPECTED
|
|
192
|
+
)
|
|
193
|
+
event_data = mlrun.common.schemas.Event(
|
|
194
|
+
kind=event_kind, entity=entity, value=drift_value
|
|
195
|
+
)
|
|
196
|
+
mlrun.get_run_db().generate_event(event_kind, event_data)
|
|
197
|
+
|
|
174
198
|
@staticmethod
|
|
175
199
|
def _reconstruct_event(event: _RawEvent) -> _AppResultEvent:
|
|
176
200
|
"""
|
|
@@ -201,4 +225,12 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
201
225
|
self._update_tsdb(event)
|
|
202
226
|
self._update_kv_db(event)
|
|
203
227
|
_Notifier(event=event, notification_pusher=self._custom_notifier).notify()
|
|
228
|
+
|
|
229
|
+
if mlrun.mlconf.alerts.mode == mlrun.common.schemas.alert.AlertsModes.enabled:
|
|
230
|
+
self._generate_event_on_drift(
|
|
231
|
+
event[WriterEvent.ENDPOINT_ID],
|
|
232
|
+
event[WriterEvent.RESULT_STATUS],
|
|
233
|
+
event[WriterEvent.RESULT_VALUE],
|
|
234
|
+
self.project,
|
|
235
|
+
)
|
|
204
236
|
logger.info("Completed event DB writes")
|
mlrun/platforms/__init__.py
CHANGED
mlrun/platforms/other.py
CHANGED
|
@@ -33,7 +33,7 @@ def mount_pvc(pvc_name=None, volume_name="pipeline", volume_mount_path="/mnt/pip
|
|
|
33
33
|
Usage::
|
|
34
34
|
|
|
35
35
|
train = train_op(...)
|
|
36
|
-
train.apply(mount_pvc(
|
|
36
|
+
train.apply(mount_pvc("claim-name", "pipeline", "/mnt/pipeline"))
|
|
37
37
|
"""
|
|
38
38
|
if "MLRUN_PVC_MOUNT" in os.environ:
|
|
39
39
|
mount = os.environ.get("MLRUN_PVC_MOUNT")
|
mlrun/projects/operations.py
CHANGED
|
@@ -95,8 +95,11 @@ def run_function(
|
|
|
95
95
|
MODEL_CLASS = "sklearn.ensemble.RandomForestClassifier"
|
|
96
96
|
DATA_PATH = "s3://bigdata/data.parquet"
|
|
97
97
|
function = mlrun.import_function("hub://auto-trainer")
|
|
98
|
-
run1 = run_function(
|
|
99
|
-
|
|
98
|
+
run1 = run_function(
|
|
99
|
+
function,
|
|
100
|
+
params={"label_columns": LABELS, "model_class": MODEL_CLASS},
|
|
101
|
+
inputs={"dataset": DATA_PATH},
|
|
102
|
+
)
|
|
100
103
|
|
|
101
104
|
example (use with project)::
|
|
102
105
|
|
|
@@ -115,8 +118,12 @@ def run_function(
|
|
|
115
118
|
@dsl.pipeline(name="test pipeline", description="test")
|
|
116
119
|
def my_pipe(url=""):
|
|
117
120
|
run1 = run_function("loaddata", params={"url": url}, outputs=["data"])
|
|
118
|
-
run2 = run_function(
|
|
119
|
-
|
|
121
|
+
run2 = run_function(
|
|
122
|
+
"train",
|
|
123
|
+
params={"label_columns": LABELS, "model_class": MODEL_CLASS},
|
|
124
|
+
inputs={"dataset": run1.outputs["data"]},
|
|
125
|
+
)
|
|
126
|
+
|
|
120
127
|
|
|
121
128
|
project.run(workflow_handler=my_pipe, arguments={"param1": 7})
|
|
122
129
|
|
mlrun/projects/pipelines.py
CHANGED