mlrun 1.7.0rc4__py3-none-any.whl → 1.7.0rc20__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 +11 -1
- mlrun/__main__.py +25 -111
- mlrun/{datastore/helpers.py → alerts/__init__.py} +2 -5
- mlrun/alerts/alert.py +144 -0
- mlrun/api/schemas/__init__.py +4 -3
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +38 -254
- mlrun/artifacts/dataset.py +9 -190
- mlrun/artifacts/manager.py +41 -47
- mlrun/artifacts/model.py +30 -158
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +68 -0
- mlrun/common/formatters/__init__.py +19 -0
- mlrun/{model_monitoring/stores/models/sqlite.py → common/formatters/artifact.py} +6 -8
- mlrun/common/formatters/base.py +78 -0
- mlrun/common/formatters/function.py +41 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/{runtimes → common/runtimes}/constants.py +32 -4
- mlrun/common/schemas/__init__.py +25 -4
- mlrun/common/schemas/alert.py +203 -0
- mlrun/common/schemas/api_gateway.py +148 -0
- mlrun/common/schemas/artifact.py +15 -5
- mlrun/common/schemas/auth.py +8 -2
- mlrun/common/schemas/client_spec.py +2 -0
- mlrun/common/schemas/frontend_spec.py +1 -0
- mlrun/common/schemas/function.py +4 -0
- mlrun/common/schemas/hub.py +7 -9
- mlrun/common/schemas/model_monitoring/__init__.py +19 -3
- mlrun/common/schemas/model_monitoring/constants.py +96 -26
- mlrun/common/schemas/model_monitoring/grafana.py +9 -5
- mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
- mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
- mlrun/common/schemas/pipeline.py +0 -9
- mlrun/common/schemas/project.py +22 -21
- mlrun/common/types.py +7 -1
- mlrun/config.py +87 -19
- mlrun/data_types/data_types.py +4 -0
- mlrun/data_types/to_pandas.py +9 -9
- mlrun/datastore/__init__.py +5 -8
- mlrun/datastore/alibaba_oss.py +130 -0
- mlrun/datastore/azure_blob.py +4 -5
- mlrun/datastore/base.py +69 -30
- mlrun/datastore/datastore.py +10 -2
- mlrun/datastore/datastore_profile.py +90 -6
- mlrun/datastore/google_cloud_storage.py +1 -1
- mlrun/datastore/hdfs.py +5 -0
- mlrun/datastore/inmem.py +2 -2
- mlrun/datastore/redis.py +2 -2
- mlrun/datastore/s3.py +5 -0
- mlrun/datastore/snowflake_utils.py +43 -0
- mlrun/datastore/sources.py +172 -44
- mlrun/datastore/store_resources.py +7 -7
- mlrun/datastore/targets.py +285 -41
- mlrun/datastore/utils.py +68 -5
- mlrun/datastore/v3io.py +27 -50
- mlrun/db/auth_utils.py +152 -0
- mlrun/db/base.py +149 -14
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +608 -178
- mlrun/db/nopdb.py +191 -7
- mlrun/errors.py +11 -0
- mlrun/execution.py +37 -20
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +21 -52
- mlrun/feature_store/feature_set.py +48 -23
- mlrun/feature_store/feature_vector.py +2 -1
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +9 -4
- mlrun/feature_store/retrieval/conversion.py +9 -9
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +9 -3
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +34 -24
- mlrun/feature_store/steps.py +30 -19
- mlrun/features.py +4 -13
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
- 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/parallel_coordinates.py +2 -1
- mlrun/frameworks/pytorch/__init__.py +2 -2
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/tf_keras/__init__.py +5 -2
- 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/k8s_utils.py +10 -11
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +6 -5
- mlrun/launcher/client.py +8 -6
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +9 -3
- mlrun/launcher/remote.py +9 -3
- mlrun/lists.py +6 -2
- mlrun/model.py +58 -19
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +127 -301
- mlrun/model_monitoring/application.py +5 -296
- mlrun/model_monitoring/applications/__init__.py +11 -0
- mlrun/model_monitoring/applications/_application_steps.py +157 -0
- mlrun/model_monitoring/applications/base.py +282 -0
- mlrun/model_monitoring/applications/context.py +214 -0
- mlrun/model_monitoring/applications/evidently_base.py +211 -0
- mlrun/model_monitoring/applications/histogram_data_drift.py +224 -93
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +30 -36
- mlrun/model_monitoring/db/__init__.py +18 -0
- mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +58 -32
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
- mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +302 -155
- mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
- mlrun/model_monitoring/db/tsdb/base.py +329 -0
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
- mlrun/model_monitoring/evidently_application.py +6 -118
- mlrun/model_monitoring/features_drift_table.py +34 -22
- mlrun/model_monitoring/helpers.py +100 -7
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/stream_processing.py +93 -228
- mlrun/model_monitoring/tracking_policy.py +7 -1
- mlrun/model_monitoring/writer.py +152 -124
- mlrun/package/packagers_manager.py +1 -0
- mlrun/package/utils/_formatter.py +2 -2
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +21 -202
- mlrun/projects/operations.py +30 -16
- mlrun/projects/pipelines.py +92 -99
- mlrun/projects/project.py +757 -268
- mlrun/render.py +15 -14
- mlrun/run.py +160 -162
- mlrun/runtimes/__init__.py +55 -3
- mlrun/runtimes/base.py +33 -19
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +0 -28
- mlrun/runtimes/kubejob.py +28 -122
- mlrun/runtimes/local.py +5 -2
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +8 -8
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/runtimes/nuclio/__init__.py +1 -0
- mlrun/runtimes/nuclio/api_gateway.py +709 -0
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +523 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/nuclio/function.py +98 -58
- mlrun/runtimes/nuclio/serving.py +36 -42
- mlrun/runtimes/pod.py +196 -45
- mlrun/runtimes/remotesparkjob.py +1 -1
- mlrun/runtimes/sparkjob/spark3job.py +1 -1
- mlrun/runtimes/utils.py +6 -73
- mlrun/secrets.py +6 -2
- mlrun/serving/remote.py +2 -3
- mlrun/serving/routers.py +7 -4
- mlrun/serving/server.py +7 -8
- mlrun/serving/states.py +73 -43
- mlrun/serving/v2_serving.py +8 -7
- mlrun/track/tracker.py +2 -1
- mlrun/utils/async_http.py +25 -5
- mlrun/utils/helpers.py +141 -75
- mlrun/utils/http.py +1 -1
- mlrun/utils/logger.py +39 -7
- mlrun/utils/notifications/notification/__init__.py +14 -9
- 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 +101 -21
- mlrun/utils/notifications/notification/webhook.py +11 -1
- mlrun/utils/notifications/notification_pusher.py +147 -16
- mlrun/utils/retryer.py +3 -2
- mlrun/utils/v3io_clients.py +0 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +33 -18
- mlrun-1.7.0rc20.dist-info/RECORD +353 -0
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +1 -1
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/batch.py +0 -974
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -382
- mlrun/platforms/other.py +0 -305
- mlrun-1.7.0rc4.dist-info/RECORD +0 -321
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
|
@@ -363,7 +363,7 @@ class AutoMLRun:
|
|
|
363
363
|
|
|
364
364
|
{
|
|
365
365
|
"/.../custom_model.py": "MyModel",
|
|
366
|
-
"/.../custom_objects.py": ["object1", "object2"]
|
|
366
|
+
"/.../custom_objects.py": ["object1", "object2"],
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
All the paths will be accessed from the given 'custom_objects_directory',
|
|
@@ -464,7 +464,7 @@ class AutoMLRun:
|
|
|
464
464
|
|
|
465
465
|
{
|
|
466
466
|
"/.../custom_model.py": "MyModel",
|
|
467
|
-
"/.../custom_objects.py": ["object1", "object2"]
|
|
467
|
+
"/.../custom_objects.py": ["object1", "object2"],
|
|
468
468
|
}
|
|
469
469
|
|
|
470
470
|
All the paths will be accessed from the given 'custom_objects_directory',
|
|
@@ -241,7 +241,7 @@ def apply_mlrun(
|
|
|
241
241
|
|
|
242
242
|
{
|
|
243
243
|
"/.../custom_model.py": "MyModel",
|
|
244
|
-
"/.../custom_objects.py": ["object1", "object2"]
|
|
244
|
+
"/.../custom_objects.py": ["object1", "object2"],
|
|
245
245
|
}
|
|
246
246
|
|
|
247
247
|
All the paths will be accessed from the given 'custom_objects_directory', meaning
|
|
@@ -63,11 +63,9 @@ class Callback(ABC):
|
|
|
63
63
|
def on_train_end(self):
|
|
64
64
|
print("{self.name}: Done training!")
|
|
65
65
|
|
|
66
|
+
|
|
66
67
|
apply_mlrun()
|
|
67
|
-
lgb.train(
|
|
68
|
-
...,
|
|
69
|
-
callbacks=[ExampleCallback(name="Example")]
|
|
70
|
-
)
|
|
68
|
+
lgb.train(..., callbacks=[ExampleCallback(name="Example")])
|
|
71
69
|
"""
|
|
72
70
|
|
|
73
71
|
def __init__(self, order: int = 10, before_iteration: bool = False):
|
|
@@ -103,7 +103,7 @@ class LGBMModelHandler(MLModelHandler):
|
|
|
103
103
|
|
|
104
104
|
{
|
|
105
105
|
"/.../custom_model.py": "MyModel",
|
|
106
|
-
"/.../custom_objects.py": ["object1", "object2"]
|
|
106
|
+
"/.../custom_objects.py": ["object1", "object2"],
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
All the paths will be accessed from the given 'custom_objects_directory',
|
|
@@ -295,7 +295,7 @@ def compare_db_runs(
|
|
|
295
295
|
iter=False,
|
|
296
296
|
start_time_from: datetime = None,
|
|
297
297
|
hide_identical: bool = True,
|
|
298
|
-
exclude: list =
|
|
298
|
+
exclude: list = None,
|
|
299
299
|
show=None,
|
|
300
300
|
colorscale: str = "Blues",
|
|
301
301
|
filename=None,
|
|
@@ -332,6 +332,7 @@ def compare_db_runs(
|
|
|
332
332
|
**query_args,
|
|
333
333
|
)
|
|
334
334
|
|
|
335
|
+
exclude = exclude or []
|
|
335
336
|
runs_df = _runs_list_to_df(runs_list)
|
|
336
337
|
plot_as_html = gen_pcp_plot(
|
|
337
338
|
runs_df,
|
|
@@ -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
|
|
@@ -18,6 +18,7 @@ from typing import Any, Union
|
|
|
18
18
|
from tensorflow import keras
|
|
19
19
|
|
|
20
20
|
import mlrun
|
|
21
|
+
import mlrun.common.constants as mlrun_constants
|
|
21
22
|
|
|
22
23
|
from .callbacks import MLRunLoggingCallback, TensorboardLoggingCallback
|
|
23
24
|
from .mlrun_interface import TFKerasMLRunInterface
|
|
@@ -85,7 +86,7 @@ def apply_mlrun(
|
|
|
85
86
|
|
|
86
87
|
{
|
|
87
88
|
"/.../custom_optimizer.py": "optimizer",
|
|
88
|
-
"/.../custom_layers.py": ["layer1", "layer2"]
|
|
89
|
+
"/.../custom_layers.py": ["layer1", "layer2"],
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
All the paths will be accessed from the given 'custom_objects_directory',
|
|
@@ -126,7 +127,9 @@ def apply_mlrun(
|
|
|
126
127
|
# # Use horovod:
|
|
127
128
|
if use_horovod is None:
|
|
128
129
|
use_horovod = (
|
|
129
|
-
context.labels.get(
|
|
130
|
+
context.labels.get(mlrun_constants.MLRunInternalLabels.kind, "") == "mpijob"
|
|
131
|
+
if context is not None
|
|
132
|
+
else False
|
|
130
133
|
)
|
|
131
134
|
|
|
132
135
|
# Create a model handler:
|
|
@@ -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/k8s_utils.py
CHANGED
|
@@ -141,17 +141,6 @@ def verify_label_key(key: str):
|
|
|
141
141
|
if not key:
|
|
142
142
|
raise mlrun.errors.MLRunInvalidArgumentError("label key cannot be empty")
|
|
143
143
|
|
|
144
|
-
mlrun.utils.helpers.verify_field_regex(
|
|
145
|
-
f"project.metadata.labels.'{key}'",
|
|
146
|
-
key,
|
|
147
|
-
mlrun.utils.regex.k8s_character_limit,
|
|
148
|
-
)
|
|
149
|
-
|
|
150
|
-
if key.startswith("k8s.io/") or key.startswith("kubernetes.io/"):
|
|
151
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
152
|
-
"Labels cannot start with 'k8s.io/' or 'kubernetes.io/'"
|
|
153
|
-
)
|
|
154
|
-
|
|
155
144
|
parts = key.split("/")
|
|
156
145
|
if len(parts) == 1:
|
|
157
146
|
name = parts[0]
|
|
@@ -173,12 +162,22 @@ def verify_label_key(key: str):
|
|
|
173
162
|
"Label key can only contain one '/'"
|
|
174
163
|
)
|
|
175
164
|
|
|
165
|
+
mlrun.utils.helpers.verify_field_regex(
|
|
166
|
+
f"project.metadata.labels.'{key}'",
|
|
167
|
+
name,
|
|
168
|
+
mlrun.utils.regex.k8s_character_limit,
|
|
169
|
+
)
|
|
176
170
|
mlrun.utils.helpers.verify_field_regex(
|
|
177
171
|
f"project.metadata.labels.'{key}'",
|
|
178
172
|
name,
|
|
179
173
|
mlrun.utils.regex.qualified_name,
|
|
180
174
|
)
|
|
181
175
|
|
|
176
|
+
if key.startswith("k8s.io/") or key.startswith("kubernetes.io/"):
|
|
177
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
178
|
+
"Labels cannot start with 'k8s.io/' or 'kubernetes.io/'"
|
|
179
|
+
)
|
|
180
|
+
|
|
182
181
|
|
|
183
182
|
def verify_label_value(value, label_key):
|
|
184
183
|
mlrun.utils.helpers.verify_field_regex(
|
mlrun/launcher/__init__.py
CHANGED
mlrun/launcher/base.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -18,10 +18,11 @@ import os
|
|
|
18
18
|
import uuid
|
|
19
19
|
from typing import Any, Callable, Optional, Union
|
|
20
20
|
|
|
21
|
+
import mlrun_pipelines.common.ops
|
|
22
|
+
|
|
21
23
|
import mlrun.common.schemas
|
|
22
24
|
import mlrun.config
|
|
23
25
|
import mlrun.errors
|
|
24
|
-
import mlrun.kfpops
|
|
25
26
|
import mlrun.lists
|
|
26
27
|
import mlrun.model
|
|
27
28
|
import mlrun.runtimes
|
|
@@ -353,7 +354,7 @@ class BaseLauncher(abc.ABC):
|
|
|
353
354
|
or {}
|
|
354
355
|
)
|
|
355
356
|
state_thresholds = (
|
|
356
|
-
mlrun.
|
|
357
|
+
mlrun.mlconf.function.spec.state_thresholds.default.to_dict()
|
|
357
358
|
| state_thresholds
|
|
358
359
|
)
|
|
359
360
|
run.spec.state_thresholds = state_thresholds or run.spec.state_thresholds
|
|
@@ -390,7 +391,7 @@ class BaseLauncher(abc.ABC):
|
|
|
390
391
|
return
|
|
391
392
|
|
|
392
393
|
if result and runtime.kfp and err is None:
|
|
393
|
-
|
|
394
|
+
mlrun_pipelines.common.ops.write_kfpmeta(result)
|
|
394
395
|
|
|
395
396
|
self._log_track_results(runtime.is_child, result, run)
|
|
396
397
|
|
|
@@ -403,7 +404,7 @@ class BaseLauncher(abc.ABC):
|
|
|
403
404
|
)
|
|
404
405
|
if (
|
|
405
406
|
run.status.state
|
|
406
|
-
in mlrun.runtimes.constants.RunStates.error_and_abortion_states()
|
|
407
|
+
in mlrun.common.runtimes.constants.RunStates.error_and_abortion_states()
|
|
407
408
|
):
|
|
408
409
|
if runtime._is_remote and not runtime.is_child:
|
|
409
410
|
logger.error(
|
mlrun/launcher/client.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -16,6 +16,7 @@ from typing import Optional
|
|
|
16
16
|
|
|
17
17
|
import IPython
|
|
18
18
|
|
|
19
|
+
import mlrun.common.constants as mlrun_constants
|
|
19
20
|
import mlrun.errors
|
|
20
21
|
import mlrun.launcher.base as launcher
|
|
21
22
|
import mlrun.lists
|
|
@@ -47,7 +48,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
|
|
|
47
48
|
If build is needed, set the image as the base_image for the build.
|
|
48
49
|
If image is not given set the default one.
|
|
49
50
|
"""
|
|
50
|
-
if runtime.kind in mlrun.runtimes.RuntimeKinds.
|
|
51
|
+
if runtime.kind in mlrun.runtimes.RuntimeKinds.pure_nuclio_deployed_runtimes():
|
|
51
52
|
return
|
|
52
53
|
|
|
53
54
|
require_build = runtime.requires_build()
|
|
@@ -69,13 +70,14 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
|
|
|
69
70
|
def _store_function(
|
|
70
71
|
runtime: "mlrun.runtimes.BaseRuntime", run: "mlrun.run.RunObject"
|
|
71
72
|
):
|
|
72
|
-
run.metadata.labels[
|
|
73
|
+
run.metadata.labels[mlrun_constants.MLRunInternalLabels.kind] = runtime.kind
|
|
73
74
|
mlrun.runtimes.utils.enrich_run_labels(
|
|
74
|
-
run.metadata.labels, [mlrun.runtimes.constants.RunLabels.owner]
|
|
75
|
+
run.metadata.labels, [mlrun.common.runtimes.constants.RunLabels.owner]
|
|
75
76
|
)
|
|
76
77
|
if run.spec.output_path:
|
|
77
78
|
run.spec.output_path = run.spec.output_path.replace(
|
|
78
|
-
"{{run.user}}",
|
|
79
|
+
"{{run.user}}",
|
|
80
|
+
run.metadata.labels[mlrun_constants.MLRunInternalLabels.owner],
|
|
79
81
|
)
|
|
80
82
|
db = runtime._get_db()
|
|
81
83
|
if db and runtime.kind != "handler":
|
|
@@ -129,7 +131,7 @@ class ClientBaseLauncher(launcher.BaseLauncher, abc.ABC):
|
|
|
129
131
|
logger.info("no returned result (job may still be in progress)")
|
|
130
132
|
results_tbl.append(run.to_dict())
|
|
131
133
|
|
|
132
|
-
if mlrun.utils.is_ipython and mlrun.
|
|
134
|
+
if mlrun.utils.is_ipython and mlrun.mlconf.ipython_widget:
|
|
133
135
|
results_tbl.show()
|
|
134
136
|
print()
|
|
135
137
|
ui_url = mlrun.utils.get_ui_url(project, uid)
|
mlrun/launcher/factory.py
CHANGED
mlrun/launcher/local.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -15,6 +15,7 @@ import os
|
|
|
15
15
|
import pathlib
|
|
16
16
|
from typing import Callable, Optional, Union
|
|
17
17
|
|
|
18
|
+
import mlrun.common.constants as mlrun_constants
|
|
18
19
|
import mlrun.common.schemas.schedule
|
|
19
20
|
import mlrun.errors
|
|
20
21
|
import mlrun.launcher.client as launcher
|
|
@@ -132,8 +133,13 @@ class ClientLocalLauncher(launcher.ClientBaseLauncher):
|
|
|
132
133
|
runtime: "mlrun.runtimes.BaseRuntime",
|
|
133
134
|
run: Optional[Union["mlrun.run.RunTemplate", "mlrun.run.RunObject"]] = None,
|
|
134
135
|
):
|
|
135
|
-
if
|
|
136
|
-
|
|
136
|
+
if (
|
|
137
|
+
"V3IO_USERNAME" in os.environ
|
|
138
|
+
and mlrun_constants.MLRunInternalLabels.v3io_user not in run.metadata.labels
|
|
139
|
+
):
|
|
140
|
+
run.metadata.labels[mlrun_constants.MLRunInternalLabels.v3io_user] = (
|
|
141
|
+
os.environ.get("V3IO_USERNAME")
|
|
142
|
+
)
|
|
137
143
|
|
|
138
144
|
# store function object in db unless running from within a run pod
|
|
139
145
|
if not runtime.is_child:
|
mlrun/launcher/remote.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2023
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -17,6 +17,7 @@ from typing import Optional, Union
|
|
|
17
17
|
import pandas as pd
|
|
18
18
|
import requests
|
|
19
19
|
|
|
20
|
+
import mlrun.common.constants as mlrun_constants
|
|
20
21
|
import mlrun.common.schemas.schedule
|
|
21
22
|
import mlrun.db
|
|
22
23
|
import mlrun.errors
|
|
@@ -100,8 +101,13 @@ class ClientRemoteLauncher(launcher.ClientBaseLauncher):
|
|
|
100
101
|
if runtime.verbose:
|
|
101
102
|
logger.info(f"runspec:\n{run.to_yaml()}")
|
|
102
103
|
|
|
103
|
-
if
|
|
104
|
-
|
|
104
|
+
if (
|
|
105
|
+
"V3IO_USERNAME" in os.environ
|
|
106
|
+
and mlrun_constants.MLRunInternalLabels.v3io_user not in run.metadata.labels
|
|
107
|
+
):
|
|
108
|
+
run.metadata.labels[mlrun_constants.MLRunInternalLabels.v3io_user] = (
|
|
109
|
+
os.environ.get("V3IO_USERNAME")
|
|
110
|
+
)
|
|
105
111
|
|
|
106
112
|
logger.info(
|
|
107
113
|
"Storing function",
|
mlrun/lists.py
CHANGED
|
@@ -21,7 +21,7 @@ import mlrun.frameworks
|
|
|
21
21
|
from .artifacts import Artifact, dict_to_artifact
|
|
22
22
|
from .config import config
|
|
23
23
|
from .render import artifacts_to_html, runs_to_html
|
|
24
|
-
from .utils import flatten, get_artifact_target, get_in
|
|
24
|
+
from .utils import flatten, get_artifact_target, get_in
|
|
25
25
|
|
|
26
26
|
list_header = [
|
|
27
27
|
"project",
|
|
@@ -29,12 +29,14 @@ list_header = [
|
|
|
29
29
|
"iter",
|
|
30
30
|
"start",
|
|
31
31
|
"state",
|
|
32
|
+
"kind",
|
|
32
33
|
"name",
|
|
33
34
|
"labels",
|
|
34
35
|
"inputs",
|
|
35
36
|
"parameters",
|
|
36
37
|
"results",
|
|
37
38
|
"artifacts",
|
|
39
|
+
"artifact_uris",
|
|
38
40
|
"error",
|
|
39
41
|
]
|
|
40
42
|
|
|
@@ -56,12 +58,14 @@ class RunList(list):
|
|
|
56
58
|
get_in(run, "metadata.iteration", ""),
|
|
57
59
|
get_in(run, "status.start_time", ""),
|
|
58
60
|
get_in(run, "status.state", ""),
|
|
61
|
+
get_in(run, "step_kind", get_in(run, "kind", "")),
|
|
59
62
|
get_in(run, "metadata.name", ""),
|
|
60
63
|
get_in(run, "metadata.labels", ""),
|
|
61
64
|
get_in(run, "spec.inputs", ""),
|
|
62
65
|
get_in(run, "spec.parameters", ""),
|
|
63
66
|
get_in(run, "status.results", ""),
|
|
64
67
|
get_in(run, "status.artifacts", []),
|
|
68
|
+
get_in(run, "status.artifact_uris", {}),
|
|
65
69
|
get_in(run, "status.error", ""),
|
|
66
70
|
]
|
|
67
71
|
if extend_iterations and iterations:
|
|
@@ -184,7 +188,7 @@ class ArtifactList(list):
|
|
|
184
188
|
"uri": ["uri", "uri"],
|
|
185
189
|
}
|
|
186
190
|
for artifact in self:
|
|
187
|
-
fields_index =
|
|
191
|
+
fields_index = 1
|
|
188
192
|
row = [get_in(artifact, v[fields_index], "") for k, v in head.items()]
|
|
189
193
|
artifact_uri = dict_to_artifact(artifact).uri
|
|
190
194
|
last_index = len(row) - 1
|
mlrun/model.py
CHANGED
|
@@ -27,13 +27,13 @@ from typing import Any, Optional, Union
|
|
|
27
27
|
import pydantic.error_wrappers
|
|
28
28
|
|
|
29
29
|
import mlrun
|
|
30
|
+
import mlrun.common.constants as mlrun_constants
|
|
30
31
|
import mlrun.common.schemas.notification
|
|
31
32
|
|
|
32
33
|
from .utils import (
|
|
33
34
|
dict_to_json,
|
|
34
35
|
dict_to_yaml,
|
|
35
36
|
get_artifact_target,
|
|
36
|
-
is_legacy_artifact,
|
|
37
37
|
logger,
|
|
38
38
|
template_artifact_path,
|
|
39
39
|
)
|
|
@@ -71,6 +71,7 @@ class ModelObj:
|
|
|
71
71
|
return new_type.from_dict(param)
|
|
72
72
|
return param
|
|
73
73
|
|
|
74
|
+
@mlrun.utils.filter_warnings("ignore", FutureWarning)
|
|
74
75
|
def to_dict(
|
|
75
76
|
self, fields: list = None, exclude: list = None, strip: bool = False
|
|
76
77
|
) -> dict:
|
|
@@ -681,10 +682,14 @@ class Notification(ModelObj):
|
|
|
681
682
|
|
|
682
683
|
def __init__(
|
|
683
684
|
self,
|
|
684
|
-
kind=
|
|
685
|
+
kind: mlrun.common.schemas.notification.NotificationKind = (
|
|
686
|
+
mlrun.common.schemas.notification.NotificationKind.slack
|
|
687
|
+
),
|
|
685
688
|
name=None,
|
|
686
689
|
message=None,
|
|
687
|
-
severity=
|
|
690
|
+
severity: mlrun.common.schemas.notification.NotificationSeverity = (
|
|
691
|
+
mlrun.common.schemas.notification.NotificationSeverity.INFO
|
|
692
|
+
),
|
|
688
693
|
when=None,
|
|
689
694
|
condition=None,
|
|
690
695
|
secret_params=None,
|
|
@@ -693,12 +698,10 @@ class Notification(ModelObj):
|
|
|
693
698
|
sent_time=None,
|
|
694
699
|
reason=None,
|
|
695
700
|
):
|
|
696
|
-
self.kind = kind
|
|
701
|
+
self.kind = kind
|
|
697
702
|
self.name = name or ""
|
|
698
703
|
self.message = message or ""
|
|
699
|
-
self.severity =
|
|
700
|
-
severity or mlrun.common.schemas.notification.NotificationSeverity.INFO
|
|
701
|
-
)
|
|
704
|
+
self.severity = severity
|
|
702
705
|
self.when = when or ["completed"]
|
|
703
706
|
self.condition = condition or ""
|
|
704
707
|
self.secret_params = secret_params or {}
|
|
@@ -765,6 +768,14 @@ class RunMetadata(ModelObj):
|
|
|
765
768
|
def iteration(self, iteration):
|
|
766
769
|
self._iteration = iteration
|
|
767
770
|
|
|
771
|
+
def is_workflow_runner(self):
|
|
772
|
+
if not self.labels:
|
|
773
|
+
return False
|
|
774
|
+
return (
|
|
775
|
+
self.labels.get(mlrun_constants.MLRunInternalLabels.job_type, "")
|
|
776
|
+
== "workflow-runner"
|
|
777
|
+
)
|
|
778
|
+
|
|
768
779
|
|
|
769
780
|
class HyperParamStrategies:
|
|
770
781
|
grid = "grid"
|
|
@@ -930,7 +941,7 @@ class RunSpec(ModelObj):
|
|
|
930
941
|
|
|
931
942
|
>>> run_spec.inputs = {
|
|
932
943
|
... "my_input": "...",
|
|
933
|
-
... "my_hinted_input : pandas.DataFrame": "..."
|
|
944
|
+
... "my_hinted_input : pandas.DataFrame": "...",
|
|
934
945
|
... }
|
|
935
946
|
|
|
936
947
|
:param inputs: The inputs to set.
|
|
@@ -1202,6 +1213,7 @@ class RunStatus(ModelObj):
|
|
|
1202
1213
|
ui_url=None,
|
|
1203
1214
|
reason: str = None,
|
|
1204
1215
|
notifications: dict[str, Notification] = None,
|
|
1216
|
+
artifact_uris: dict[str, str] = None,
|
|
1205
1217
|
):
|
|
1206
1218
|
self.state = state or "created"
|
|
1207
1219
|
self.status_text = status_text
|
|
@@ -1216,6 +1228,21 @@ class RunStatus(ModelObj):
|
|
|
1216
1228
|
self.ui_url = ui_url
|
|
1217
1229
|
self.reason = reason
|
|
1218
1230
|
self.notifications = notifications or {}
|
|
1231
|
+
# Artifact key -> URI mapping, since the full artifacts are not stored in the runs DB table
|
|
1232
|
+
self.artifact_uris = artifact_uris or {}
|
|
1233
|
+
|
|
1234
|
+
def is_failed(self) -> Optional[bool]:
|
|
1235
|
+
"""
|
|
1236
|
+
This method returns whether a run has failed.
|
|
1237
|
+
Returns none if state has yet to be defined. callee is responsible for handling None.
|
|
1238
|
+
(e.g wait for state to be defined)
|
|
1239
|
+
"""
|
|
1240
|
+
if not self.state:
|
|
1241
|
+
return None
|
|
1242
|
+
return self.state.casefold() in [
|
|
1243
|
+
mlrun.run.RunStatuses.failed.casefold(),
|
|
1244
|
+
mlrun.run.RunStatuses.error.casefold(),
|
|
1245
|
+
]
|
|
1219
1246
|
|
|
1220
1247
|
|
|
1221
1248
|
class RunTemplate(ModelObj):
|
|
@@ -1274,7 +1301,7 @@ class RunTemplate(ModelObj):
|
|
|
1274
1301
|
|
|
1275
1302
|
example::
|
|
1276
1303
|
|
|
1277
|
-
grid_params = {"p1": [2,4,1], "p2": [10,20]}
|
|
1304
|
+
grid_params = {"p1": [2, 4, 1], "p2": [10, 20]}
|
|
1278
1305
|
task = mlrun.new_task("grid-search")
|
|
1279
1306
|
task.with_hyper_params(grid_params, selector="max.accuracy")
|
|
1280
1307
|
"""
|
|
@@ -1416,11 +1443,14 @@ class RunObject(RunTemplate):
|
|
|
1416
1443
|
unknown_error = ""
|
|
1417
1444
|
if (
|
|
1418
1445
|
self.status.state
|
|
1419
|
-
in mlrun.runtimes.constants.RunStates.abortion_states()
|
|
1446
|
+
in mlrun.common.runtimes.constants.RunStates.abortion_states()
|
|
1420
1447
|
):
|
|
1421
1448
|
unknown_error = "Run was aborted"
|
|
1422
1449
|
|
|
1423
|
-
elif
|
|
1450
|
+
elif (
|
|
1451
|
+
self.status.state
|
|
1452
|
+
in mlrun.common.runtimes.constants.RunStates.error_states()
|
|
1453
|
+
):
|
|
1424
1454
|
unknown_error = "Unknown error"
|
|
1425
1455
|
|
|
1426
1456
|
return (
|
|
@@ -1458,7 +1488,7 @@ class RunObject(RunTemplate):
|
|
|
1458
1488
|
outputs = {k: v for k, v in self.status.results.items()}
|
|
1459
1489
|
if self.status.artifacts:
|
|
1460
1490
|
for a in self.status.artifacts:
|
|
1461
|
-
key = a["
|
|
1491
|
+
key = a["metadata"]["key"]
|
|
1462
1492
|
outputs[key] = get_artifact_target(a, self.metadata.project)
|
|
1463
1493
|
return outputs
|
|
1464
1494
|
|
|
@@ -1501,7 +1531,10 @@ class RunObject(RunTemplate):
|
|
|
1501
1531
|
|
|
1502
1532
|
def state(self):
|
|
1503
1533
|
"""current run state"""
|
|
1504
|
-
if
|
|
1534
|
+
if (
|
|
1535
|
+
self.status.state
|
|
1536
|
+
in mlrun.common.runtimes.constants.RunStates.terminal_states()
|
|
1537
|
+
):
|
|
1505
1538
|
return self.status.state
|
|
1506
1539
|
self.refresh()
|
|
1507
1540
|
return self.status.state or "unknown"
|
|
@@ -1515,8 +1548,10 @@ class RunObject(RunTemplate):
|
|
|
1515
1548
|
iter=self.metadata.iteration,
|
|
1516
1549
|
)
|
|
1517
1550
|
if run:
|
|
1518
|
-
|
|
1519
|
-
|
|
1551
|
+
run_status = run.get("status", {})
|
|
1552
|
+
# Artifacts are not stored in the DB, so we need to preserve them here
|
|
1553
|
+
run_status["artifacts"] = self.status.artifacts
|
|
1554
|
+
self.status = RunStatus.from_dict(run_status)
|
|
1520
1555
|
return self
|
|
1521
1556
|
|
|
1522
1557
|
def show(self):
|
|
@@ -1563,7 +1598,7 @@ class RunObject(RunTemplate):
|
|
|
1563
1598
|
last_pull_log_time = None
|
|
1564
1599
|
logs_enabled = show_logs is not False
|
|
1565
1600
|
state = self.state()
|
|
1566
|
-
if state not in mlrun.runtimes.constants.RunStates.terminal_states():
|
|
1601
|
+
if state not in mlrun.common.runtimes.constants.RunStates.terminal_states():
|
|
1567
1602
|
logger.info(
|
|
1568
1603
|
f"run {self.metadata.name} is not completed yet, waiting for it to complete",
|
|
1569
1604
|
current_state=state,
|
|
@@ -1573,7 +1608,8 @@ class RunObject(RunTemplate):
|
|
|
1573
1608
|
if (
|
|
1574
1609
|
logs_enabled
|
|
1575
1610
|
and logs_interval
|
|
1576
|
-
and state
|
|
1611
|
+
and state
|
|
1612
|
+
not in mlrun.common.runtimes.constants.RunStates.terminal_states()
|
|
1577
1613
|
and (
|
|
1578
1614
|
last_pull_log_time is None
|
|
1579
1615
|
or (datetime.now() - last_pull_log_time).seconds > logs_interval
|
|
@@ -1582,7 +1618,7 @@ class RunObject(RunTemplate):
|
|
|
1582
1618
|
last_pull_log_time = datetime.now()
|
|
1583
1619
|
state, offset = self.logs(watch=False, offset=offset)
|
|
1584
1620
|
|
|
1585
|
-
if state in mlrun.runtimes.constants.RunStates.terminal_states():
|
|
1621
|
+
if state in mlrun.common.runtimes.constants.RunStates.terminal_states():
|
|
1586
1622
|
if logs_enabled and logs_interval:
|
|
1587
1623
|
self.logs(watch=False, offset=offset)
|
|
1588
1624
|
break
|
|
@@ -1594,7 +1630,10 @@ class RunObject(RunTemplate):
|
|
|
1594
1630
|
)
|
|
1595
1631
|
if logs_enabled and not logs_interval:
|
|
1596
1632
|
self.logs(watch=False)
|
|
1597
|
-
if
|
|
1633
|
+
if (
|
|
1634
|
+
raise_on_failure
|
|
1635
|
+
and state != mlrun.common.runtimes.constants.RunStates.completed
|
|
1636
|
+
):
|
|
1598
1637
|
raise mlrun.errors.MLRunRuntimeError(
|
|
1599
1638
|
f"Task {self.metadata.name} did not complete (state={state})"
|
|
1600
1639
|
)
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
16
16
|
# for backwards compatibility
|
|
17
17
|
|
|
18
|
+
from .db import get_store_object, get_tsdb_connector
|
|
18
19
|
from .helpers import get_stream_path
|
|
19
20
|
from .model_endpoint import ModelEndpoint
|
|
20
|
-
from .stores import ModelEndpointStore, ModelEndpointStoreType, get_model_endpoint_store
|
|
21
21
|
from .tracking_policy import TrackingPolicy
|