mlrun 1.7.2rc4__py3-none-any.whl → 1.8.0__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 +26 -22
- mlrun/__main__.py +15 -16
- mlrun/alerts/alert.py +150 -15
- mlrun/api/schemas/__init__.py +1 -9
- mlrun/artifacts/__init__.py +2 -3
- mlrun/artifacts/base.py +62 -19
- mlrun/artifacts/dataset.py +17 -17
- mlrun/artifacts/document.py +454 -0
- mlrun/artifacts/manager.py +28 -18
- mlrun/artifacts/model.py +91 -59
- mlrun/artifacts/plots.py +2 -2
- mlrun/common/constants.py +8 -0
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/artifact.py +1 -1
- mlrun/common/formatters/feature_set.py +2 -0
- mlrun/common/formatters/function.py +1 -0
- mlrun/{model_monitoring/db/stores/v3io_kv/__init__.py → common/formatters/model_endpoint.py} +17 -0
- mlrun/common/formatters/pipeline.py +1 -2
- mlrun/common/formatters/project.py +9 -0
- mlrun/common/model_monitoring/__init__.py +0 -5
- mlrun/common/model_monitoring/helpers.py +12 -62
- mlrun/common/runtimes/constants.py +25 -4
- mlrun/common/schemas/__init__.py +9 -5
- mlrun/common/schemas/alert.py +114 -19
- mlrun/common/schemas/api_gateway.py +3 -3
- mlrun/common/schemas/artifact.py +22 -9
- mlrun/common/schemas/auth.py +8 -4
- mlrun/common/schemas/background_task.py +7 -7
- mlrun/common/schemas/client_spec.py +4 -4
- mlrun/common/schemas/clusterization_spec.py +2 -2
- mlrun/common/schemas/common.py +53 -3
- mlrun/common/schemas/constants.py +15 -0
- mlrun/common/schemas/datastore_profile.py +1 -1
- mlrun/common/schemas/feature_store.py +9 -9
- mlrun/common/schemas/frontend_spec.py +4 -4
- mlrun/common/schemas/function.py +10 -10
- mlrun/common/schemas/hub.py +1 -1
- mlrun/common/schemas/k8s.py +3 -3
- mlrun/common/schemas/memory_reports.py +3 -3
- mlrun/common/schemas/model_monitoring/__init__.py +4 -8
- mlrun/common/schemas/model_monitoring/constants.py +127 -46
- mlrun/common/schemas/model_monitoring/grafana.py +18 -12
- mlrun/common/schemas/model_monitoring/model_endpoints.py +154 -160
- mlrun/common/schemas/notification.py +24 -3
- mlrun/common/schemas/object.py +1 -1
- mlrun/common/schemas/pagination.py +4 -4
- mlrun/common/schemas/partition.py +142 -0
- mlrun/common/schemas/pipeline.py +3 -3
- mlrun/common/schemas/project.py +26 -18
- mlrun/common/schemas/runs.py +3 -3
- mlrun/common/schemas/runtime_resource.py +5 -5
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/schemas/secret.py +1 -1
- mlrun/{model_monitoring/db/stores/sqldb/__init__.py → common/schemas/serving.py} +10 -1
- mlrun/common/schemas/tag.py +3 -3
- mlrun/common/schemas/workflow.py +6 -5
- mlrun/common/types.py +1 -0
- mlrun/config.py +157 -89
- mlrun/data_types/__init__.py +5 -3
- mlrun/data_types/infer.py +13 -3
- mlrun/data_types/spark.py +2 -1
- mlrun/datastore/__init__.py +59 -18
- mlrun/datastore/alibaba_oss.py +4 -1
- mlrun/datastore/azure_blob.py +4 -1
- mlrun/datastore/base.py +19 -24
- mlrun/datastore/datastore.py +10 -4
- mlrun/datastore/datastore_profile.py +178 -45
- mlrun/datastore/dbfs_store.py +4 -1
- mlrun/datastore/filestore.py +4 -1
- mlrun/datastore/google_cloud_storage.py +4 -1
- mlrun/datastore/hdfs.py +4 -1
- mlrun/datastore/inmem.py +4 -1
- mlrun/datastore/redis.py +4 -1
- mlrun/datastore/s3.py +14 -3
- mlrun/datastore/sources.py +89 -92
- mlrun/datastore/store_resources.py +7 -4
- mlrun/datastore/storeytargets.py +51 -16
- mlrun/datastore/targets.py +38 -31
- mlrun/datastore/utils.py +87 -4
- mlrun/datastore/v3io.py +4 -1
- mlrun/datastore/vectorstore.py +291 -0
- mlrun/datastore/wasbfs/fs.py +13 -12
- mlrun/db/base.py +286 -100
- mlrun/db/httpdb.py +1562 -490
- mlrun/db/nopdb.py +250 -83
- mlrun/errors.py +6 -2
- mlrun/execution.py +194 -50
- mlrun/feature_store/__init__.py +2 -10
- mlrun/feature_store/api.py +20 -458
- mlrun/feature_store/common.py +9 -9
- mlrun/feature_store/feature_set.py +20 -18
- mlrun/feature_store/feature_vector.py +105 -479
- mlrun/feature_store/feature_vector_utils.py +466 -0
- mlrun/feature_store/retrieval/base.py +15 -11
- mlrun/feature_store/retrieval/job.py +2 -1
- mlrun/feature_store/retrieval/storey_merger.py +1 -1
- mlrun/feature_store/steps.py +3 -3
- mlrun/features.py +30 -13
- mlrun/frameworks/__init__.py +1 -2
- mlrun/frameworks/_common/__init__.py +1 -2
- mlrun/frameworks/_common/artifacts_library.py +2 -2
- mlrun/frameworks/_common/mlrun_interface.py +10 -6
- mlrun/frameworks/_common/model_handler.py +31 -31
- mlrun/frameworks/_common/producer.py +3 -1
- mlrun/frameworks/_dl_common/__init__.py +1 -2
- mlrun/frameworks/_dl_common/loggers/__init__.py +1 -2
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +4 -4
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +3 -3
- mlrun/frameworks/_ml_common/__init__.py +1 -2
- mlrun/frameworks/_ml_common/loggers/__init__.py +1 -2
- mlrun/frameworks/_ml_common/model_handler.py +21 -21
- mlrun/frameworks/_ml_common/plans/__init__.py +1 -2
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +3 -1
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
- mlrun/frameworks/auto_mlrun/__init__.py +1 -2
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +22 -15
- mlrun/frameworks/huggingface/__init__.py +1 -2
- mlrun/frameworks/huggingface/model_server.py +9 -9
- mlrun/frameworks/lgbm/__init__.py +47 -44
- mlrun/frameworks/lgbm/callbacks/__init__.py +1 -2
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -2
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -2
- mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -2
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +5 -5
- mlrun/frameworks/lgbm/model_handler.py +15 -11
- mlrun/frameworks/lgbm/model_server.py +11 -7
- mlrun/frameworks/lgbm/utils.py +2 -2
- mlrun/frameworks/onnx/__init__.py +1 -2
- mlrun/frameworks/onnx/dataset.py +3 -3
- mlrun/frameworks/onnx/mlrun_interface.py +2 -2
- mlrun/frameworks/onnx/model_handler.py +7 -5
- mlrun/frameworks/onnx/model_server.py +8 -6
- mlrun/frameworks/parallel_coordinates.py +11 -11
- mlrun/frameworks/pytorch/__init__.py +22 -23
- mlrun/frameworks/pytorch/callbacks/__init__.py +1 -2
- mlrun/frameworks/pytorch/callbacks/callback.py +2 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +15 -8
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +19 -12
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +22 -15
- mlrun/frameworks/pytorch/callbacks_handler.py +36 -30
- mlrun/frameworks/pytorch/mlrun_interface.py +17 -17
- mlrun/frameworks/pytorch/model_handler.py +21 -17
- mlrun/frameworks/pytorch/model_server.py +13 -9
- mlrun/frameworks/sklearn/__init__.py +19 -18
- mlrun/frameworks/sklearn/estimator.py +2 -2
- mlrun/frameworks/sklearn/metric.py +3 -3
- mlrun/frameworks/sklearn/metrics_library.py +8 -6
- mlrun/frameworks/sklearn/mlrun_interface.py +3 -2
- mlrun/frameworks/sklearn/model_handler.py +4 -3
- mlrun/frameworks/tf_keras/__init__.py +11 -12
- mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -2
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +17 -14
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +15 -12
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +21 -18
- mlrun/frameworks/tf_keras/model_handler.py +17 -13
- mlrun/frameworks/tf_keras/model_server.py +12 -8
- mlrun/frameworks/xgboost/__init__.py +19 -18
- mlrun/frameworks/xgboost/model_handler.py +13 -9
- mlrun/k8s_utils.py +2 -5
- mlrun/launcher/base.py +3 -4
- mlrun/launcher/client.py +2 -2
- mlrun/launcher/local.py +6 -2
- mlrun/launcher/remote.py +1 -1
- mlrun/lists.py +8 -4
- mlrun/model.py +132 -46
- mlrun/model_monitoring/__init__.py +3 -5
- mlrun/model_monitoring/api.py +113 -98
- mlrun/model_monitoring/applications/__init__.py +0 -5
- mlrun/model_monitoring/applications/_application_steps.py +81 -50
- mlrun/model_monitoring/applications/base.py +467 -14
- mlrun/model_monitoring/applications/context.py +212 -134
- mlrun/model_monitoring/{db/stores/base → applications/evidently}/__init__.py +6 -2
- mlrun/model_monitoring/applications/evidently/base.py +146 -0
- mlrun/model_monitoring/applications/histogram_data_drift.py +89 -56
- mlrun/model_monitoring/applications/results.py +67 -15
- mlrun/model_monitoring/controller.py +701 -315
- mlrun/model_monitoring/db/__init__.py +0 -2
- mlrun/model_monitoring/db/_schedules.py +242 -0
- mlrun/model_monitoring/db/_stats.py +189 -0
- mlrun/model_monitoring/db/tsdb/__init__.py +33 -22
- mlrun/model_monitoring/db/tsdb/base.py +243 -49
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +76 -36
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py +213 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +534 -88
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +436 -106
- mlrun/model_monitoring/helpers.py +356 -114
- mlrun/model_monitoring/stream_processing.py +190 -345
- mlrun/model_monitoring/tracking_policy.py +11 -4
- mlrun/model_monitoring/writer.py +49 -90
- mlrun/package/__init__.py +3 -6
- mlrun/package/context_handler.py +2 -2
- mlrun/package/packager.py +12 -9
- mlrun/package/packagers/__init__.py +0 -2
- mlrun/package/packagers/default_packager.py +14 -11
- mlrun/package/packagers/numpy_packagers.py +16 -7
- mlrun/package/packagers/pandas_packagers.py +18 -18
- mlrun/package/packagers/python_standard_library_packagers.py +25 -11
- mlrun/package/packagers_manager.py +35 -32
- mlrun/package/utils/__init__.py +0 -3
- mlrun/package/utils/_pickler.py +6 -6
- mlrun/platforms/__init__.py +47 -16
- mlrun/platforms/iguazio.py +4 -1
- mlrun/projects/operations.py +30 -30
- mlrun/projects/pipelines.py +116 -47
- mlrun/projects/project.py +1292 -329
- mlrun/render.py +5 -9
- mlrun/run.py +57 -14
- mlrun/runtimes/__init__.py +1 -3
- mlrun/runtimes/base.py +30 -22
- mlrun/runtimes/daskjob.py +9 -9
- mlrun/runtimes/databricks_job/databricks_runtime.py +6 -5
- mlrun/runtimes/function_reference.py +5 -2
- mlrun/runtimes/generators.py +3 -2
- mlrun/runtimes/kubejob.py +6 -7
- mlrun/runtimes/mounts.py +574 -0
- mlrun/runtimes/mpijob/__init__.py +0 -2
- mlrun/runtimes/mpijob/abstract.py +7 -6
- mlrun/runtimes/nuclio/api_gateway.py +7 -7
- mlrun/runtimes/nuclio/application/application.py +11 -13
- mlrun/runtimes/nuclio/application/reverse_proxy.go +66 -64
- mlrun/runtimes/nuclio/function.py +127 -70
- mlrun/runtimes/nuclio/serving.py +105 -37
- mlrun/runtimes/pod.py +159 -54
- mlrun/runtimes/remotesparkjob.py +3 -2
- mlrun/runtimes/sparkjob/__init__.py +0 -2
- mlrun/runtimes/sparkjob/spark3job.py +22 -12
- mlrun/runtimes/utils.py +7 -6
- mlrun/secrets.py +2 -2
- mlrun/serving/__init__.py +8 -0
- mlrun/serving/merger.py +7 -5
- mlrun/serving/remote.py +35 -22
- mlrun/serving/routers.py +186 -240
- mlrun/serving/server.py +41 -10
- mlrun/serving/states.py +432 -118
- mlrun/serving/utils.py +13 -2
- mlrun/serving/v1_serving.py +3 -2
- mlrun/serving/v2_serving.py +161 -203
- mlrun/track/__init__.py +1 -1
- mlrun/track/tracker.py +2 -2
- mlrun/track/trackers/mlflow_tracker.py +6 -5
- mlrun/utils/async_http.py +35 -22
- mlrun/utils/clones.py +7 -4
- mlrun/utils/helpers.py +511 -58
- mlrun/utils/logger.py +119 -13
- mlrun/utils/notifications/notification/__init__.py +22 -19
- mlrun/utils/notifications/notification/base.py +39 -15
- mlrun/utils/notifications/notification/console.py +6 -6
- mlrun/utils/notifications/notification/git.py +11 -11
- mlrun/utils/notifications/notification/ipython.py +10 -9
- mlrun/utils/notifications/notification/mail.py +176 -0
- mlrun/utils/notifications/notification/slack.py +16 -8
- mlrun/utils/notifications/notification/webhook.py +24 -8
- mlrun/utils/notifications/notification_pusher.py +191 -200
- mlrun/utils/regex.py +12 -2
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/METADATA +69 -54
- mlrun-1.8.0.dist-info/RECORD +351 -0
- {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/WHEEL +1 -1
- mlrun/model_monitoring/applications/evidently_base.py +0 -137
- mlrun/model_monitoring/db/stores/__init__.py +0 -136
- mlrun/model_monitoring/db/stores/base/store.py +0 -213
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -71
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -190
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -103
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -40
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -659
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -726
- mlrun/model_monitoring/model_endpoint.py +0 -118
- mlrun-1.7.2rc4.dist-info/RECORD +0 -351
- {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info/licenses}/LICENSE +0 -0
- {mlrun-1.7.2rc4.dist-info → mlrun-1.8.0.dist-info}/top_level.txt +0 -0
mlrun/runtimes/pod.py
CHANGED
|
@@ -17,14 +17,16 @@ import os
|
|
|
17
17
|
import re
|
|
18
18
|
import time
|
|
19
19
|
import typing
|
|
20
|
+
from collections.abc import Iterable
|
|
20
21
|
from enum import Enum
|
|
21
22
|
|
|
22
23
|
import dotenv
|
|
23
24
|
import kubernetes.client as k8s_client
|
|
24
|
-
import
|
|
25
|
-
from mlrun_pipelines.mixins import KfpAdapterMixin
|
|
25
|
+
from kubernetes.client import V1Volume, V1VolumeMount
|
|
26
26
|
|
|
27
|
+
import mlrun.common.constants
|
|
27
28
|
import mlrun.errors
|
|
29
|
+
import mlrun.runtimes.mounts
|
|
28
30
|
import mlrun.utils.regex
|
|
29
31
|
from mlrun.common.schemas import (
|
|
30
32
|
NodeSelectorOperator,
|
|
@@ -212,9 +214,7 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
212
214
|
# default service account is set in mlrun.utils.process_function_service_account
|
|
213
215
|
# due to project specific defaults
|
|
214
216
|
self.service_account = service_account
|
|
215
|
-
self.image_pull_secret =
|
|
216
|
-
image_pull_secret or mlrun.mlconf.function.spec.image_pull_secret.default
|
|
217
|
-
)
|
|
217
|
+
self.image_pull_secret = image_pull_secret
|
|
218
218
|
self.node_name = node_name
|
|
219
219
|
self.node_selector = node_selector or {}
|
|
220
220
|
self._affinity = affinity
|
|
@@ -309,7 +309,7 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
309
309
|
return self._termination_grace_period_seconds
|
|
310
310
|
|
|
311
311
|
def _serialize_field(
|
|
312
|
-
self, struct: dict, field_name: str = None, strip: bool = False
|
|
312
|
+
self, struct: dict, field_name: typing.Optional[str] = None, strip: bool = False
|
|
313
313
|
) -> typing.Any:
|
|
314
314
|
"""
|
|
315
315
|
Serialize a field to a dict, list, or primitive type.
|
|
@@ -321,7 +321,7 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
321
321
|
return super()._serialize_field(struct, field_name, strip)
|
|
322
322
|
|
|
323
323
|
def _enrich_field(
|
|
324
|
-
self, struct: dict, field_name: str = None, strip: bool = False
|
|
324
|
+
self, struct: dict, field_name: typing.Optional[str] = None, strip: bool = False
|
|
325
325
|
) -> typing.Any:
|
|
326
326
|
k8s_api = k8s_client.ApiClient()
|
|
327
327
|
if strip:
|
|
@@ -366,6 +366,35 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
366
366
|
+ f"service accounts {allowed_service_accounts}"
|
|
367
367
|
)
|
|
368
368
|
|
|
369
|
+
def with_volumes(
|
|
370
|
+
self,
|
|
371
|
+
volumes: typing.Union[list[dict], dict, V1Volume],
|
|
372
|
+
) -> "KubeResourceSpec":
|
|
373
|
+
"""Add volumes to the volumes dictionary, only used as part of the mlrun_pipelines mount functions."""
|
|
374
|
+
if isinstance(volumes, dict):
|
|
375
|
+
set_named_item(self._volumes, volumes)
|
|
376
|
+
elif isinstance(volumes, Iterable):
|
|
377
|
+
for volume in volumes:
|
|
378
|
+
set_named_item(self._volumes, volume)
|
|
379
|
+
else:
|
|
380
|
+
set_named_item(self._volumes, volumes)
|
|
381
|
+
return self
|
|
382
|
+
|
|
383
|
+
def with_volume_mounts(
|
|
384
|
+
self,
|
|
385
|
+
volume_mounts: typing.Union[list[dict], dict, V1VolumeMount],
|
|
386
|
+
) -> "KubeResourceSpec":
|
|
387
|
+
"""Add volume mounts to the volume mounts dictionary,
|
|
388
|
+
only used as part of the mlrun_pipelines mount functions."""
|
|
389
|
+
if isinstance(volume_mounts, dict):
|
|
390
|
+
self._set_volume_mount(volume_mounts)
|
|
391
|
+
elif isinstance(volume_mounts, Iterable):
|
|
392
|
+
for volume_mount in volume_mounts:
|
|
393
|
+
self._set_volume_mount(volume_mount)
|
|
394
|
+
else:
|
|
395
|
+
self._set_volume_mount(volume_mounts)
|
|
396
|
+
return self
|
|
397
|
+
|
|
369
398
|
def _set_volume_mount(
|
|
370
399
|
self, volume_mount, volume_mounts_field_name="_volume_mounts"
|
|
371
400
|
):
|
|
@@ -380,9 +409,9 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
380
409
|
def _verify_and_set_limits(
|
|
381
410
|
self,
|
|
382
411
|
resources_field_name,
|
|
383
|
-
mem: str = None,
|
|
384
|
-
cpu: str = None,
|
|
385
|
-
gpus: int = None,
|
|
412
|
+
mem: typing.Optional[str] = None,
|
|
413
|
+
cpu: typing.Optional[str] = None,
|
|
414
|
+
gpus: typing.Optional[int] = None,
|
|
386
415
|
gpu_type: str = "nvidia.com/gpu",
|
|
387
416
|
patch: bool = False,
|
|
388
417
|
):
|
|
@@ -430,8 +459,8 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
430
459
|
def _verify_and_set_requests(
|
|
431
460
|
self,
|
|
432
461
|
resources_field_name,
|
|
433
|
-
mem: str = None,
|
|
434
|
-
cpu: str = None,
|
|
462
|
+
mem: typing.Optional[str] = None,
|
|
463
|
+
cpu: typing.Optional[str] = None,
|
|
435
464
|
patch: bool = False,
|
|
436
465
|
):
|
|
437
466
|
resources = verify_requests(resources_field_name, mem=mem, cpu=cpu)
|
|
@@ -456,9 +485,9 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
456
485
|
|
|
457
486
|
def with_limits(
|
|
458
487
|
self,
|
|
459
|
-
mem: str = None,
|
|
460
|
-
cpu: str = None,
|
|
461
|
-
gpus: int = None,
|
|
488
|
+
mem: typing.Optional[str] = None,
|
|
489
|
+
cpu: typing.Optional[str] = None,
|
|
490
|
+
gpus: typing.Optional[int] = None,
|
|
462
491
|
gpu_type: str = "nvidia.com/gpu",
|
|
463
492
|
patch: bool = False,
|
|
464
493
|
):
|
|
@@ -474,7 +503,12 @@ class KubeResourceSpec(FunctionSpec):
|
|
|
474
503
|
"""
|
|
475
504
|
self._verify_and_set_limits("resources", mem, cpu, gpus, gpu_type, patch=patch)
|
|
476
505
|
|
|
477
|
-
def with_requests(
|
|
506
|
+
def with_requests(
|
|
507
|
+
self,
|
|
508
|
+
mem: typing.Optional[str] = None,
|
|
509
|
+
cpu: typing.Optional[str] = None,
|
|
510
|
+
patch: bool = False,
|
|
511
|
+
):
|
|
478
512
|
"""
|
|
479
513
|
Set requested (desired) pod cpu/memory resources
|
|
480
514
|
|
|
@@ -936,12 +970,12 @@ class AutoMountType(str, Enum):
|
|
|
936
970
|
@classmethod
|
|
937
971
|
def all_mount_modifiers(cls):
|
|
938
972
|
return [
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
973
|
+
mlrun.runtimes.mounts.v3io_cred.__name__,
|
|
974
|
+
mlrun.runtimes.mounts.mount_v3io.__name__,
|
|
975
|
+
mlrun.runtimes.mounts.mount_pvc.__name__,
|
|
976
|
+
mlrun.runtimes.mounts.auto_mount.__name__,
|
|
977
|
+
mlrun.runtimes.mounts.mount_s3.__name__,
|
|
978
|
+
mlrun.runtimes.mounts.set_env_variables.__name__,
|
|
945
979
|
]
|
|
946
980
|
|
|
947
981
|
@classmethod
|
|
@@ -958,27 +992,27 @@ class AutoMountType(str, Enum):
|
|
|
958
992
|
def _get_auto_modifier():
|
|
959
993
|
# If we're running on Iguazio - use v3io_cred
|
|
960
994
|
if mlconf.igz_version != "":
|
|
961
|
-
return
|
|
995
|
+
return mlrun.runtimes.mounts.v3io_cred
|
|
962
996
|
# Else, either pvc mount if it's configured or do nothing otherwise
|
|
963
997
|
pvc_configured = (
|
|
964
998
|
"MLRUN_PVC_MOUNT" in os.environ
|
|
965
999
|
or "pvc_name" in mlconf.get_storage_auto_mount_params()
|
|
966
1000
|
)
|
|
967
|
-
return
|
|
1001
|
+
return mlrun.runtimes.mounts.mount_pvc if pvc_configured else None
|
|
968
1002
|
|
|
969
1003
|
def get_modifier(self):
|
|
970
1004
|
return {
|
|
971
1005
|
AutoMountType.none: None,
|
|
972
|
-
AutoMountType.v3io_credentials:
|
|
973
|
-
AutoMountType.v3io_fuse:
|
|
974
|
-
AutoMountType.pvc:
|
|
1006
|
+
AutoMountType.v3io_credentials: mlrun.runtimes.mounts.v3io_cred,
|
|
1007
|
+
AutoMountType.v3io_fuse: mlrun.runtimes.mounts.mount_v3io,
|
|
1008
|
+
AutoMountType.pvc: mlrun.runtimes.mounts.mount_pvc,
|
|
975
1009
|
AutoMountType.auto: self._get_auto_modifier(),
|
|
976
|
-
AutoMountType.s3:
|
|
977
|
-
AutoMountType.env:
|
|
1010
|
+
AutoMountType.s3: mlrun.runtimes.mounts.mount_s3,
|
|
1011
|
+
AutoMountType.env: mlrun.runtimes.mounts.set_env_variables,
|
|
978
1012
|
}[self]
|
|
979
1013
|
|
|
980
1014
|
|
|
981
|
-
class KubeResource(BaseRuntime
|
|
1015
|
+
class KubeResource(BaseRuntime):
|
|
982
1016
|
"""
|
|
983
1017
|
A parent class for runtimes that generate k8s resources when executing.
|
|
984
1018
|
"""
|
|
@@ -1020,7 +1054,8 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1020
1054
|
|
|
1021
1055
|
def get_env(self, name, default=None):
|
|
1022
1056
|
"""Get the pod environment variable for the given name, if not found return the default
|
|
1023
|
-
If it's a scalar value, will return it, if the value is from source, return the k8s struct (V1EnvVarSource)
|
|
1057
|
+
If it's a scalar value, will return it, if the value is from source, return the k8s struct (V1EnvVarSource)
|
|
1058
|
+
"""
|
|
1024
1059
|
for env_var in self.spec.env:
|
|
1025
1060
|
if get_item_name(env_var) == name:
|
|
1026
1061
|
# valueFrom is a workaround for now, for some reason the envs aren't getting sanitized
|
|
@@ -1050,7 +1085,11 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1050
1085
|
self.spec.env.append(new_var)
|
|
1051
1086
|
return self
|
|
1052
1087
|
|
|
1053
|
-
def set_envs(
|
|
1088
|
+
def set_envs(
|
|
1089
|
+
self,
|
|
1090
|
+
env_vars: typing.Optional[dict] = None,
|
|
1091
|
+
file_path: typing.Optional[str] = None,
|
|
1092
|
+
):
|
|
1054
1093
|
"""set pod environment var from key/value dict or .env file
|
|
1055
1094
|
|
|
1056
1095
|
:param env_vars: dict with env key/values
|
|
@@ -1070,11 +1109,16 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1070
1109
|
else:
|
|
1071
1110
|
raise mlrun.errors.MLRunNotFoundError(f"{file_path} does not exist")
|
|
1072
1111
|
for name, value in env_vars.items():
|
|
1073
|
-
|
|
1112
|
+
if isinstance(value, dict) and "valueFrom" in value:
|
|
1113
|
+
self.set_env(name, value_from=value["valueFrom"])
|
|
1114
|
+
else:
|
|
1115
|
+
self.set_env(name, value)
|
|
1074
1116
|
return self
|
|
1075
1117
|
|
|
1076
1118
|
def set_image_pull_configuration(
|
|
1077
|
-
self,
|
|
1119
|
+
self,
|
|
1120
|
+
image_pull_policy: typing.Optional[str] = None,
|
|
1121
|
+
image_pull_secret_name: typing.Optional[str] = None,
|
|
1078
1122
|
):
|
|
1079
1123
|
"""
|
|
1080
1124
|
Configure the image pull parameters for the runtime.
|
|
@@ -1123,9 +1167,9 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1123
1167
|
|
|
1124
1168
|
def with_limits(
|
|
1125
1169
|
self,
|
|
1126
|
-
mem: str = None,
|
|
1127
|
-
cpu: str = None,
|
|
1128
|
-
gpus: int = None,
|
|
1170
|
+
mem: typing.Optional[str] = None,
|
|
1171
|
+
cpu: typing.Optional[str] = None,
|
|
1172
|
+
gpus: typing.Optional[int] = None,
|
|
1129
1173
|
gpu_type: str = "nvidia.com/gpu",
|
|
1130
1174
|
patch: bool = False,
|
|
1131
1175
|
):
|
|
@@ -1141,7 +1185,12 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1141
1185
|
"""
|
|
1142
1186
|
self.spec.with_limits(mem, cpu, gpus, gpu_type, patch=patch)
|
|
1143
1187
|
|
|
1144
|
-
def with_requests(
|
|
1188
|
+
def with_requests(
|
|
1189
|
+
self,
|
|
1190
|
+
mem: typing.Optional[str] = None,
|
|
1191
|
+
cpu: typing.Optional[str] = None,
|
|
1192
|
+
patch: bool = False,
|
|
1193
|
+
):
|
|
1145
1194
|
"""
|
|
1146
1195
|
Set requested (desired) pod cpu/memory resources
|
|
1147
1196
|
|
|
@@ -1253,6 +1302,36 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1253
1302
|
)
|
|
1254
1303
|
self.spec.security_context = security_context
|
|
1255
1304
|
|
|
1305
|
+
def apply(
|
|
1306
|
+
self,
|
|
1307
|
+
modifier: typing.Callable[["KubeResource"], "KubeResource"],
|
|
1308
|
+
) -> "KubeResource":
|
|
1309
|
+
"""
|
|
1310
|
+
Apply a modifier to the runtime which is used to change the runtimes k8s object's spec.
|
|
1311
|
+
All modifiers accept Kube, apply some changes on its spec and return it so modifiers can be chained
|
|
1312
|
+
one after the other.
|
|
1313
|
+
|
|
1314
|
+
:param modifier: a modifier callable object
|
|
1315
|
+
:return: the runtime (self) after the modifications
|
|
1316
|
+
"""
|
|
1317
|
+
modifier(self)
|
|
1318
|
+
if AutoMountType.is_auto_modifier(modifier):
|
|
1319
|
+
self.spec.disable_auto_mount = True
|
|
1320
|
+
|
|
1321
|
+
api_client = k8s_client.ApiClient()
|
|
1322
|
+
if self.spec.env:
|
|
1323
|
+
for index, env in enumerate(
|
|
1324
|
+
api_client.sanitize_for_serialization(self.spec.env)
|
|
1325
|
+
):
|
|
1326
|
+
self.spec.env[index] = env
|
|
1327
|
+
|
|
1328
|
+
if self.spec.volumes and self.spec.volume_mounts:
|
|
1329
|
+
vols = api_client.sanitize_for_serialization(self.spec.volumes)
|
|
1330
|
+
mounts = api_client.sanitize_for_serialization(self.spec.volume_mounts)
|
|
1331
|
+
self.spec.update_vols_and_mounts(vols, mounts)
|
|
1332
|
+
|
|
1333
|
+
return self
|
|
1334
|
+
|
|
1256
1335
|
def list_valid_priority_class_names(self):
|
|
1257
1336
|
return mlconf.get_valid_function_priority_class_names()
|
|
1258
1337
|
|
|
@@ -1393,15 +1472,13 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1393
1472
|
f"Started building image: {data.get('data', {}).get('spec', {}).get('build', {}).get('image')}"
|
|
1394
1473
|
)
|
|
1395
1474
|
if watch and not ready:
|
|
1396
|
-
state = self._build_watch(
|
|
1475
|
+
self.status.state = self._build_watch(
|
|
1397
1476
|
watch=watch,
|
|
1398
1477
|
show_on_failure=show_on_failure,
|
|
1399
1478
|
)
|
|
1400
|
-
ready = state == "ready"
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
if watch and not ready:
|
|
1404
|
-
raise mlrun.errors.MLRunRuntimeError("Deploy failed")
|
|
1479
|
+
ready = self.status.state == "ready"
|
|
1480
|
+
if not ready:
|
|
1481
|
+
raise mlrun.errors.MLRunRuntimeError("Deploy failed")
|
|
1405
1482
|
return ready
|
|
1406
1483
|
|
|
1407
1484
|
def _build_watch(
|
|
@@ -1412,20 +1489,32 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1412
1489
|
):
|
|
1413
1490
|
db = self._get_db()
|
|
1414
1491
|
offset = 0
|
|
1492
|
+
events_offset = 0
|
|
1415
1493
|
try:
|
|
1416
|
-
text, _ = db.get_builder_status(
|
|
1494
|
+
text, _, deploy_status_text_kind = db.get_builder_status(
|
|
1495
|
+
self,
|
|
1496
|
+
offset=0,
|
|
1497
|
+
logs=logs,
|
|
1498
|
+
events_offset=0,
|
|
1499
|
+
)
|
|
1417
1500
|
except mlrun.db.RunDBError:
|
|
1418
|
-
raise ValueError("
|
|
1501
|
+
raise ValueError("Function or build process not found")
|
|
1419
1502
|
|
|
1420
|
-
def print_log(
|
|
1421
|
-
if
|
|
1503
|
+
def print_log(_text):
|
|
1504
|
+
if _text and (
|
|
1422
1505
|
not show_on_failure
|
|
1423
1506
|
or self.status.state == mlrun.common.schemas.FunctionState.error
|
|
1424
1507
|
):
|
|
1425
|
-
print(
|
|
1508
|
+
print(_text, end="")
|
|
1426
1509
|
|
|
1427
1510
|
print_log(text)
|
|
1428
|
-
|
|
1511
|
+
if (
|
|
1512
|
+
deploy_status_text_kind
|
|
1513
|
+
== mlrun.common.constants.DeployStatusTextKind.events
|
|
1514
|
+
):
|
|
1515
|
+
events_offset += len(text)
|
|
1516
|
+
else:
|
|
1517
|
+
offset += len(text)
|
|
1429
1518
|
if watch:
|
|
1430
1519
|
while self.status.state in [
|
|
1431
1520
|
mlrun.common.schemas.FunctionState.pending,
|
|
@@ -1434,14 +1523,30 @@ class KubeResource(BaseRuntime, KfpAdapterMixin):
|
|
|
1434
1523
|
time.sleep(2)
|
|
1435
1524
|
if show_on_failure:
|
|
1436
1525
|
text = ""
|
|
1437
|
-
db.get_builder_status(self, 0, logs=False)
|
|
1526
|
+
db.get_builder_status(self, offset=0, logs=False, events_offset=0)
|
|
1438
1527
|
if self.status.state == mlrun.common.schemas.FunctionState.error:
|
|
1439
1528
|
# re-read the full log on failure
|
|
1440
|
-
text, _ = db.get_builder_status(
|
|
1529
|
+
text, _, deploy_status_text_kind = db.get_builder_status(
|
|
1530
|
+
self,
|
|
1531
|
+
offset=offset,
|
|
1532
|
+
logs=logs,
|
|
1533
|
+
events_offset=events_offset,
|
|
1534
|
+
)
|
|
1441
1535
|
else:
|
|
1442
|
-
text, _ = db.get_builder_status(
|
|
1536
|
+
text, _, deploy_status_text_kind = db.get_builder_status(
|
|
1537
|
+
self,
|
|
1538
|
+
offset=offset,
|
|
1539
|
+
logs=logs,
|
|
1540
|
+
events_offset=events_offset,
|
|
1541
|
+
)
|
|
1443
1542
|
print_log(text)
|
|
1444
|
-
|
|
1543
|
+
if (
|
|
1544
|
+
deploy_status_text_kind
|
|
1545
|
+
== mlrun.common.constants.DeployStatusTextKind.events
|
|
1546
|
+
):
|
|
1547
|
+
events_offset += len(text)
|
|
1548
|
+
else:
|
|
1549
|
+
offset += len(text)
|
|
1445
1550
|
|
|
1446
1551
|
return self.status.state
|
|
1447
1552
|
|
mlrun/runtimes/remotesparkjob.py
CHANGED
|
@@ -13,12 +13,13 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
import re
|
|
15
15
|
from subprocess import run
|
|
16
|
+
from typing import Optional
|
|
16
17
|
|
|
17
18
|
import kubernetes.client
|
|
18
|
-
from mlrun_pipelines.mounts import mount_v3io, mount_v3iod
|
|
19
19
|
|
|
20
20
|
import mlrun.errors
|
|
21
21
|
from mlrun.config import config
|
|
22
|
+
from mlrun.runtimes.mounts import mount_v3io, mount_v3iod
|
|
22
23
|
|
|
23
24
|
from .kubejob import KubejobRuntime
|
|
24
25
|
from .pod import KubeResourceSpec
|
|
@@ -179,7 +180,7 @@ class RemoteSparkRuntime(KubejobRuntime):
|
|
|
179
180
|
skip_deployed=False,
|
|
180
181
|
is_kfp=False,
|
|
181
182
|
mlrun_version_specifier=None,
|
|
182
|
-
builder_env: dict = None,
|
|
183
|
+
builder_env: Optional[dict] = None,
|
|
183
184
|
show_on_failure: bool = False,
|
|
184
185
|
force_build: bool = False,
|
|
185
186
|
):
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
import typing
|
|
15
15
|
|
|
16
16
|
import kubernetes.client
|
|
17
|
-
from mlrun_pipelines.mounts import mount_v3io, mount_v3iod
|
|
18
17
|
|
|
19
18
|
import mlrun.common.schemas.function
|
|
20
19
|
import mlrun.errors
|
|
21
20
|
import mlrun.k8s_utils
|
|
22
21
|
import mlrun.runtimes.pod
|
|
23
22
|
from mlrun.config import config
|
|
23
|
+
from mlrun.runtimes.mounts import mount_v3io, mount_v3iod
|
|
24
24
|
|
|
25
25
|
from ...execution import MLClientCtx
|
|
26
26
|
from ...model import RunObject
|
|
@@ -405,8 +405,8 @@ class Spark3JobSpec(KubeResourceSpec):
|
|
|
405
405
|
def _verify_and_set_requests(
|
|
406
406
|
self,
|
|
407
407
|
resources_field_name,
|
|
408
|
-
mem: str = None,
|
|
409
|
-
cpu: str = None,
|
|
408
|
+
mem: typing.Optional[str] = None,
|
|
409
|
+
cpu: typing.Optional[str] = None,
|
|
410
410
|
patch: bool = False,
|
|
411
411
|
):
|
|
412
412
|
# Spark operator uses JVM notation for memory, so we must verify it separately
|
|
@@ -774,7 +774,11 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
774
774
|
exporter_jar="/spark/jars/jmx_prometheus_javaagent-0.16.1.jar",
|
|
775
775
|
)
|
|
776
776
|
|
|
777
|
-
def with_cores(
|
|
777
|
+
def with_cores(
|
|
778
|
+
self,
|
|
779
|
+
executor_cores: typing.Optional[int] = None,
|
|
780
|
+
driver_cores: typing.Optional[int] = None,
|
|
781
|
+
):
|
|
778
782
|
"""
|
|
779
783
|
Allows to configure spark.executor.cores and spark.driver.cores parameters. The values must be integers
|
|
780
784
|
greater than or equal to 1. If a parameter is not specified, it defaults to 1.
|
|
@@ -785,7 +789,7 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
785
789
|
Spark itself uses the spec.[executor|driver].cores parameter to set the parallelism of tasks and cores
|
|
786
790
|
assigned to each task within the pod. This function sets the .cores parameters for the job executed.
|
|
787
791
|
|
|
788
|
-
See https://github.com/
|
|
792
|
+
See https://github.com/kubeflow/spark-operator/issues/581 for a discussion about those
|
|
789
793
|
parameters and their meaning in Spark operator.
|
|
790
794
|
|
|
791
795
|
:param executor_cores: Number of cores to use for executor (spark.executor.cores)
|
|
@@ -853,7 +857,7 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
853
857
|
skip_deployed=False,
|
|
854
858
|
is_kfp=False,
|
|
855
859
|
mlrun_version_specifier=None,
|
|
856
|
-
builder_env: dict = None,
|
|
860
|
+
builder_env: typing.Optional[dict] = None,
|
|
857
861
|
show_on_failure: bool = False,
|
|
858
862
|
force_build: bool = False,
|
|
859
863
|
):
|
|
@@ -944,7 +948,10 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
944
948
|
)
|
|
945
949
|
|
|
946
950
|
def with_executor_requests(
|
|
947
|
-
self,
|
|
951
|
+
self,
|
|
952
|
+
mem: typing.Optional[str] = None,
|
|
953
|
+
cpu: typing.Optional[str] = None,
|
|
954
|
+
patch: bool = False,
|
|
948
955
|
):
|
|
949
956
|
"""
|
|
950
957
|
set executor pod required cpu/memory/gpu resources
|
|
@@ -954,8 +961,8 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
954
961
|
|
|
955
962
|
def with_executor_limits(
|
|
956
963
|
self,
|
|
957
|
-
cpu: str = None,
|
|
958
|
-
gpus: int = None,
|
|
964
|
+
cpu: typing.Optional[str] = None,
|
|
965
|
+
gpus: typing.Optional[int] = None,
|
|
959
966
|
gpu_type: str = "nvidia.com/gpu",
|
|
960
967
|
patch: bool = False,
|
|
961
968
|
):
|
|
@@ -970,7 +977,10 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
970
977
|
)
|
|
971
978
|
|
|
972
979
|
def with_driver_requests(
|
|
973
|
-
self,
|
|
980
|
+
self,
|
|
981
|
+
mem: typing.Optional[str] = None,
|
|
982
|
+
cpu: typing.Optional[str] = None,
|
|
983
|
+
patch: bool = False,
|
|
974
984
|
):
|
|
975
985
|
"""
|
|
976
986
|
set driver pod required cpu/memory/gpu resources
|
|
@@ -980,8 +990,8 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
980
990
|
|
|
981
991
|
def with_driver_limits(
|
|
982
992
|
self,
|
|
983
|
-
cpu: str = None,
|
|
984
|
-
gpus: int = None,
|
|
993
|
+
cpu: typing.Optional[str] = None,
|
|
994
|
+
gpus: typing.Optional[int] = None,
|
|
985
995
|
gpu_type: str = "nvidia.com/gpu",
|
|
986
996
|
patch: bool = False,
|
|
987
997
|
):
|
mlrun/runtimes/utils.py
CHANGED
|
@@ -18,6 +18,7 @@ import os
|
|
|
18
18
|
import re
|
|
19
19
|
from io import StringIO
|
|
20
20
|
from sys import stderr
|
|
21
|
+
from typing import Optional
|
|
21
22
|
|
|
22
23
|
import pandas as pd
|
|
23
24
|
|
|
@@ -147,7 +148,7 @@ def add_code_metadata(path=""):
|
|
|
147
148
|
|
|
148
149
|
def results_to_iter(results, runspec, execution):
|
|
149
150
|
if not results:
|
|
150
|
-
logger.error("
|
|
151
|
+
logger.error("Got an empty results list in to_iter")
|
|
151
152
|
return
|
|
152
153
|
|
|
153
154
|
iter = []
|
|
@@ -174,7 +175,7 @@ def results_to_iter(results, runspec, execution):
|
|
|
174
175
|
|
|
175
176
|
if not iter:
|
|
176
177
|
execution.set_state("completed", commit=True)
|
|
177
|
-
logger.warning("
|
|
178
|
+
logger.warning("Warning!, zero iteration results")
|
|
178
179
|
return
|
|
179
180
|
if hasattr(pd, "json_normalize"):
|
|
180
181
|
df = pd.json_normalize(iter).sort_values("iter")
|
|
@@ -189,10 +190,10 @@ def results_to_iter(results, runspec, execution):
|
|
|
189
190
|
item, id = selector(results, criteria)
|
|
190
191
|
if runspec.spec.selector and not id:
|
|
191
192
|
logger.warning(
|
|
192
|
-
f"
|
|
193
|
+
f"No best result selected, check selector ({criteria}) or results"
|
|
193
194
|
)
|
|
194
195
|
if id:
|
|
195
|
-
logger.info(f"
|
|
196
|
+
logger.info(f"Best iteration={id}, used criteria {criteria}")
|
|
196
197
|
task = results[item] if id and results else None
|
|
197
198
|
execution.log_iteration_results(id, summary, task)
|
|
198
199
|
|
|
@@ -432,11 +433,11 @@ def enrich_function_from_dict(function, function_dict):
|
|
|
432
433
|
|
|
433
434
|
def enrich_run_labels(
|
|
434
435
|
labels: dict,
|
|
435
|
-
labels_to_enrich: list[RunLabels] = None,
|
|
436
|
+
labels_to_enrich: Optional[list[RunLabels]] = None,
|
|
436
437
|
):
|
|
437
438
|
labels_enrichment = {
|
|
438
439
|
RunLabels.owner: os.environ.get("V3IO_USERNAME") or getpass.getuser(),
|
|
439
|
-
# TODO: remove this in 1.
|
|
440
|
+
# TODO: remove this in 1.10.0
|
|
440
441
|
RunLabels.v3io_user: os.environ.get("V3IO_USERNAME"),
|
|
441
442
|
}
|
|
442
443
|
labels_to_enrich = labels_to_enrich or RunLabels.all()
|
mlrun/secrets.py
CHANGED
|
@@ -134,7 +134,7 @@ class SecretsStore:
|
|
|
134
134
|
def k8s_env_variable_name_for_secret(secret_name):
|
|
135
135
|
from mlrun.config import config
|
|
136
136
|
|
|
137
|
-
return config.secret_stores.kubernetes.env_variable_prefix + secret_name
|
|
137
|
+
return config.secret_stores.kubernetes.env_variable_prefix + secret_name
|
|
138
138
|
|
|
139
139
|
def get_k8s_secrets(self):
|
|
140
140
|
for source in self._hidden_sources:
|
|
@@ -151,7 +151,7 @@ def get_secret_or_env(
|
|
|
151
151
|
secret_provider: Union[dict, SecretsStore, Callable, None] = None,
|
|
152
152
|
default: Optional[str] = None,
|
|
153
153
|
prefix: Optional[str] = None,
|
|
154
|
-
) -> str:
|
|
154
|
+
) -> Optional[str]:
|
|
155
155
|
"""Retrieve value of a secret, either from a user-provided secret store, or from environment variables.
|
|
156
156
|
The function will retrieve a secret value, attempting to find it according to the following order:
|
|
157
157
|
|
mlrun/serving/__init__.py
CHANGED
|
@@ -23,6 +23,10 @@ __all__ = [
|
|
|
23
23
|
"QueueStep",
|
|
24
24
|
"ErrorStep",
|
|
25
25
|
"MonitoringApplicationStep",
|
|
26
|
+
"ModelRunnerStep",
|
|
27
|
+
"ModelRunner",
|
|
28
|
+
"Model",
|
|
29
|
+
"ModelSelector",
|
|
26
30
|
]
|
|
27
31
|
|
|
28
32
|
from .routers import ModelRouter, VotingEnsemble # noqa
|
|
@@ -33,6 +37,10 @@ from .states import (
|
|
|
33
37
|
RouterStep,
|
|
34
38
|
TaskStep,
|
|
35
39
|
MonitoringApplicationStep,
|
|
40
|
+
ModelRunnerStep,
|
|
41
|
+
ModelRunner,
|
|
42
|
+
Model,
|
|
43
|
+
ModelSelector,
|
|
36
44
|
) # noqa
|
|
37
45
|
from .v1_serving import MLModelServer, new_v1_model_server # noqa
|
|
38
46
|
from .v2_serving import V2ModelServer # noqa
|
mlrun/serving/merger.py
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
15
|
|
|
16
|
+
from typing import Optional
|
|
17
|
+
|
|
16
18
|
import storey
|
|
17
19
|
|
|
18
20
|
|
|
@@ -37,10 +39,10 @@ class CacheEntry:
|
|
|
37
39
|
class Merge(storey.Flow):
|
|
38
40
|
def __init__(
|
|
39
41
|
self,
|
|
40
|
-
full_event: bool = None,
|
|
41
|
-
key_path: str = None,
|
|
42
|
-
max_behind: int = None,
|
|
43
|
-
expected_num_events: int = None,
|
|
42
|
+
full_event: Optional[bool] = None,
|
|
43
|
+
key_path: Optional[str] = None,
|
|
44
|
+
max_behind: Optional[int] = None,
|
|
45
|
+
expected_num_events: Optional[int] = None,
|
|
44
46
|
**kwargs,
|
|
45
47
|
):
|
|
46
48
|
"""Merge multiple events based on event id or provided key path
|
|
@@ -72,7 +74,7 @@ class Merge(storey.Flow):
|
|
|
72
74
|
self._queue_len = max_behind or 64 # default queue is 64 entries
|
|
73
75
|
self._keys_queue = []
|
|
74
76
|
|
|
75
|
-
def post_init(self, mode="sync"):
|
|
77
|
+
def post_init(self, mode="sync", **kwargs):
|
|
76
78
|
# auto detect number of uplinks or use user specified value
|
|
77
79
|
self._uplinks = self.expected_num_events or (
|
|
78
80
|
len(self._graph_step.after) if self._graph_step else 0
|