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
mlrun/render.py
CHANGED
|
@@ -121,20 +121,12 @@ def artifacts_html(
|
|
|
121
121
|
html = ""
|
|
122
122
|
|
|
123
123
|
for artifact in artifacts:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
attribute_value = artifact.get(attribute_name)
|
|
127
|
-
else:
|
|
128
|
-
attribute_value = artifact["spec"].get(attribute_name)
|
|
129
|
-
|
|
130
|
-
if mlrun.utils.is_legacy_artifact(artifact):
|
|
131
|
-
key = artifact["key"]
|
|
132
|
-
else:
|
|
133
|
-
key = artifact["metadata"]["key"]
|
|
124
|
+
attribute_value = artifact["spec"].get(attribute_name)
|
|
125
|
+
key = artifact["metadata"]["key"]
|
|
134
126
|
|
|
135
127
|
if not attribute_value:
|
|
136
128
|
mlrun.utils.logger.warning(
|
|
137
|
-
"Artifact is
|
|
129
|
+
f"Artifact required attribute {attribute_name} is missing, omitting from output",
|
|
138
130
|
artifact_key=key,
|
|
139
131
|
)
|
|
140
132
|
continue
|
|
@@ -404,12 +396,21 @@ def runs_to_html(
|
|
|
404
396
|
df.drop("labels", axis=1, inplace=True)
|
|
405
397
|
df.drop("inputs", axis=1, inplace=True)
|
|
406
398
|
df.drop("artifacts", axis=1, inplace=True)
|
|
399
|
+
df.drop("artifact_uris", axis=1, inplace=True)
|
|
407
400
|
else:
|
|
408
401
|
df["labels"] = df["labels"].apply(dict_html)
|
|
409
402
|
df["inputs"] = df["inputs"].apply(inputs_html)
|
|
410
|
-
df["artifacts"]
|
|
411
|
-
|
|
412
|
-
|
|
403
|
+
if df["artifacts"][0]:
|
|
404
|
+
df["artifacts"] = df["artifacts"].apply(
|
|
405
|
+
lambda artifacts: artifacts_html(artifacts, "target_path"),
|
|
406
|
+
)
|
|
407
|
+
df.drop("artifact_uris", axis=1, inplace=True)
|
|
408
|
+
elif df["artifact_uris"][0]:
|
|
409
|
+
df["artifact_uris"] = df["artifact_uris"].apply(dict_html)
|
|
410
|
+
df.drop("artifacts", axis=1, inplace=True)
|
|
411
|
+
else:
|
|
412
|
+
df.drop("artifacts", axis=1, inplace=True)
|
|
413
|
+
df.drop("artifact_uris", axis=1, inplace=True)
|
|
413
414
|
|
|
414
415
|
def expand_error(x):
|
|
415
416
|
if x["state"] == "error":
|
mlrun/run.py
CHANGED
|
@@ -29,12 +29,13 @@ from typing import Optional, Union
|
|
|
29
29
|
import nuclio
|
|
30
30
|
import yaml
|
|
31
31
|
from kfp import Client
|
|
32
|
+
from mlrun_pipelines.common.models import RunStatuses
|
|
33
|
+
from mlrun_pipelines.common.ops import format_summary_from_kfp_run, show_kfp_run
|
|
32
34
|
|
|
35
|
+
import mlrun.common.formatters
|
|
33
36
|
import mlrun.common.schemas
|
|
34
37
|
import mlrun.errors
|
|
35
38
|
import mlrun.utils.helpers
|
|
36
|
-
from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
|
|
37
|
-
from mlrun.runtimes.nuclio.serving import serving_subkind
|
|
38
39
|
|
|
39
40
|
from .common.helpers import parse_versioned_object_uri
|
|
40
41
|
from .config import config as mlconf
|
|
@@ -48,7 +49,6 @@ from .runtimes import (
|
|
|
48
49
|
KubejobRuntime,
|
|
49
50
|
LocalRuntime,
|
|
50
51
|
MpiRuntimeV1,
|
|
51
|
-
MpiRuntimeV1Alpha1,
|
|
52
52
|
RemoteRuntime,
|
|
53
53
|
RemoteSparkRuntime,
|
|
54
54
|
RuntimeKinds,
|
|
@@ -58,6 +58,7 @@ from .runtimes import (
|
|
|
58
58
|
)
|
|
59
59
|
from .runtimes.databricks_job.databricks_runtime import DatabricksRuntime
|
|
60
60
|
from .runtimes.funcdoc import update_function_entry_points
|
|
61
|
+
from .runtimes.nuclio.application import ApplicationRuntime
|
|
61
62
|
from .runtimes.utils import add_code_metadata, global_context
|
|
62
63
|
from .utils import (
|
|
63
64
|
extend_hub_uri_if_needed,
|
|
@@ -69,41 +70,6 @@ from .utils import (
|
|
|
69
70
|
)
|
|
70
71
|
|
|
71
72
|
|
|
72
|
-
class RunStatuses:
|
|
73
|
-
succeeded = "Succeeded"
|
|
74
|
-
failed = "Failed"
|
|
75
|
-
skipped = "Skipped"
|
|
76
|
-
error = "Error"
|
|
77
|
-
running = "Running"
|
|
78
|
-
|
|
79
|
-
@staticmethod
|
|
80
|
-
def all():
|
|
81
|
-
return [
|
|
82
|
-
RunStatuses.succeeded,
|
|
83
|
-
RunStatuses.failed,
|
|
84
|
-
RunStatuses.skipped,
|
|
85
|
-
RunStatuses.error,
|
|
86
|
-
RunStatuses.running,
|
|
87
|
-
]
|
|
88
|
-
|
|
89
|
-
@staticmethod
|
|
90
|
-
def stable_statuses():
|
|
91
|
-
return [
|
|
92
|
-
RunStatuses.succeeded,
|
|
93
|
-
RunStatuses.failed,
|
|
94
|
-
RunStatuses.skipped,
|
|
95
|
-
RunStatuses.error,
|
|
96
|
-
]
|
|
97
|
-
|
|
98
|
-
@staticmethod
|
|
99
|
-
def transient_statuses():
|
|
100
|
-
return [
|
|
101
|
-
status
|
|
102
|
-
for status in RunStatuses.all()
|
|
103
|
-
if status not in RunStatuses.stable_statuses()
|
|
104
|
-
]
|
|
105
|
-
|
|
106
|
-
|
|
107
73
|
def function_to_module(code="", workdir=None, secrets=None, silent=False):
|
|
108
74
|
"""Load code, notebook or mlrun function as .py module
|
|
109
75
|
this function can import a local/remote py file or notebook
|
|
@@ -114,16 +80,18 @@ def function_to_module(code="", workdir=None, secrets=None, silent=False):
|
|
|
114
80
|
|
|
115
81
|
example::
|
|
116
82
|
|
|
117
|
-
mod = mlrun.function_to_module(
|
|
118
|
-
task = mlrun.new_task(inputs={
|
|
119
|
-
context = mlrun.get_or_create_ctx(
|
|
120
|
-
mod.my_job(context, p1=1, p2=
|
|
83
|
+
mod = mlrun.function_to_module("./examples/training.py")
|
|
84
|
+
task = mlrun.new_task(inputs={"infile.txt": "../examples/infile.txt"})
|
|
85
|
+
context = mlrun.get_or_create_ctx("myfunc", spec=task)
|
|
86
|
+
mod.my_job(context, p1=1, p2="x")
|
|
121
87
|
print(context.to_yaml())
|
|
122
88
|
|
|
123
|
-
fn = mlrun.import_function(
|
|
89
|
+
fn = mlrun.import_function("hub://open-archive")
|
|
124
90
|
mod = mlrun.function_to_module(fn)
|
|
125
|
-
data = mlrun.run.get_dataitem(
|
|
126
|
-
|
|
91
|
+
data = mlrun.run.get_dataitem(
|
|
92
|
+
"https://fpsignals-public.s3.amazonaws.com/catsndogs.tar.gz"
|
|
93
|
+
)
|
|
94
|
+
context = mlrun.get_or_create_ctx("myfunc")
|
|
127
95
|
mod.open_archive(context, archive_url=data)
|
|
128
96
|
print(context.to_yaml())
|
|
129
97
|
|
|
@@ -256,29 +224,31 @@ def get_or_create_ctx(
|
|
|
256
224
|
Examples::
|
|
257
225
|
|
|
258
226
|
# load MLRUN runtime context (will be set by the runtime framework e.g. KubeFlow)
|
|
259
|
-
context = get_or_create_ctx(
|
|
227
|
+
context = get_or_create_ctx("train")
|
|
260
228
|
|
|
261
229
|
# get parameters from the runtime context (or use defaults)
|
|
262
|
-
p1 = context.get_param(
|
|
263
|
-
p2 = context.get_param(
|
|
230
|
+
p1 = context.get_param("p1", 1)
|
|
231
|
+
p2 = context.get_param("p2", "a-string")
|
|
264
232
|
|
|
265
233
|
# access input metadata, values, files, and secrets (passwords)
|
|
266
|
-
print(f
|
|
267
|
-
print(f
|
|
234
|
+
print(f"Run: {context.name} (uid={context.uid})")
|
|
235
|
+
print(f"Params: p1={p1}, p2={p2}")
|
|
268
236
|
print(f'accesskey = {context.get_secret("ACCESS_KEY")}')
|
|
269
|
-
input_str = context.get_input(
|
|
270
|
-
print(f
|
|
237
|
+
input_str = context.get_input("infile.txt").get()
|
|
238
|
+
print(f"file: {input_str}")
|
|
271
239
|
|
|
272
240
|
# RUN some useful code e.g. ML training, data prep, etc.
|
|
273
241
|
|
|
274
242
|
# log scalar result values (job result metrics)
|
|
275
|
-
context.log_result(
|
|
276
|
-
context.log_result(
|
|
277
|
-
context.set_label(
|
|
243
|
+
context.log_result("accuracy", p1 * 2)
|
|
244
|
+
context.log_result("loss", p1 * 3)
|
|
245
|
+
context.set_label("framework", "sklearn")
|
|
278
246
|
|
|
279
247
|
# log various types of artifacts (file, web page, table), will be versioned and visible in the UI
|
|
280
|
-
context.log_artifact(
|
|
281
|
-
|
|
248
|
+
context.log_artifact(
|
|
249
|
+
"model.txt", body=b"abc is 123", labels={"framework": "xgboost"}
|
|
250
|
+
)
|
|
251
|
+
context.log_artifact("results.html", body=b"<b> Some HTML <b>", viewer="web-app")
|
|
282
252
|
|
|
283
253
|
"""
|
|
284
254
|
|
|
@@ -348,7 +318,9 @@ def import_function(url="", secrets=None, db="", project=None, new_name=None):
|
|
|
348
318
|
|
|
349
319
|
function = mlrun.import_function("hub://auto-trainer")
|
|
350
320
|
function = mlrun.import_function("./func.yaml")
|
|
351
|
-
function = mlrun.import_function(
|
|
321
|
+
function = mlrun.import_function(
|
|
322
|
+
"https://raw.githubusercontent.com/org/repo/func.yaml"
|
|
323
|
+
)
|
|
352
324
|
|
|
353
325
|
:param url: path/url to Function Hub, db or function YAML file
|
|
354
326
|
:param secrets: optional, credentials dict for DB or URL (s3, v3io, ...)
|
|
@@ -389,6 +361,8 @@ def import_function_to_dict(url, secrets=None):
|
|
|
389
361
|
code = get_in(runtime, "spec.build.functionSourceCode")
|
|
390
362
|
update_in(runtime, "metadata.build.code_origin", url)
|
|
391
363
|
cmd = code_file = get_in(runtime, "spec.command", "")
|
|
364
|
+
# use kind = "job" by default if not specified
|
|
365
|
+
runtime.setdefault("kind", "job")
|
|
392
366
|
if " " in cmd:
|
|
393
367
|
code_file = cmd[: cmd.find(" ")]
|
|
394
368
|
if runtime["kind"] in ["", "local"]:
|
|
@@ -425,19 +399,19 @@ def import_function_to_dict(url, secrets=None):
|
|
|
425
399
|
|
|
426
400
|
|
|
427
401
|
def new_function(
|
|
428
|
-
name: str = "",
|
|
429
|
-
project: str = "",
|
|
430
|
-
tag: str = "",
|
|
431
|
-
kind: str = "",
|
|
432
|
-
command: str = "",
|
|
433
|
-
image: str = "",
|
|
434
|
-
args: list = None,
|
|
435
|
-
runtime=None,
|
|
436
|
-
mode=None,
|
|
437
|
-
handler: str = None,
|
|
438
|
-
source: str = None,
|
|
402
|
+
name: Optional[str] = "",
|
|
403
|
+
project: Optional[str] = "",
|
|
404
|
+
tag: Optional[str] = "",
|
|
405
|
+
kind: Optional[str] = "",
|
|
406
|
+
command: Optional[str] = "",
|
|
407
|
+
image: Optional[str] = "",
|
|
408
|
+
args: Optional[list] = None,
|
|
409
|
+
runtime: Optional[Union[mlrun.runtimes.BaseRuntime, dict]] = None,
|
|
410
|
+
mode: Optional[str] = None,
|
|
411
|
+
handler: Optional[str] = None,
|
|
412
|
+
source: Optional[str] = None,
|
|
439
413
|
requirements: Union[str, list[str]] = None,
|
|
440
|
-
kfp=None,
|
|
414
|
+
kfp: Optional[bool] = None,
|
|
441
415
|
requirements_file: str = "",
|
|
442
416
|
):
|
|
443
417
|
"""Create a new ML function from base properties
|
|
@@ -445,12 +419,18 @@ def new_function(
|
|
|
445
419
|
Example::
|
|
446
420
|
|
|
447
421
|
# define a container based function (the `training.py` must exist in the container workdir)
|
|
448
|
-
f = new_function(
|
|
422
|
+
f = new_function(
|
|
423
|
+
command="training.py -x {x}", image="myrepo/image:latest", kind="job"
|
|
424
|
+
)
|
|
449
425
|
f.run(params={"x": 5})
|
|
450
426
|
|
|
451
427
|
# define a container based function which reads its source from a git archive
|
|
452
|
-
f = new_function(
|
|
453
|
-
|
|
428
|
+
f = new_function(
|
|
429
|
+
command="training.py -x {x}",
|
|
430
|
+
image="myrepo/image:latest",
|
|
431
|
+
kind="job",
|
|
432
|
+
source="git://github.com/mlrun/something.git",
|
|
433
|
+
)
|
|
454
434
|
f.run(params={"x": 5})
|
|
455
435
|
|
|
456
436
|
# define a local handler function (execute a local function handler)
|
|
@@ -535,9 +515,9 @@ def new_function(
|
|
|
535
515
|
if source:
|
|
536
516
|
runner.spec.build.source = source
|
|
537
517
|
if handler:
|
|
538
|
-
if kind
|
|
518
|
+
if kind in RuntimeKinds.handlerless_runtimes():
|
|
539
519
|
raise MLRunInvalidArgumentError(
|
|
540
|
-
"
|
|
520
|
+
f"Handler is not supported for {kind} runtime"
|
|
541
521
|
)
|
|
542
522
|
elif kind in RuntimeKinds.nuclio_runtimes():
|
|
543
523
|
runner.spec.function_handler = handler
|
|
@@ -575,24 +555,23 @@ def _process_runtime(command, runtime, kind):
|
|
|
575
555
|
|
|
576
556
|
|
|
577
557
|
def code_to_function(
|
|
578
|
-
name: str = "",
|
|
579
|
-
project: str = "",
|
|
580
|
-
tag: str = "",
|
|
581
|
-
filename: str = "",
|
|
582
|
-
handler: str = "",
|
|
583
|
-
kind: str = "",
|
|
584
|
-
image: str = None,
|
|
585
|
-
code_output: str = "",
|
|
558
|
+
name: Optional[str] = "",
|
|
559
|
+
project: Optional[str] = "",
|
|
560
|
+
tag: Optional[str] = "",
|
|
561
|
+
filename: Optional[str] = "",
|
|
562
|
+
handler: Optional[str] = "",
|
|
563
|
+
kind: Optional[str] = "",
|
|
564
|
+
image: Optional[str] = None,
|
|
565
|
+
code_output: Optional[str] = "",
|
|
586
566
|
embed_code: bool = True,
|
|
587
|
-
description: str = "",
|
|
588
|
-
requirements: Union[str, list[str]] = None,
|
|
589
|
-
categories: list[str] = None,
|
|
590
|
-
labels: dict[str, str] = None,
|
|
591
|
-
with_doc: bool = True,
|
|
592
|
-
ignored_tags=None,
|
|
593
|
-
requirements_file: str = "",
|
|
567
|
+
description: Optional[str] = "",
|
|
568
|
+
requirements: Optional[Union[str, list[str]]] = None,
|
|
569
|
+
categories: Optional[list[str]] = None,
|
|
570
|
+
labels: Optional[dict[str, str]] = None,
|
|
571
|
+
with_doc: Optional[bool] = True,
|
|
572
|
+
ignored_tags: Optional[str] = None,
|
|
573
|
+
requirements_file: Optional[str] = "",
|
|
594
574
|
) -> Union[
|
|
595
|
-
MpiRuntimeV1Alpha1,
|
|
596
575
|
MpiRuntimeV1,
|
|
597
576
|
RemoteRuntime,
|
|
598
577
|
ServingRuntime,
|
|
@@ -602,6 +581,7 @@ def code_to_function(
|
|
|
602
581
|
Spark3Runtime,
|
|
603
582
|
RemoteSparkRuntime,
|
|
604
583
|
DatabricksRuntime,
|
|
584
|
+
ApplicationRuntime,
|
|
605
585
|
]:
|
|
606
586
|
"""Convenience function to insert code and configure an mlrun runtime.
|
|
607
587
|
|
|
@@ -627,8 +607,10 @@ def code_to_function(
|
|
|
627
607
|
- mpijob: run distributed Horovod jobs over the MPI job operator
|
|
628
608
|
- spark: run distributed Spark job using Spark Kubernetes Operator
|
|
629
609
|
- remote-spark: run distributed Spark job on remote Spark service
|
|
610
|
+
- databricks: run code on Databricks cluster (python scripts, Spark etc.)
|
|
611
|
+
- application: run a long living application (e.g. a web server, UI, etc.)
|
|
630
612
|
|
|
631
|
-
Learn more about
|
|
613
|
+
Learn more about [Kinds of function (runtimes)](../concepts/functions-overview.html).
|
|
632
614
|
|
|
633
615
|
:param name: function name, typically best to use hyphen-case
|
|
634
616
|
:param project: project used to namespace the function, defaults to 'default'
|
|
@@ -644,7 +626,6 @@ def code_to_function(
|
|
|
644
626
|
:param embed_code: indicates whether or not to inject the code directly into the function runtime spec,
|
|
645
627
|
defaults to True
|
|
646
628
|
:param description: short function description, defaults to ''
|
|
647
|
-
:param requirements: list of python packages or pip requirements file path, defaults to None
|
|
648
629
|
:param requirements: a list of python packages
|
|
649
630
|
:param requirements_file: path to a python requirements file
|
|
650
631
|
:param categories: list of categories for mlrun Function Hub, defaults to None
|
|
@@ -660,11 +641,15 @@ def code_to_function(
|
|
|
660
641
|
import mlrun
|
|
661
642
|
|
|
662
643
|
# create job function object from notebook code and add doc/metadata
|
|
663
|
-
fn = mlrun.code_to_function(
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
644
|
+
fn = mlrun.code_to_function(
|
|
645
|
+
"file_utils",
|
|
646
|
+
kind="job",
|
|
647
|
+
handler="open_archive",
|
|
648
|
+
image="mlrun/mlrun",
|
|
649
|
+
description="this function opens a zip archive into a local/mounted folder",
|
|
650
|
+
categories=["fileutils"],
|
|
651
|
+
labels={"author": "me"},
|
|
652
|
+
)
|
|
668
653
|
|
|
669
654
|
example::
|
|
670
655
|
|
|
@@ -675,11 +660,15 @@ def code_to_function(
|
|
|
675
660
|
Path("mover.py").touch()
|
|
676
661
|
|
|
677
662
|
# create nuclio function object from python module call mover.py
|
|
678
|
-
fn = mlrun.code_to_function(
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
663
|
+
fn = mlrun.code_to_function(
|
|
664
|
+
"nuclio-mover",
|
|
665
|
+
kind="nuclio",
|
|
666
|
+
filename="mover.py",
|
|
667
|
+
image="python:3.9",
|
|
668
|
+
description="this function moves files from one system to another",
|
|
669
|
+
requirements=["pandas"],
|
|
670
|
+
labels={"author": "me"},
|
|
671
|
+
)
|
|
683
672
|
|
|
684
673
|
"""
|
|
685
674
|
filebase, _ = path.splitext(path.basename(filename))
|
|
@@ -718,35 +707,34 @@ def code_to_function(
|
|
|
718
707
|
fn.metadata.categories = categories
|
|
719
708
|
fn.metadata.labels = labels or fn.metadata.labels
|
|
720
709
|
|
|
721
|
-
def resolve_nuclio_subkind(kind):
|
|
722
|
-
is_nuclio = kind.startswith("nuclio")
|
|
723
|
-
subkind = kind[kind.find(":") + 1 :] if is_nuclio and ":" in kind else None
|
|
724
|
-
if kind == RuntimeKinds.serving:
|
|
725
|
-
is_nuclio = True
|
|
726
|
-
subkind = serving_subkind
|
|
727
|
-
return is_nuclio, subkind
|
|
728
|
-
|
|
729
710
|
if (
|
|
730
711
|
not embed_code
|
|
731
712
|
and not code_output
|
|
732
713
|
and (not filename or filename.endswith(".ipynb"))
|
|
733
714
|
):
|
|
734
715
|
raise ValueError(
|
|
735
|
-
"
|
|
716
|
+
"A valid code file must be specified "
|
|
736
717
|
"when not using the embed_code option"
|
|
737
718
|
)
|
|
738
719
|
|
|
739
720
|
if kind == RuntimeKinds.databricks and not embed_code:
|
|
740
|
-
raise ValueError("
|
|
721
|
+
raise ValueError("Databricks tasks only support embed_code=True")
|
|
722
|
+
|
|
723
|
+
if kind == RuntimeKinds.application:
|
|
724
|
+
if handler:
|
|
725
|
+
raise MLRunInvalidArgumentError(
|
|
726
|
+
"Handler is not supported for application runtime"
|
|
727
|
+
)
|
|
728
|
+
filename, handler = ApplicationRuntime.get_filename_and_handler()
|
|
741
729
|
|
|
742
|
-
is_nuclio,
|
|
730
|
+
is_nuclio, sub_kind = RuntimeKinds.resolve_nuclio_sub_kind(kind)
|
|
743
731
|
code_origin = add_name(add_code_metadata(filename), name)
|
|
744
732
|
|
|
745
733
|
name, spec, code = nuclio.build_file(
|
|
746
734
|
filename,
|
|
747
735
|
name=name,
|
|
748
736
|
handler=handler or "handler",
|
|
749
|
-
kind=
|
|
737
|
+
kind=sub_kind,
|
|
750
738
|
ignored_tags=ignored_tags,
|
|
751
739
|
)
|
|
752
740
|
spec["spec"]["env"].append(
|
|
@@ -759,14 +747,14 @@ def code_to_function(
|
|
|
759
747
|
if not kind and spec_kind not in ["", "Function"]:
|
|
760
748
|
kind = spec_kind.lower()
|
|
761
749
|
|
|
762
|
-
# if its a nuclio
|
|
763
|
-
is_nuclio,
|
|
750
|
+
# if its a nuclio sub kind, redo nb parsing
|
|
751
|
+
is_nuclio, sub_kind = RuntimeKinds.resolve_nuclio_sub_kind(kind)
|
|
764
752
|
if is_nuclio:
|
|
765
753
|
name, spec, code = nuclio.build_file(
|
|
766
754
|
filename,
|
|
767
755
|
name=name,
|
|
768
756
|
handler=handler or "handler",
|
|
769
|
-
kind=
|
|
757
|
+
kind=sub_kind,
|
|
770
758
|
ignored_tags=ignored_tags,
|
|
771
759
|
)
|
|
772
760
|
|
|
@@ -780,33 +768,29 @@ def code_to_function(
|
|
|
780
768
|
raise ValueError("code_output option is only used with notebooks")
|
|
781
769
|
|
|
782
770
|
if is_nuclio:
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
else
|
|
786
|
-
|
|
787
|
-
r.spec.function_kind = subkind
|
|
788
|
-
# default_handler is only used in :mlrun subkind, determine the handler to invoke in function.run()
|
|
789
|
-
r.spec.default_handler = handler if subkind == "mlrun" else ""
|
|
790
|
-
r.spec.function_handler = (
|
|
771
|
+
runtime = RuntimeKinds.resolve_nuclio_runtime(kind, sub_kind)
|
|
772
|
+
# default_handler is only used in :mlrun sub kind, determine the handler to invoke in function.run()
|
|
773
|
+
runtime.spec.default_handler = handler if sub_kind == "mlrun" else ""
|
|
774
|
+
runtime.spec.function_handler = (
|
|
791
775
|
handler if handler and ":" in handler else get_in(spec, "spec.handler")
|
|
792
776
|
)
|
|
793
777
|
if not embed_code:
|
|
794
|
-
|
|
778
|
+
runtime.spec.source = filename
|
|
795
779
|
nuclio_runtime = get_in(spec, "spec.runtime")
|
|
796
780
|
if nuclio_runtime and not nuclio_runtime.startswith("py"):
|
|
797
|
-
|
|
781
|
+
runtime.spec.nuclio_runtime = nuclio_runtime
|
|
798
782
|
if not name:
|
|
799
|
-
raise ValueError("
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
update_common(
|
|
804
|
-
return
|
|
783
|
+
raise ValueError("Missing required parameter: name")
|
|
784
|
+
runtime.metadata.name = name
|
|
785
|
+
runtime.spec.build.code_origin = code_origin
|
|
786
|
+
runtime.spec.build.origin_filename = filename or (name + ".ipynb")
|
|
787
|
+
update_common(runtime, spec)
|
|
788
|
+
return runtime
|
|
805
789
|
|
|
806
790
|
if kind is None or kind in ["", "Function"]:
|
|
807
791
|
raise ValueError("please specify the function kind")
|
|
808
792
|
elif kind in RuntimeKinds.all():
|
|
809
|
-
|
|
793
|
+
runtime = get_runtime_class(kind)()
|
|
810
794
|
else:
|
|
811
795
|
raise ValueError(f"unsupported runtime ({kind})")
|
|
812
796
|
|
|
@@ -815,10 +799,10 @@ def code_to_function(
|
|
|
815
799
|
if not name:
|
|
816
800
|
raise ValueError("name must be specified")
|
|
817
801
|
h = get_in(spec, "spec.handler", "").split(":")
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
build =
|
|
802
|
+
runtime.handler = h[0] if len(h) <= 1 else h[1]
|
|
803
|
+
runtime.metadata = get_in(spec, "spec.metadata")
|
|
804
|
+
runtime.metadata.name = name
|
|
805
|
+
build = runtime.spec.build
|
|
822
806
|
build.code_origin = code_origin
|
|
823
807
|
build.origin_filename = filename or (name + ".ipynb")
|
|
824
808
|
build.extra = get_in(spec, "spec.build.extra")
|
|
@@ -826,18 +810,18 @@ def code_to_function(
|
|
|
826
810
|
build.builder_env = get_in(spec, "spec.build.builder_env")
|
|
827
811
|
if not embed_code:
|
|
828
812
|
if code_output:
|
|
829
|
-
|
|
813
|
+
runtime.spec.command = code_output
|
|
830
814
|
else:
|
|
831
|
-
|
|
815
|
+
runtime.spec.command = filename
|
|
832
816
|
|
|
833
817
|
build.image = get_in(spec, "spec.build.image")
|
|
834
|
-
update_common(
|
|
835
|
-
|
|
818
|
+
update_common(runtime, spec)
|
|
819
|
+
runtime.prepare_image_for_deploy()
|
|
836
820
|
|
|
837
821
|
if with_doc:
|
|
838
|
-
update_function_entry_points(
|
|
839
|
-
|
|
840
|
-
return
|
|
822
|
+
update_function_entry_points(runtime, code)
|
|
823
|
+
runtime.spec.default_handler = handler
|
|
824
|
+
return runtime
|
|
841
825
|
|
|
842
826
|
|
|
843
827
|
def _run_pipeline(
|
|
@@ -851,6 +835,7 @@ def _run_pipeline(
|
|
|
851
835
|
ops=None,
|
|
852
836
|
url=None,
|
|
853
837
|
cleanup_ttl=None,
|
|
838
|
+
timeout=60,
|
|
854
839
|
):
|
|
855
840
|
"""remote KubeFlow pipeline execution
|
|
856
841
|
|
|
@@ -888,6 +873,7 @@ def _run_pipeline(
|
|
|
888
873
|
ops=ops,
|
|
889
874
|
artifact_path=artifact_path,
|
|
890
875
|
cleanup_ttl=cleanup_ttl,
|
|
876
|
+
timeout=timeout,
|
|
891
877
|
)
|
|
892
878
|
logger.info(f"Pipeline run id={pipeline_run_id}, check UI for progress")
|
|
893
879
|
return pipeline_run_id
|
|
@@ -965,7 +951,7 @@ def wait_for_pipeline_completion(
|
|
|
965
951
|
show_kfp_run(resp)
|
|
966
952
|
|
|
967
953
|
status = resp["run"]["status"] if resp else "unknown"
|
|
968
|
-
message = resp["run"].get("message", "")
|
|
954
|
+
message = resp["run"].get("message", "") if resp else ""
|
|
969
955
|
if expected_statuses:
|
|
970
956
|
if status not in expected_statuses:
|
|
971
957
|
raise RuntimeError(
|
|
@@ -987,8 +973,8 @@ def get_pipeline(
|
|
|
987
973
|
run_id,
|
|
988
974
|
namespace=None,
|
|
989
975
|
format_: Union[
|
|
990
|
-
str, mlrun.common.
|
|
991
|
-
] = mlrun.common.
|
|
976
|
+
str, mlrun.common.formatters.PipelineFormat
|
|
977
|
+
] = mlrun.common.formatters.PipelineFormat.summary,
|
|
992
978
|
project: str = None,
|
|
993
979
|
remote: bool = True,
|
|
994
980
|
):
|
|
@@ -1002,7 +988,7 @@ def get_pipeline(
|
|
|
1002
988
|
:param project: the project of the pipeline run
|
|
1003
989
|
:param remote: read kfp data from mlrun service (default=True)
|
|
1004
990
|
|
|
1005
|
-
:return: kfp run
|
|
991
|
+
:return: kfp run
|
|
1006
992
|
"""
|
|
1007
993
|
namespace = namespace or mlconf.namespace
|
|
1008
994
|
if remote:
|
|
@@ -1024,9 +1010,9 @@ def get_pipeline(
|
|
|
1024
1010
|
resp = resp.to_dict()
|
|
1025
1011
|
if (
|
|
1026
1012
|
not format_
|
|
1027
|
-
or format_ == mlrun.common.
|
|
1013
|
+
or format_ == mlrun.common.formatters.PipelineFormat.summary.value
|
|
1028
1014
|
):
|
|
1029
|
-
resp =
|
|
1015
|
+
resp = mlrun.common.formatters.PipelineFormat.format_obj(resp, format_)
|
|
1030
1016
|
|
|
1031
1017
|
show_kfp_run(resp)
|
|
1032
1018
|
return resp
|
|
@@ -1040,7 +1026,7 @@ def list_pipelines(
|
|
|
1040
1026
|
filter_="",
|
|
1041
1027
|
namespace=None,
|
|
1042
1028
|
project="*",
|
|
1043
|
-
format_: mlrun.common.
|
|
1029
|
+
format_: mlrun.common.formatters.PipelineFormat = mlrun.common.formatters.PipelineFormat.metadata_only,
|
|
1044
1030
|
) -> tuple[int, Optional[int], list[dict]]:
|
|
1045
1031
|
"""List pipelines
|
|
1046
1032
|
|
|
@@ -1060,7 +1046,7 @@ def list_pipelines(
|
|
|
1060
1046
|
:param format_: Control what will be returned (full/metadata_only/name_only)
|
|
1061
1047
|
"""
|
|
1062
1048
|
if full:
|
|
1063
|
-
format_ = mlrun.common.
|
|
1049
|
+
format_ = mlrun.common.formatters.PipelineFormat.full
|
|
1064
1050
|
run_db = mlrun.db.get_run_db()
|
|
1065
1051
|
pipelines = run_db.list_pipelines(
|
|
1066
1052
|
project, namespace, sort_by, page_token, filter_, format_, page_size
|
|
@@ -1096,13 +1082,25 @@ def wait_for_runs_completion(
|
|
|
1096
1082
|
example::
|
|
1097
1083
|
|
|
1098
1084
|
# run two training functions in parallel and wait for the results
|
|
1099
|
-
inputs = {
|
|
1100
|
-
run1 = train.run(
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1085
|
+
inputs = {"dataset": cleaned_data}
|
|
1086
|
+
run1 = train.run(
|
|
1087
|
+
name="train_lr",
|
|
1088
|
+
inputs=inputs,
|
|
1089
|
+
watch=False,
|
|
1090
|
+
params={
|
|
1091
|
+
"model_pkg_class": "sklearn.linear_model.LogisticRegression",
|
|
1092
|
+
"label_column": "label",
|
|
1093
|
+
},
|
|
1094
|
+
)
|
|
1095
|
+
run2 = train.run(
|
|
1096
|
+
name="train_lr",
|
|
1097
|
+
inputs=inputs,
|
|
1098
|
+
watch=False,
|
|
1099
|
+
params={
|
|
1100
|
+
"model_pkg_class": "sklearn.ensemble.RandomForestClassifier",
|
|
1101
|
+
"label_column": "label",
|
|
1102
|
+
},
|
|
1103
|
+
)
|
|
1106
1104
|
completed = wait_for_runs_completion([run1, run2])
|
|
1107
1105
|
|
|
1108
1106
|
:param runs: list of run objects (the returned values of function.run())
|
|
@@ -1117,7 +1115,7 @@ def wait_for_runs_completion(
|
|
|
1117
1115
|
running = []
|
|
1118
1116
|
for run in runs:
|
|
1119
1117
|
state = run.state()
|
|
1120
|
-
if state in mlrun.runtimes.constants.RunStates.terminal_states():
|
|
1118
|
+
if state in mlrun.common.runtimes.constants.RunStates.terminal_states():
|
|
1121
1119
|
completed.append(run)
|
|
1122
1120
|
else:
|
|
1123
1121
|
running.append(run)
|