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
|
@@ -22,9 +22,11 @@ from time import sleep
|
|
|
22
22
|
import nuclio
|
|
23
23
|
import nuclio.utils
|
|
24
24
|
import requests
|
|
25
|
-
import semver
|
|
26
25
|
from aiohttp.client import ClientSession
|
|
27
26
|
from kubernetes import client
|
|
27
|
+
from mlrun_pipelines.common.mounts import VolumeMount
|
|
28
|
+
from mlrun_pipelines.common.ops import deploy_op
|
|
29
|
+
from mlrun_pipelines.mounts import mount_v3io, v3io_cred
|
|
28
30
|
from nuclio.deploy import find_dashboard_url, get_deploy_status
|
|
29
31
|
from nuclio.triggers import V3IOStreamTrigger
|
|
30
32
|
|
|
@@ -36,15 +38,11 @@ import mlrun.utils.helpers
|
|
|
36
38
|
from mlrun.common.schemas import AuthInfo
|
|
37
39
|
from mlrun.config import config as mlconf
|
|
38
40
|
from mlrun.errors import err_to_str
|
|
39
|
-
from mlrun.kfpops import deploy_op
|
|
40
41
|
from mlrun.lists import RunList
|
|
41
42
|
from mlrun.model import RunObject
|
|
42
43
|
from mlrun.platforms.iguazio import (
|
|
43
|
-
VolumeMount,
|
|
44
|
-
mount_v3io,
|
|
45
44
|
parse_path,
|
|
46
45
|
split_path,
|
|
47
|
-
v3io_cred,
|
|
48
46
|
)
|
|
49
47
|
from mlrun.runtimes.base import FunctionStatus, RunError
|
|
50
48
|
from mlrun.runtimes.pod import KubeResource, KubeResourceSpec
|
|
@@ -56,33 +54,9 @@ def validate_nuclio_version_compatibility(*min_versions):
|
|
|
56
54
|
"""
|
|
57
55
|
:param min_versions: Valid minimum version(s) required, assuming no 2 versions has equal major and minor.
|
|
58
56
|
"""
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
try:
|
|
63
|
-
parsed_current_version = semver.VersionInfo.parse(mlconf.nuclio_version)
|
|
64
|
-
except ValueError:
|
|
65
|
-
# only log when version is set but invalid
|
|
66
|
-
if mlconf.nuclio_version:
|
|
67
|
-
logger.warning(
|
|
68
|
-
"Unable to parse nuclio version, assuming compatibility",
|
|
69
|
-
nuclio_version=mlconf.nuclio_version,
|
|
70
|
-
min_versions=min_versions,
|
|
71
|
-
)
|
|
72
|
-
return True
|
|
73
|
-
|
|
74
|
-
parsed_min_versions.sort(reverse=True)
|
|
75
|
-
for parsed_min_version in parsed_min_versions:
|
|
76
|
-
if (
|
|
77
|
-
parsed_current_version.major == parsed_min_version.major
|
|
78
|
-
and parsed_current_version.minor == parsed_min_version.minor
|
|
79
|
-
and parsed_current_version.patch < parsed_min_version.patch
|
|
80
|
-
):
|
|
81
|
-
return False
|
|
82
|
-
|
|
83
|
-
if parsed_current_version >= parsed_min_version:
|
|
84
|
-
return True
|
|
85
|
-
return False
|
|
57
|
+
return mlrun.utils.helpers.validate_component_version_compatibility(
|
|
58
|
+
"nuclio", *min_versions
|
|
59
|
+
)
|
|
86
60
|
|
|
87
61
|
|
|
88
62
|
def min_nuclio_versions(*versions):
|
|
@@ -91,10 +65,7 @@ def min_nuclio_versions(*versions):
|
|
|
91
65
|
if validate_nuclio_version_compatibility(*versions):
|
|
92
66
|
return function(*args, **kwargs)
|
|
93
67
|
|
|
94
|
-
message = (
|
|
95
|
-
f"{function.__name__} is supported since nuclio {' or '.join(versions)}, currently using "
|
|
96
|
-
f"nuclio {mlconf.nuclio_version}, please upgrade."
|
|
97
|
-
)
|
|
68
|
+
message = f"'{function.__qualname__}' function requires Nuclio v{' or v'.join(versions)} or higher"
|
|
98
69
|
raise mlrun.errors.MLRunIncompatibleVersionError(message)
|
|
99
70
|
|
|
100
71
|
return wrapper
|
|
@@ -291,6 +262,9 @@ class RemoteRuntime(KubeResource):
|
|
|
291
262
|
def status(self, status):
|
|
292
263
|
self._status = self._verify_dict(status, "status", NuclioStatus)
|
|
293
264
|
|
|
265
|
+
def pre_deploy_validation(self):
|
|
266
|
+
pass
|
|
267
|
+
|
|
294
268
|
def set_config(self, key, value):
|
|
295
269
|
self.spec.config[key] = value
|
|
296
270
|
return self
|
|
@@ -342,17 +316,21 @@ class RemoteRuntime(KubeResource):
|
|
|
342
316
|
|
|
343
317
|
git::
|
|
344
318
|
|
|
345
|
-
fn.with_source_archive(
|
|
346
|
-
|
|
347
|
-
|
|
319
|
+
fn.with_source_archive(
|
|
320
|
+
"git://github.com/org/repo#my-branch",
|
|
321
|
+
handler="main:handler",
|
|
322
|
+
workdir="path/inside/repo",
|
|
323
|
+
)
|
|
348
324
|
|
|
349
325
|
s3::
|
|
350
326
|
|
|
351
327
|
fn.spec.nuclio_runtime = "golang"
|
|
352
|
-
fn.with_source_archive(
|
|
328
|
+
fn.with_source_archive(
|
|
329
|
+
"s3://my-bucket/path/in/bucket/my-functions-archive",
|
|
353
330
|
handler="my_func:Handler",
|
|
354
331
|
workdir="path/inside/functions/archive",
|
|
355
|
-
runtime="golang"
|
|
332
|
+
runtime="golang",
|
|
333
|
+
)
|
|
356
334
|
"""
|
|
357
335
|
self.spec.build.source = source
|
|
358
336
|
# update handler in function_handler
|
|
@@ -540,11 +518,16 @@ class RemoteRuntime(KubeResource):
|
|
|
540
518
|
:param project: project name
|
|
541
519
|
:param tag: function tag
|
|
542
520
|
:param verbose: set True for verbose logging
|
|
543
|
-
:param auth_info: service AuthInfo
|
|
521
|
+
:param auth_info: service AuthInfo (deprecated and ignored)
|
|
544
522
|
:param builder_env: env vars dict for source archive config/credentials e.g. builder_env={"GIT_TOKEN": token}
|
|
545
523
|
:param force_build: set True for force building the image
|
|
546
524
|
"""
|
|
547
|
-
|
|
525
|
+
if auth_info:
|
|
526
|
+
# TODO: remove in 1.9.0
|
|
527
|
+
warnings.warn(
|
|
528
|
+
"'auth_info' is deprecated for nuclio runtimes in 1.7.0 and will be removed in 1.9.0",
|
|
529
|
+
FutureWarning,
|
|
530
|
+
)
|
|
548
531
|
|
|
549
532
|
old_http_session = getattr(self, "_http_session", None)
|
|
550
533
|
if old_http_session:
|
|
@@ -561,15 +544,12 @@ class RemoteRuntime(KubeResource):
|
|
|
561
544
|
if tag:
|
|
562
545
|
self.metadata.tag = tag
|
|
563
546
|
|
|
564
|
-
save_record = False
|
|
565
547
|
# Attempt auto-mounting, before sending to remote build
|
|
566
548
|
self.try_auto_mount_based_on_config()
|
|
567
549
|
self._fill_credentials()
|
|
568
550
|
db = self._get_db()
|
|
569
551
|
logger.info("Starting remote function deploy")
|
|
570
|
-
data = db.
|
|
571
|
-
self, False, builder_env=builder_env, force_build=force_build
|
|
572
|
-
)
|
|
552
|
+
data = db.deploy_nuclio_function(func=self, builder_env=builder_env)
|
|
573
553
|
self.status = data["data"].get("status")
|
|
574
554
|
self._update_credentials_from_remote_build(data["data"])
|
|
575
555
|
|
|
@@ -581,15 +561,18 @@ class RemoteRuntime(KubeResource):
|
|
|
581
561
|
# now, functions can be not exposed (using service type ClusterIP) and hence
|
|
582
562
|
# for BC we first try to populate the external invocation url, and then
|
|
583
563
|
# if not exists, take the internal invocation url
|
|
584
|
-
if
|
|
564
|
+
if (
|
|
565
|
+
self.status.external_invocation_urls
|
|
566
|
+
and self.status.external_invocation_urls[0] != ""
|
|
567
|
+
):
|
|
585
568
|
self.spec.command = f"http://{self.status.external_invocation_urls[0]}"
|
|
586
|
-
|
|
587
|
-
|
|
569
|
+
elif (
|
|
570
|
+
self.status.internal_invocation_urls
|
|
571
|
+
and self.status.internal_invocation_urls[0] != ""
|
|
572
|
+
):
|
|
588
573
|
self.spec.command = f"http://{self.status.internal_invocation_urls[0]}"
|
|
589
|
-
|
|
590
|
-
elif self.status.address:
|
|
574
|
+
elif self.status.address and self.status.address != "":
|
|
591
575
|
self.spec.command = f"http://{self.status.address}"
|
|
592
|
-
save_record = True
|
|
593
576
|
|
|
594
577
|
logger.info(
|
|
595
578
|
"Successfully deployed function",
|
|
@@ -597,13 +580,11 @@ class RemoteRuntime(KubeResource):
|
|
|
597
580
|
external_invocation_urls=self.status.external_invocation_urls,
|
|
598
581
|
)
|
|
599
582
|
|
|
600
|
-
|
|
601
|
-
self.save(versioned=False)
|
|
583
|
+
self.save(versioned=False)
|
|
602
584
|
|
|
603
585
|
return self.spec.command
|
|
604
586
|
|
|
605
587
|
def _wait_for_function_deployment(self, db, verbose=False):
|
|
606
|
-
text = ""
|
|
607
588
|
state = ""
|
|
608
589
|
last_log_timestamp = 1
|
|
609
590
|
while state not in ["ready", "error", "unhealthy"]:
|
|
@@ -611,7 +592,7 @@ class RemoteRuntime(KubeResource):
|
|
|
611
592
|
int(mlrun.mlconf.httpdb.logs.nuclio.pull_deploy_status_default_interval)
|
|
612
593
|
)
|
|
613
594
|
try:
|
|
614
|
-
text, last_log_timestamp = db.
|
|
595
|
+
text, last_log_timestamp = db.get_nuclio_deploy_status(
|
|
615
596
|
self, last_log_timestamp=last_log_timestamp, verbose=verbose
|
|
616
597
|
)
|
|
617
598
|
except mlrun.db.RunDBError:
|
|
@@ -769,10 +750,13 @@ class RemoteRuntime(KubeResource):
|
|
|
769
750
|
runtime_env["MLRUN_NAMESPACE"] = mlconf.namespace
|
|
770
751
|
if self.metadata.credentials.access_key:
|
|
771
752
|
runtime_env[
|
|
772
|
-
mlrun.runtimes.constants.FunctionEnvironmentVariables.auth_session
|
|
753
|
+
mlrun.common.runtimes.constants.FunctionEnvironmentVariables.auth_session
|
|
773
754
|
] = self.metadata.credentials.access_key
|
|
774
755
|
return runtime_env
|
|
775
756
|
|
|
757
|
+
def _get_serving_spec(self):
|
|
758
|
+
return None
|
|
759
|
+
|
|
776
760
|
def _get_nuclio_config_spec_env(self):
|
|
777
761
|
env_dict = {}
|
|
778
762
|
external_source_env_dict = {}
|
|
@@ -958,6 +942,62 @@ class RemoteRuntime(KubeResource):
|
|
|
958
942
|
data = json.loads(data)
|
|
959
943
|
return data
|
|
960
944
|
|
|
945
|
+
def with_sidecar(
|
|
946
|
+
self,
|
|
947
|
+
name: str = None,
|
|
948
|
+
image: str = None,
|
|
949
|
+
ports: typing.Optional[typing.Union[int, list[int]]] = None,
|
|
950
|
+
command: typing.Optional[str] = None,
|
|
951
|
+
args: typing.Optional[list[str]] = None,
|
|
952
|
+
):
|
|
953
|
+
"""
|
|
954
|
+
Add a sidecar container to the function pod
|
|
955
|
+
:param name: Sidecar container name.
|
|
956
|
+
:param image: Sidecar container image.
|
|
957
|
+
:param ports: Sidecar container ports to expose. Can be a single port or a list of ports.
|
|
958
|
+
:param command: Sidecar container command instead of the image entrypoint.
|
|
959
|
+
:param args: Sidecar container command args (requires command to be set).
|
|
960
|
+
"""
|
|
961
|
+
name = name or f"{self.metadata.name}-sidecar"
|
|
962
|
+
sidecar = self._set_sidecar(name)
|
|
963
|
+
if image:
|
|
964
|
+
sidecar["image"] = image
|
|
965
|
+
|
|
966
|
+
ports = mlrun.utils.helpers.as_list(ports)
|
|
967
|
+
# according to RFC-6335, port name should be less than 15 characters,
|
|
968
|
+
# so we truncate it if needed and leave room for the index
|
|
969
|
+
port_name = name[:13].rstrip("-_") if len(name) > 13 else name
|
|
970
|
+
sidecar["ports"] = [
|
|
971
|
+
{
|
|
972
|
+
"name": f"{port_name}-{i}",
|
|
973
|
+
"containerPort": port,
|
|
974
|
+
"protocol": "TCP",
|
|
975
|
+
}
|
|
976
|
+
for i, port in enumerate(ports)
|
|
977
|
+
]
|
|
978
|
+
|
|
979
|
+
# if it is a redeploy, 'command' might be set with the previous invocation url.
|
|
980
|
+
# in this case, we don't want to use it as the sidecar command
|
|
981
|
+
if command and not command.startswith("http"):
|
|
982
|
+
sidecar["command"] = mlrun.utils.helpers.as_list(command)
|
|
983
|
+
|
|
984
|
+
if args and sidecar["command"]:
|
|
985
|
+
sidecar["args"] = mlrun.utils.helpers.as_list(args)
|
|
986
|
+
|
|
987
|
+
# populate the sidecar resources from the function spec
|
|
988
|
+
if self.spec.resources:
|
|
989
|
+
sidecar["resources"] = self.spec.resources
|
|
990
|
+
|
|
991
|
+
def _set_sidecar(self, name: str) -> dict:
|
|
992
|
+
self.spec.config.setdefault("spec.sidecars", [])
|
|
993
|
+
sidecars = self.spec.config["spec.sidecars"]
|
|
994
|
+
for sidecar in sidecars:
|
|
995
|
+
if sidecar["name"] == name:
|
|
996
|
+
return sidecar
|
|
997
|
+
|
|
998
|
+
sidecars.append({"name": name})
|
|
999
|
+
return sidecars[-1]
|
|
1000
|
+
|
|
961
1001
|
def _trigger_of_kind_exists(self, kind: str) -> bool:
|
|
962
1002
|
if not self.spec.config:
|
|
963
1003
|
return False
|
mlrun/runtimes/nuclio/serving.py
CHANGED
|
@@ -14,17 +14,17 @@
|
|
|
14
14
|
|
|
15
15
|
import json
|
|
16
16
|
import os
|
|
17
|
+
import warnings
|
|
17
18
|
from copy import deepcopy
|
|
18
|
-
from typing import Union
|
|
19
|
+
from typing import TYPE_CHECKING, Optional, Union
|
|
19
20
|
|
|
20
21
|
import nuclio
|
|
21
22
|
from nuclio import KafkaTrigger
|
|
22
23
|
|
|
23
24
|
import mlrun
|
|
24
25
|
import mlrun.common.schemas
|
|
25
|
-
from mlrun.datastore import parse_kafka_url
|
|
26
|
+
from mlrun.datastore import get_kafka_brokers_from_dict, parse_kafka_url
|
|
26
27
|
from mlrun.model import ObjectList
|
|
27
|
-
from mlrun.model_monitoring.tracking_policy import TrackingPolicy
|
|
28
28
|
from mlrun.runtimes.function_reference import FunctionReference
|
|
29
29
|
from mlrun.secrets import SecretsStore
|
|
30
30
|
from mlrun.serving.server import GraphServer, create_graph_server
|
|
@@ -43,6 +43,10 @@ from .function import NuclioSpec, RemoteRuntime
|
|
|
43
43
|
|
|
44
44
|
serving_subkind = "serving_v2"
|
|
45
45
|
|
|
46
|
+
if TYPE_CHECKING:
|
|
47
|
+
# remove this block in 1.9.0
|
|
48
|
+
from mlrun.model_monitoring import TrackingPolicy
|
|
49
|
+
|
|
46
50
|
|
|
47
51
|
def new_v2_model_server(
|
|
48
52
|
name,
|
|
@@ -303,12 +307,12 @@ class ServingRuntime(RemoteRuntime):
|
|
|
303
307
|
|
|
304
308
|
def set_tracking(
|
|
305
309
|
self,
|
|
306
|
-
stream_path: str = None,
|
|
307
|
-
batch: int = None,
|
|
308
|
-
sample: int = None,
|
|
309
|
-
stream_args: dict = None,
|
|
310
|
-
tracking_policy: Union[TrackingPolicy, dict] = None,
|
|
311
|
-
):
|
|
310
|
+
stream_path: Optional[str] = None,
|
|
311
|
+
batch: Optional[int] = None,
|
|
312
|
+
sample: Optional[int] = None,
|
|
313
|
+
stream_args: Optional[dict] = None,
|
|
314
|
+
tracking_policy: Optional[Union["TrackingPolicy", dict]] = None,
|
|
315
|
+
) -> None:
|
|
312
316
|
"""apply on your serving function to monitor a deployed model, including real-time dashboards to detect drift
|
|
313
317
|
and analyze performance.
|
|
314
318
|
|
|
@@ -317,31 +321,17 @@ class ServingRuntime(RemoteRuntime):
|
|
|
317
321
|
:param batch: Micro batch size (send micro batches of N records at a time).
|
|
318
322
|
:param sample: Sample size (send only one of N records).
|
|
319
323
|
:param stream_args: Stream initialization parameters, e.g. shards, retention_in_hours, ..
|
|
320
|
-
:param tracking_policy: Tracking policy object or a dictionary that will be converted into a tracking policy
|
|
321
|
-
object. By using TrackingPolicy, the user can apply his model monitoring requirements,
|
|
322
|
-
such as setting the scheduling policy of the model monitoring batch job or changing
|
|
323
|
-
the image of the model monitoring stream.
|
|
324
324
|
|
|
325
325
|
example::
|
|
326
326
|
|
|
327
327
|
# initialize a new serving function
|
|
328
328
|
serving_fn = mlrun.import_function("hub://v2-model-server", new_name="serving")
|
|
329
|
-
# apply model monitoring
|
|
330
|
-
|
|
331
|
-
serving_fn.set_tracking(tracking_policy=tracking_policy)
|
|
329
|
+
# apply model monitoring
|
|
330
|
+
serving_fn.set_tracking()
|
|
332
331
|
|
|
333
332
|
"""
|
|
334
|
-
|
|
335
333
|
# Applying model monitoring configurations
|
|
336
334
|
self.spec.track_models = True
|
|
337
|
-
self.spec.tracking_policy = None
|
|
338
|
-
if tracking_policy:
|
|
339
|
-
if isinstance(tracking_policy, dict):
|
|
340
|
-
# Convert tracking policy dictionary into `model_monitoring.TrackingPolicy` object
|
|
341
|
-
self.spec.tracking_policy = TrackingPolicy.from_dict(tracking_policy)
|
|
342
|
-
else:
|
|
343
|
-
# Tracking_policy is already a `model_monitoring.TrackingPolicy` object
|
|
344
|
-
self.spec.tracking_policy = tracking_policy
|
|
345
335
|
|
|
346
336
|
if stream_path:
|
|
347
337
|
self.spec.parameters["log_stream"] = stream_path
|
|
@@ -351,6 +341,14 @@ class ServingRuntime(RemoteRuntime):
|
|
|
351
341
|
self.spec.parameters["log_stream_sample"] = sample
|
|
352
342
|
if stream_args:
|
|
353
343
|
self.spec.parameters["stream_args"] = stream_args
|
|
344
|
+
if tracking_policy is not None:
|
|
345
|
+
warnings.warn(
|
|
346
|
+
"The `tracking_policy` argument is deprecated from version 1.7.0 "
|
|
347
|
+
"and has no effect. It will be removed in 1.9.0.\n"
|
|
348
|
+
"To set the desired model monitoring time window and schedule, use "
|
|
349
|
+
"the `base_period` argument in `project.enable_model_monitoring()`.",
|
|
350
|
+
FutureWarning,
|
|
351
|
+
)
|
|
354
352
|
|
|
355
353
|
def add_model(
|
|
356
354
|
self,
|
|
@@ -367,8 +365,8 @@ class ServingRuntime(RemoteRuntime):
|
|
|
367
365
|
|
|
368
366
|
Example, create a function (from the notebook), add a model class, and deploy::
|
|
369
367
|
|
|
370
|
-
fn = code_to_function(kind=
|
|
371
|
-
fn.add_model(
|
|
368
|
+
fn = code_to_function(kind="serving")
|
|
369
|
+
fn.add_model("boost", model_path, model_class="MyClass", my_arg=5)
|
|
372
370
|
fn.deploy()
|
|
373
371
|
|
|
374
372
|
only works with router topology, for nested topologies (model under router under flow)
|
|
@@ -450,7 +448,7 @@ class ServingRuntime(RemoteRuntime):
|
|
|
450
448
|
|
|
451
449
|
example::
|
|
452
450
|
|
|
453
|
-
fn.add_child_function(
|
|
451
|
+
fn.add_child_function("enrich", "./enrich.ipynb", "mlrun/mlrun")
|
|
454
452
|
|
|
455
453
|
:param name: child function name
|
|
456
454
|
:param url: function/code url, support .py, .ipynb, .yaml extensions
|
|
@@ -489,11 +487,8 @@ class ServingRuntime(RemoteRuntime):
|
|
|
489
487
|
"worker_allocation_mode", "static"
|
|
490
488
|
)
|
|
491
489
|
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
or "kafka_bootstrap_servers" in stream.options
|
|
495
|
-
):
|
|
496
|
-
brokers = stream.options.get("kafka_bootstrap_servers")
|
|
490
|
+
brokers = get_kafka_brokers_from_dict(stream.options)
|
|
491
|
+
if stream.path.startswith("kafka://") or brokers:
|
|
497
492
|
if brokers:
|
|
498
493
|
brokers = brokers.split(",")
|
|
499
494
|
topic, brokers = parse_kafka_url(stream.path, brokers)
|
|
@@ -644,8 +639,7 @@ class ServingRuntime(RemoteRuntime):
|
|
|
644
639
|
force_build=force_build,
|
|
645
640
|
)
|
|
646
641
|
|
|
647
|
-
def
|
|
648
|
-
env = super()._get_runtime_env()
|
|
642
|
+
def _get_serving_spec(self):
|
|
649
643
|
function_name_uri_map = {f.name: f.uri(self) for f in self.spec.function_refs}
|
|
650
644
|
|
|
651
645
|
serving_spec = {
|
|
@@ -658,9 +652,7 @@ class ServingRuntime(RemoteRuntime):
|
|
|
658
652
|
"graph_initializer": self.spec.graph_initializer,
|
|
659
653
|
"error_stream": self.spec.error_stream,
|
|
660
654
|
"track_models": self.spec.track_models,
|
|
661
|
-
"tracking_policy":
|
|
662
|
-
if self.spec.tracking_policy
|
|
663
|
-
else None,
|
|
655
|
+
"tracking_policy": None,
|
|
664
656
|
"default_content_type": self.spec.default_content_type,
|
|
665
657
|
}
|
|
666
658
|
|
|
@@ -668,8 +660,7 @@ class ServingRuntime(RemoteRuntime):
|
|
|
668
660
|
self._secrets = SecretsStore.from_list(self.spec.secret_sources)
|
|
669
661
|
serving_spec["secret_sources"] = self._secrets.to_serial()
|
|
670
662
|
|
|
671
|
-
|
|
672
|
-
return env
|
|
663
|
+
return json.dumps(serving_spec)
|
|
673
664
|
|
|
674
665
|
def to_mock_server(
|
|
675
666
|
self,
|
|
@@ -735,8 +726,11 @@ class ServingRuntime(RemoteRuntime):
|
|
|
735
726
|
example::
|
|
736
727
|
|
|
737
728
|
serving_fn = mlrun.new_function("serving", image="mlrun/mlrun", kind="serving")
|
|
738
|
-
serving_fn.add_model(
|
|
739
|
-
|
|
729
|
+
serving_fn.add_model(
|
|
730
|
+
"my-classifier",
|
|
731
|
+
model_path=model_path,
|
|
732
|
+
class_name="mlrun.frameworks.sklearn.SklearnModelServer",
|
|
733
|
+
)
|
|
740
734
|
serving_fn.plot(rankdir="LR")
|
|
741
735
|
|
|
742
736
|
:param filename: target filepath for the image (None for the notebook)
|