mlrun 1.7.1rc10__py3-none-any.whl → 1.8.0rc11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__init__.py +23 -21
- mlrun/__main__.py +3 -3
- mlrun/alerts/alert.py +148 -14
- mlrun/artifacts/__init__.py +2 -3
- mlrun/artifacts/base.py +55 -12
- mlrun/artifacts/dataset.py +16 -16
- mlrun/artifacts/document.py +378 -0
- mlrun/artifacts/manager.py +26 -17
- mlrun/artifacts/model.py +66 -53
- mlrun/common/constants.py +8 -0
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/feature_set.py +1 -0
- mlrun/common/formatters/function.py +1 -0
- mlrun/{model_monitoring/db/stores/base/__init__.py → common/formatters/model_endpoint.py} +16 -1
- 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 +1 -29
- mlrun/common/runtimes/constants.py +1 -2
- mlrun/common/schemas/__init__.py +6 -2
- mlrun/common/schemas/alert.py +111 -19
- mlrun/common/schemas/api_gateway.py +3 -3
- mlrun/common/schemas/artifact.py +11 -7
- mlrun/common/schemas/auth.py +6 -4
- mlrun/common/schemas/background_task.py +7 -7
- mlrun/common/schemas/client_spec.py +2 -3
- 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 +2 -1
- mlrun/common/schemas/model_monitoring/constants.py +67 -14
- mlrun/common/schemas/model_monitoring/grafana.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoints.py +92 -147
- 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 +137 -0
- mlrun/common/schemas/pipeline.py +2 -2
- mlrun/common/schemas/project.py +25 -17
- mlrun/common/schemas/runs.py +2 -2
- mlrun/common/schemas/runtime_resource.py +5 -5
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/schemas/secret.py +1 -1
- mlrun/common/schemas/tag.py +3 -3
- mlrun/common/schemas/workflow.py +5 -5
- mlrun/config.py +68 -10
- mlrun/data_types/__init__.py +0 -2
- mlrun/data_types/data_types.py +1 -0
- mlrun/data_types/infer.py +3 -1
- mlrun/data_types/spark.py +5 -3
- mlrun/data_types/to_pandas.py +11 -2
- mlrun/datastore/__init__.py +2 -2
- mlrun/datastore/alibaba_oss.py +4 -1
- mlrun/datastore/azure_blob.py +4 -1
- mlrun/datastore/base.py +12 -4
- mlrun/datastore/datastore.py +9 -3
- mlrun/datastore/datastore_profile.py +79 -20
- 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 +4 -1
- mlrun/datastore/sources.py +52 -51
- mlrun/datastore/store_resources.py +7 -4
- mlrun/datastore/targets.py +23 -22
- mlrun/datastore/utils.py +2 -2
- mlrun/datastore/v3io.py +4 -1
- mlrun/datastore/vectorstore.py +229 -0
- mlrun/datastore/wasbfs/fs.py +13 -12
- mlrun/db/base.py +213 -83
- mlrun/db/factory.py +0 -3
- mlrun/db/httpdb.py +1265 -387
- mlrun/db/nopdb.py +205 -74
- mlrun/errors.py +2 -2
- mlrun/execution.py +136 -50
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +41 -40
- mlrun/feature_store/common.py +9 -9
- mlrun/feature_store/feature_set.py +20 -18
- mlrun/feature_store/feature_vector.py +27 -24
- mlrun/feature_store/retrieval/base.py +14 -9
- mlrun/feature_store/retrieval/job.py +2 -1
- mlrun/feature_store/steps.py +2 -2
- 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 +29 -27
- 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/launcher/base.py +3 -4
- mlrun/launcher/local.py +1 -1
- mlrun/launcher/remote.py +1 -1
- mlrun/lists.py +4 -3
- mlrun/model.py +117 -46
- mlrun/model_monitoring/__init__.py +4 -4
- mlrun/model_monitoring/api.py +72 -59
- mlrun/model_monitoring/applications/_application_steps.py +17 -17
- mlrun/model_monitoring/applications/base.py +165 -6
- mlrun/model_monitoring/applications/context.py +88 -37
- mlrun/model_monitoring/applications/evidently_base.py +0 -1
- mlrun/model_monitoring/applications/histogram_data_drift.py +43 -21
- mlrun/model_monitoring/applications/results.py +55 -3
- mlrun/model_monitoring/controller.py +207 -239
- mlrun/model_monitoring/db/__init__.py +0 -2
- mlrun/model_monitoring/db/_schedules.py +156 -0
- mlrun/model_monitoring/db/_stats.py +189 -0
- mlrun/model_monitoring/db/tsdb/base.py +78 -25
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +61 -6
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +255 -29
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +78 -17
- mlrun/model_monitoring/helpers.py +151 -49
- mlrun/model_monitoring/stream_processing.py +99 -283
- mlrun/model_monitoring/tracking_policy.py +10 -3
- mlrun/model_monitoring/writer.py +48 -36
- mlrun/package/__init__.py +3 -6
- mlrun/package/context_handler.py +1 -1
- 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 +31 -14
- 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 +27 -27
- mlrun/projects/pipelines.py +71 -36
- mlrun/projects/project.py +890 -220
- mlrun/run.py +53 -10
- mlrun/runtimes/__init__.py +1 -3
- mlrun/runtimes/base.py +15 -11
- mlrun/runtimes/daskjob.py +9 -9
- mlrun/runtimes/generators.py +2 -1
- mlrun/runtimes/kubejob.py +4 -5
- mlrun/runtimes/mounts.py +572 -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 -11
- mlrun/runtimes/nuclio/function.py +19 -17
- mlrun/runtimes/nuclio/serving.py +18 -13
- mlrun/runtimes/pod.py +154 -45
- mlrun/runtimes/remotesparkjob.py +3 -2
- mlrun/runtimes/sparkjob/__init__.py +0 -2
- mlrun/runtimes/sparkjob/spark3job.py +21 -11
- mlrun/runtimes/utils.py +6 -5
- mlrun/serving/merger.py +6 -4
- mlrun/serving/remote.py +18 -17
- mlrun/serving/routers.py +185 -172
- mlrun/serving/server.py +7 -1
- mlrun/serving/states.py +97 -78
- mlrun/serving/utils.py +13 -2
- mlrun/serving/v1_serving.py +3 -2
- mlrun/serving/v2_serving.py +105 -72
- 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 +1 -1
- mlrun/utils/clones.py +1 -1
- mlrun/utils/helpers.py +63 -19
- mlrun/utils/logger.py +106 -4
- mlrun/utils/notifications/notification/__init__.py +22 -19
- mlrun/utils/notifications/notification/base.py +33 -14
- 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 +6 -6
- mlrun/utils/notifications/notification/webhook.py +6 -6
- mlrun/utils/notifications/notification_pusher.py +86 -44
- mlrun/utils/regex.py +11 -2
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/METADATA +29 -24
- mlrun-1.8.0rc11.dist-info/RECORD +347 -0
- 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/__init__.py +0 -13
- 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/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -726
- mlrun/model_monitoring/model_endpoint.py +0 -118
- mlrun-1.7.1rc10.dist-info/RECORD +0 -351
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/LICENSE +0 -0
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/WHEEL +0 -0
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/top_level.txt +0 -0
mlrun/serving/states.py
CHANGED
|
@@ -25,7 +25,7 @@ import pathlib
|
|
|
25
25
|
import traceback
|
|
26
26
|
from copy import copy, deepcopy
|
|
27
27
|
from inspect import getfullargspec, signature
|
|
28
|
-
from typing import Any, Union
|
|
28
|
+
from typing import Any, Optional, Union
|
|
29
29
|
|
|
30
30
|
import storey.utils
|
|
31
31
|
|
|
@@ -104,7 +104,12 @@ class BaseStep(ModelObj):
|
|
|
104
104
|
default_shape = "ellipse"
|
|
105
105
|
_dict_fields = ["kind", "comment", "after", "on_error"]
|
|
106
106
|
|
|
107
|
-
def __init__(
|
|
107
|
+
def __init__(
|
|
108
|
+
self,
|
|
109
|
+
name: Optional[str] = None,
|
|
110
|
+
after: Optional[list] = None,
|
|
111
|
+
shape: Optional[str] = None,
|
|
112
|
+
):
|
|
108
113
|
self.name = name
|
|
109
114
|
self._parent = None
|
|
110
115
|
self.comment = None
|
|
@@ -154,14 +159,14 @@ class BaseStep(ModelObj):
|
|
|
154
159
|
|
|
155
160
|
def error_handler(
|
|
156
161
|
self,
|
|
157
|
-
name: str = None,
|
|
162
|
+
name: Optional[str] = None,
|
|
158
163
|
class_name=None,
|
|
159
164
|
handler=None,
|
|
160
165
|
before=None,
|
|
161
166
|
function=None,
|
|
162
|
-
full_event: bool = None,
|
|
163
|
-
input_path: str = None,
|
|
164
|
-
result_path: str = None,
|
|
167
|
+
full_event: Optional[bool] = None,
|
|
168
|
+
input_path: Optional[str] = None,
|
|
169
|
+
result_path: Optional[str] = None,
|
|
165
170
|
**class_args,
|
|
166
171
|
):
|
|
167
172
|
"""set error handler on a step or the entire graph (to be executed on failure/raise)
|
|
@@ -297,13 +302,13 @@ class BaseStep(ModelObj):
|
|
|
297
302
|
def to(
|
|
298
303
|
self,
|
|
299
304
|
class_name: Union[str, StepToDict] = None,
|
|
300
|
-
name: str = None,
|
|
301
|
-
handler: str = None,
|
|
302
|
-
graph_shape: str = None,
|
|
303
|
-
function: str = None,
|
|
304
|
-
full_event: bool = None,
|
|
305
|
-
input_path: str = None,
|
|
306
|
-
result_path: str = None,
|
|
305
|
+
name: Optional[str] = None,
|
|
306
|
+
handler: Optional[str] = None,
|
|
307
|
+
graph_shape: Optional[str] = None,
|
|
308
|
+
function: Optional[str] = None,
|
|
309
|
+
full_event: Optional[bool] = None,
|
|
310
|
+
input_path: Optional[str] = None,
|
|
311
|
+
result_path: Optional[str] = None,
|
|
307
312
|
**class_args,
|
|
308
313
|
):
|
|
309
314
|
"""add a step right after this step and return the new step
|
|
@@ -404,16 +409,16 @@ class TaskStep(BaseStep):
|
|
|
404
409
|
|
|
405
410
|
def __init__(
|
|
406
411
|
self,
|
|
407
|
-
class_name: Union[str, type] = None,
|
|
408
|
-
class_args: dict = None,
|
|
409
|
-
handler: str = None,
|
|
410
|
-
name: str = None,
|
|
411
|
-
after: list = None,
|
|
412
|
-
full_event: bool = None,
|
|
413
|
-
function: str = None,
|
|
414
|
-
responder: bool = None,
|
|
415
|
-
input_path: str = None,
|
|
416
|
-
result_path: str = None,
|
|
412
|
+
class_name: Optional[Union[str, type]] = None,
|
|
413
|
+
class_args: Optional[dict] = None,
|
|
414
|
+
handler: Optional[str] = None,
|
|
415
|
+
name: Optional[str] = None,
|
|
416
|
+
after: Optional[list] = None,
|
|
417
|
+
full_event: Optional[bool] = None,
|
|
418
|
+
function: Optional[str] = None,
|
|
419
|
+
responder: Optional[bool] = None,
|
|
420
|
+
input_path: Optional[str] = None,
|
|
421
|
+
result_path: Optional[str] = None,
|
|
417
422
|
):
|
|
418
423
|
super().__init__(name, after)
|
|
419
424
|
self.class_name = class_name
|
|
@@ -552,6 +557,8 @@ class TaskStep(BaseStep):
|
|
|
552
557
|
self._object.post_init(mode)
|
|
553
558
|
if hasattr(self._object, "model_endpoint_uid"):
|
|
554
559
|
self.endpoint_uid = self._object.model_endpoint_uid
|
|
560
|
+
if hasattr(self._object, "name"):
|
|
561
|
+
self.endpoint_name = self._object.name
|
|
555
562
|
|
|
556
563
|
def respond(self):
|
|
557
564
|
"""mark this step as the responder.
|
|
@@ -607,16 +614,16 @@ class MonitoringApplicationStep(TaskStep):
|
|
|
607
614
|
|
|
608
615
|
def __init__(
|
|
609
616
|
self,
|
|
610
|
-
class_name: Union[str, type] = None,
|
|
611
|
-
class_args: dict = None,
|
|
612
|
-
handler: str = None,
|
|
613
|
-
name: str = None,
|
|
614
|
-
after: list = None,
|
|
615
|
-
full_event: bool = None,
|
|
616
|
-
function: str = None,
|
|
617
|
-
responder: bool = None,
|
|
618
|
-
input_path: str = None,
|
|
619
|
-
result_path: str = None,
|
|
617
|
+
class_name: Optional[Union[str, type]] = None,
|
|
618
|
+
class_args: Optional[dict] = None,
|
|
619
|
+
handler: Optional[str] = None,
|
|
620
|
+
name: Optional[str] = None,
|
|
621
|
+
after: Optional[list] = None,
|
|
622
|
+
full_event: Optional[bool] = None,
|
|
623
|
+
function: Optional[str] = None,
|
|
624
|
+
responder: Optional[bool] = None,
|
|
625
|
+
input_path: Optional[str] = None,
|
|
626
|
+
result_path: Optional[str] = None,
|
|
620
627
|
):
|
|
621
628
|
super().__init__(
|
|
622
629
|
class_name=class_name,
|
|
@@ -641,16 +648,16 @@ class ErrorStep(TaskStep):
|
|
|
641
648
|
|
|
642
649
|
def __init__(
|
|
643
650
|
self,
|
|
644
|
-
class_name: Union[str, type] = None,
|
|
645
|
-
class_args: dict = None,
|
|
646
|
-
handler: str = None,
|
|
647
|
-
name: str = None,
|
|
648
|
-
after: list = None,
|
|
649
|
-
full_event: bool = None,
|
|
650
|
-
function: str = None,
|
|
651
|
-
responder: bool = None,
|
|
652
|
-
input_path: str = None,
|
|
653
|
-
result_path: str = None,
|
|
651
|
+
class_name: Optional[Union[str, type]] = None,
|
|
652
|
+
class_args: Optional[dict] = None,
|
|
653
|
+
handler: Optional[str] = None,
|
|
654
|
+
name: Optional[str] = None,
|
|
655
|
+
after: Optional[list] = None,
|
|
656
|
+
full_event: Optional[bool] = None,
|
|
657
|
+
function: Optional[str] = None,
|
|
658
|
+
responder: Optional[bool] = None,
|
|
659
|
+
input_path: Optional[str] = None,
|
|
660
|
+
result_path: Optional[str] = None,
|
|
654
661
|
):
|
|
655
662
|
super().__init__(
|
|
656
663
|
class_name=class_name,
|
|
@@ -678,14 +685,14 @@ class RouterStep(TaskStep):
|
|
|
678
685
|
|
|
679
686
|
def __init__(
|
|
680
687
|
self,
|
|
681
|
-
class_name: Union[str, type] = None,
|
|
682
|
-
class_args: dict = None,
|
|
683
|
-
handler: str = None,
|
|
684
|
-
routes: list = None,
|
|
685
|
-
name: str = None,
|
|
686
|
-
function: str = None,
|
|
687
|
-
input_path: str = None,
|
|
688
|
-
result_path: str = None,
|
|
688
|
+
class_name: Optional[Union[str, type]] = None,
|
|
689
|
+
class_args: Optional[dict] = None,
|
|
690
|
+
handler: Optional[str] = None,
|
|
691
|
+
routes: Optional[list] = None,
|
|
692
|
+
name: Optional[str] = None,
|
|
693
|
+
function: Optional[str] = None,
|
|
694
|
+
input_path: Optional[str] = None,
|
|
695
|
+
result_path: Optional[str] = None,
|
|
689
696
|
):
|
|
690
697
|
super().__init__(
|
|
691
698
|
class_name,
|
|
@@ -813,12 +820,12 @@ class QueueStep(BaseStep):
|
|
|
813
820
|
|
|
814
821
|
def __init__(
|
|
815
822
|
self,
|
|
816
|
-
name: str = None,
|
|
817
|
-
path: str = None,
|
|
818
|
-
after: list = None,
|
|
819
|
-
shards: int = None,
|
|
820
|
-
retention_in_hours: int = None,
|
|
821
|
-
trigger_args: dict = None,
|
|
823
|
+
name: Optional[str] = None,
|
|
824
|
+
path: Optional[str] = None,
|
|
825
|
+
after: Optional[list] = None,
|
|
826
|
+
shards: Optional[int] = None,
|
|
827
|
+
retention_in_hours: Optional[int] = None,
|
|
828
|
+
trigger_args: Optional[dict] = None,
|
|
822
829
|
**options,
|
|
823
830
|
):
|
|
824
831
|
super().__init__(name, after)
|
|
@@ -850,13 +857,13 @@ class QueueStep(BaseStep):
|
|
|
850
857
|
def to(
|
|
851
858
|
self,
|
|
852
859
|
class_name: Union[str, StepToDict] = None,
|
|
853
|
-
name: str = None,
|
|
854
|
-
handler: str = None,
|
|
855
|
-
graph_shape: str = None,
|
|
856
|
-
function: str = None,
|
|
857
|
-
full_event: bool = None,
|
|
858
|
-
input_path: str = None,
|
|
859
|
-
result_path: str = None,
|
|
860
|
+
name: Optional[str] = None,
|
|
861
|
+
handler: Optional[str] = None,
|
|
862
|
+
graph_shape: Optional[str] = None,
|
|
863
|
+
function: Optional[str] = None,
|
|
864
|
+
full_event: Optional[bool] = None,
|
|
865
|
+
input_path: Optional[str] = None,
|
|
866
|
+
result_path: Optional[str] = None,
|
|
860
867
|
**class_args,
|
|
861
868
|
):
|
|
862
869
|
if not function:
|
|
@@ -905,7 +912,7 @@ class FlowStep(BaseStep):
|
|
|
905
912
|
self,
|
|
906
913
|
name=None,
|
|
907
914
|
steps=None,
|
|
908
|
-
after: list = None,
|
|
915
|
+
after: Optional[list] = None,
|
|
909
916
|
engine=None,
|
|
910
917
|
final_step=None,
|
|
911
918
|
):
|
|
@@ -948,9 +955,9 @@ class FlowStep(BaseStep):
|
|
|
948
955
|
before=None,
|
|
949
956
|
graph_shape=None,
|
|
950
957
|
function=None,
|
|
951
|
-
full_event: bool = None,
|
|
952
|
-
input_path: str = None,
|
|
953
|
-
result_path: str = None,
|
|
958
|
+
full_event: Optional[bool] = None,
|
|
959
|
+
input_path: Optional[str] = None,
|
|
960
|
+
result_path: Optional[str] = None,
|
|
954
961
|
**class_args,
|
|
955
962
|
):
|
|
956
963
|
"""add task, queue or router step/class to the flow
|
|
@@ -1037,7 +1044,7 @@ class FlowStep(BaseStep):
|
|
|
1037
1044
|
self._last_added = step
|
|
1038
1045
|
return step
|
|
1039
1046
|
|
|
1040
|
-
def clear_children(self, steps: list = None):
|
|
1047
|
+
def clear_children(self, steps: Optional[list] = None):
|
|
1041
1048
|
"""remove some or all of the states, empty/None for all"""
|
|
1042
1049
|
if not steps:
|
|
1043
1050
|
steps = self._steps.keys()
|
|
@@ -1282,11 +1289,19 @@ class FlowStep(BaseStep):
|
|
|
1282
1289
|
if self._controller:
|
|
1283
1290
|
# async flow (using storey)
|
|
1284
1291
|
event._awaitable_result = None
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1292
|
+
if self.context.is_mock:
|
|
1293
|
+
resp = self._controller.emit(
|
|
1294
|
+
event, return_awaitable_result=self._wait_for_result
|
|
1295
|
+
)
|
|
1296
|
+
if self._wait_for_result and resp:
|
|
1297
|
+
return resp.await_result()
|
|
1298
|
+
else:
|
|
1299
|
+
resp_awaitable = self._controller.emit(
|
|
1300
|
+
event, await_result=self._wait_for_result
|
|
1301
|
+
)
|
|
1302
|
+
if self._wait_for_result:
|
|
1303
|
+
return resp_awaitable
|
|
1304
|
+
return self._await_and_return_id(resp_awaitable, event)
|
|
1290
1305
|
event = copy(event)
|
|
1291
1306
|
event.body = {"id": event.id}
|
|
1292
1307
|
return event
|
|
@@ -1554,8 +1569,8 @@ def params_to_step(
|
|
|
1554
1569
|
graph_shape=None,
|
|
1555
1570
|
function=None,
|
|
1556
1571
|
full_event=None,
|
|
1557
|
-
input_path: str = None,
|
|
1558
|
-
result_path: str = None,
|
|
1572
|
+
input_path: Optional[str] = None,
|
|
1573
|
+
result_path: Optional[str] = None,
|
|
1559
1574
|
class_args=None,
|
|
1560
1575
|
):
|
|
1561
1576
|
"""return step object from provided params or classes/objects"""
|
|
@@ -1703,8 +1718,12 @@ def _init_async_objects(context, steps):
|
|
|
1703
1718
|
is_explicit_ack_supported(context) and mlrun.mlconf.is_explicit_ack_enabled()
|
|
1704
1719
|
)
|
|
1705
1720
|
|
|
1706
|
-
|
|
1707
|
-
|
|
1721
|
+
if context.is_mock:
|
|
1722
|
+
source_class = storey.SyncEmitSource
|
|
1723
|
+
else:
|
|
1724
|
+
source_class = storey.AsyncEmitSource
|
|
1725
|
+
|
|
1726
|
+
default_source = source_class(
|
|
1708
1727
|
context=context,
|
|
1709
1728
|
explicit_ack=explicit_ack,
|
|
1710
1729
|
**source_args,
|
mlrun/serving/utils.py
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
15
|
import inspect
|
|
16
|
+
from typing import Optional
|
|
16
17
|
|
|
17
18
|
from mlrun.utils import get_in, update_in
|
|
18
19
|
|
|
@@ -55,7 +56,12 @@ class StepToDict:
|
|
|
55
56
|
"kwargs",
|
|
56
57
|
]
|
|
57
58
|
|
|
58
|
-
def to_dict(
|
|
59
|
+
def to_dict(
|
|
60
|
+
self,
|
|
61
|
+
fields: Optional[list] = None,
|
|
62
|
+
exclude: Optional[list] = None,
|
|
63
|
+
strip: bool = False,
|
|
64
|
+
):
|
|
59
65
|
"""convert the step object to a python dictionary"""
|
|
60
66
|
fields = fields or getattr(self, "_dict_fields", None)
|
|
61
67
|
if not fields:
|
|
@@ -105,5 +111,10 @@ class MonitoringApplicationToDict(StepToDict):
|
|
|
105
111
|
class RouterToDict(StepToDict):
|
|
106
112
|
_STEP_KIND = "router"
|
|
107
113
|
|
|
108
|
-
def to_dict(
|
|
114
|
+
def to_dict(
|
|
115
|
+
self,
|
|
116
|
+
fields: Optional[list] = None,
|
|
117
|
+
exclude: Optional[list] = None,
|
|
118
|
+
strip: bool = False,
|
|
119
|
+
):
|
|
109
120
|
return super().to_dict(exclude=["routes"], strip=strip)
|
mlrun/serving/v1_serving.py
CHANGED
|
@@ -18,6 +18,7 @@ import socket
|
|
|
18
18
|
from copy import deepcopy
|
|
19
19
|
from datetime import datetime
|
|
20
20
|
from io import BytesIO
|
|
21
|
+
from typing import Optional
|
|
21
22
|
from urllib.request import urlopen
|
|
22
23
|
|
|
23
24
|
import nuclio
|
|
@@ -33,7 +34,7 @@ serving_handler = "handler"
|
|
|
33
34
|
def new_v1_model_server(
|
|
34
35
|
name,
|
|
35
36
|
model_class: str,
|
|
36
|
-
models: dict = None,
|
|
37
|
+
models: Optional[dict] = None,
|
|
37
38
|
filename="",
|
|
38
39
|
protocol="",
|
|
39
40
|
image="",
|
|
@@ -68,7 +69,7 @@ def new_v1_model_server(
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
class MLModelServer:
|
|
71
|
-
def __init__(self, name: str, model_dir: str = None, model=None):
|
|
72
|
+
def __init__(self, name: str, model_dir: Optional[str] = None, model=None):
|
|
72
73
|
self.name = name
|
|
73
74
|
self.ready = False
|
|
74
75
|
self.model_dir = model_dir
|
mlrun/serving/v2_serving.py
CHANGED
|
@@ -21,10 +21,9 @@ import mlrun.artifacts
|
|
|
21
21
|
import mlrun.common.model_monitoring.helpers
|
|
22
22
|
import mlrun.common.schemas.model_monitoring
|
|
23
23
|
import mlrun.model_monitoring
|
|
24
|
-
from mlrun.errors import err_to_str
|
|
25
24
|
from mlrun.utils import logger, now_date
|
|
26
25
|
|
|
27
|
-
from ..common.
|
|
26
|
+
from ..common.schemas.model_monitoring import ModelEndpointSchema
|
|
28
27
|
from .server import GraphServer
|
|
29
28
|
from .utils import StepToDict, _extract_input_data, _update_result_body
|
|
30
29
|
|
|
@@ -33,12 +32,12 @@ class V2ModelServer(StepToDict):
|
|
|
33
32
|
def __init__(
|
|
34
33
|
self,
|
|
35
34
|
context=None,
|
|
36
|
-
name: str = None,
|
|
37
|
-
model_path: str = None,
|
|
35
|
+
name: Optional[str] = None,
|
|
36
|
+
model_path: Optional[str] = None,
|
|
38
37
|
model=None,
|
|
39
38
|
protocol=None,
|
|
40
|
-
input_path: str = None,
|
|
41
|
-
result_path: str = None,
|
|
39
|
+
input_path: Optional[str] = None,
|
|
40
|
+
result_path: Optional[str] = None,
|
|
42
41
|
shard_by_endpoint: Optional[bool] = None,
|
|
43
42
|
**kwargs,
|
|
44
43
|
):
|
|
@@ -110,12 +109,6 @@ class V2ModelServer(StepToDict):
|
|
|
110
109
|
self._result_path = result_path
|
|
111
110
|
self._kwargs = kwargs # for to_dict()
|
|
112
111
|
self._params = kwargs
|
|
113
|
-
self._model_logger = (
|
|
114
|
-
_ModelLogPusher(self, context)
|
|
115
|
-
if context and context.stream.enabled
|
|
116
|
-
else None
|
|
117
|
-
)
|
|
118
|
-
|
|
119
112
|
self.metrics = {}
|
|
120
113
|
self.labels = {}
|
|
121
114
|
self.model = None
|
|
@@ -125,6 +118,7 @@ class V2ModelServer(StepToDict):
|
|
|
125
118
|
self._versioned_model_name = None
|
|
126
119
|
self.model_endpoint_uid = None
|
|
127
120
|
self.shard_by_endpoint = shard_by_endpoint
|
|
121
|
+
self._model_logger = None
|
|
128
122
|
|
|
129
123
|
def _load_and_update_state(self):
|
|
130
124
|
try:
|
|
@@ -157,6 +151,11 @@ class V2ModelServer(StepToDict):
|
|
|
157
151
|
self.model_endpoint_uid = _init_endpoint_record(
|
|
158
152
|
graph_server=server, model=self
|
|
159
153
|
)
|
|
154
|
+
self._model_logger = (
|
|
155
|
+
_ModelLogPusher(self, self.context)
|
|
156
|
+
if self.context and self.context.stream.enabled
|
|
157
|
+
else None
|
|
158
|
+
)
|
|
160
159
|
|
|
161
160
|
def get_param(self, key: str, default=None):
|
|
162
161
|
"""get param by key (specified in the model or the function)"""
|
|
@@ -198,13 +197,15 @@ class V2ModelServer(StepToDict):
|
|
|
198
197
|
extra dataitems dictionary
|
|
199
198
|
|
|
200
199
|
"""
|
|
201
|
-
|
|
202
|
-
self.
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
200
|
+
if self.model_path:
|
|
201
|
+
model_file, self.model_spec, extra_dataitems = mlrun.artifacts.get_model(
|
|
202
|
+
self.model_path, suffix
|
|
203
|
+
)
|
|
204
|
+
if self.model_spec and self.model_spec.parameters:
|
|
205
|
+
for key, value in self.model_spec.parameters.items():
|
|
206
|
+
self._params[key] = value
|
|
207
|
+
return model_file, extra_dataitems
|
|
208
|
+
return None, None
|
|
208
209
|
|
|
209
210
|
def load(self):
|
|
210
211
|
"""model loading function, see also .get_model() method"""
|
|
@@ -474,7 +475,7 @@ class V2ModelServer(StepToDict):
|
|
|
474
475
|
|
|
475
476
|
|
|
476
477
|
class _ModelLogPusher:
|
|
477
|
-
def __init__(self, model, context, output_stream=None):
|
|
478
|
+
def __init__(self, model: V2ModelServer, context, output_stream=None):
|
|
478
479
|
self.model = model
|
|
479
480
|
self.verbose = context.verbose
|
|
480
481
|
self.hostname = context.stream.hostname
|
|
@@ -496,6 +497,7 @@ class _ModelLogPusher:
|
|
|
496
497
|
"version": self.model.version,
|
|
497
498
|
"host": self.hostname,
|
|
498
499
|
"function_uri": self.function_uri,
|
|
500
|
+
"endpoint_id": self.model.model_endpoint_uid,
|
|
499
501
|
}
|
|
500
502
|
if getattr(self.model, "labels", None):
|
|
501
503
|
base_data["labels"] = self.model.labels
|
|
@@ -567,26 +569,26 @@ def _init_endpoint_record(
|
|
|
567
569
|
"""
|
|
568
570
|
|
|
569
571
|
logger.info("Initializing endpoint records")
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
versioned_model=model.versioned_model_name,
|
|
585
|
-
).uid
|
|
586
|
-
|
|
572
|
+
if not model.model_spec:
|
|
573
|
+
model.get_model()
|
|
574
|
+
if model.model_spec:
|
|
575
|
+
model_name = model.model_spec.metadata.key
|
|
576
|
+
model_db_key = model.model_spec.spec.db_key
|
|
577
|
+
model_uid = model.model_spec.metadata.uid
|
|
578
|
+
model_tag = model.model_spec.tag
|
|
579
|
+
model_labels = model.model_spec.labels # todo : check if we still need this
|
|
580
|
+
else:
|
|
581
|
+
model_name = None
|
|
582
|
+
model_db_key = None
|
|
583
|
+
model_uid = None
|
|
584
|
+
model_tag = None
|
|
585
|
+
model_labels = {}
|
|
587
586
|
try:
|
|
588
587
|
model_ep = mlrun.get_run_db().get_model_endpoint(
|
|
589
|
-
project=project,
|
|
588
|
+
project=graph_server.project,
|
|
589
|
+
name=model.name,
|
|
590
|
+
function_name=graph_server.function_name,
|
|
591
|
+
function_tag=graph_server.function_tag or "latest",
|
|
590
592
|
)
|
|
591
593
|
except mlrun.errors.MLRunNotFoundError:
|
|
592
594
|
model_ep = None
|
|
@@ -596,62 +598,93 @@ def _init_endpoint_record(
|
|
|
596
598
|
)
|
|
597
599
|
return
|
|
598
600
|
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
601
|
+
function = mlrun.get_run_db().get_function(
|
|
602
|
+
name=graph_server.function_name,
|
|
603
|
+
project=graph_server.project,
|
|
604
|
+
tag=graph_server.function_tag or "latest",
|
|
605
|
+
)
|
|
606
|
+
function_uid = function.get("metadata", {}).get("uid")
|
|
607
|
+
if not model_ep and model.context.server.track_models:
|
|
608
|
+
logger.info(
|
|
609
|
+
"Creating a new model endpoint record",
|
|
610
|
+
name=model.name,
|
|
611
|
+
project=graph_server.project,
|
|
612
|
+
function_name=graph_server.function_name,
|
|
613
|
+
function_tag=graph_server.function_tag or "latest",
|
|
614
|
+
function_uid=function_uid,
|
|
615
|
+
model_name=model_name,
|
|
616
|
+
model_tag=model_tag,
|
|
617
|
+
model_db_key=model_db_key,
|
|
618
|
+
model_uid=model_uid,
|
|
619
|
+
model_class=model.__class__.__name__,
|
|
620
|
+
)
|
|
621
|
+
model_ep = mlrun.common.schemas.ModelEndpoint(
|
|
602
622
|
metadata=mlrun.common.schemas.ModelEndpointMetadata(
|
|
603
|
-
project=project,
|
|
623
|
+
project=graph_server.project,
|
|
624
|
+
labels=model_labels,
|
|
625
|
+
name=model.name,
|
|
626
|
+
endpoint_type=mlrun.common.schemas.model_monitoring.EndpointType.NODE_EP,
|
|
604
627
|
),
|
|
605
628
|
spec=mlrun.common.schemas.ModelEndpointSpec(
|
|
606
|
-
|
|
607
|
-
|
|
629
|
+
function_name=graph_server.function_name,
|
|
630
|
+
function_uid=function_uid,
|
|
631
|
+
function_tag=graph_server.function_tag or "latest",
|
|
632
|
+
model_name=model_name,
|
|
633
|
+
model_db_key=model_db_key,
|
|
634
|
+
model_uid=model_uid,
|
|
608
635
|
model_class=model.__class__.__name__,
|
|
609
|
-
|
|
610
|
-
stream_path=model.context.stream.stream_uri,
|
|
611
|
-
active=True,
|
|
612
|
-
monitoring_mode=mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled,
|
|
636
|
+
model_tag=model_tag,
|
|
613
637
|
),
|
|
614
638
|
status=mlrun.common.schemas.ModelEndpointStatus(
|
|
615
|
-
|
|
639
|
+
monitoring_mode=mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled
|
|
640
|
+
if model.context.server.track_models
|
|
641
|
+
else mlrun.common.schemas.model_monitoring.ModelMonitoringMode.disabled,
|
|
616
642
|
),
|
|
617
643
|
)
|
|
618
|
-
|
|
619
644
|
db = mlrun.get_run_db()
|
|
620
|
-
db.create_model_endpoint(
|
|
621
|
-
project=project,
|
|
622
|
-
endpoint_id=uid,
|
|
623
|
-
model_endpoint=model_endpoint.dict(),
|
|
624
|
-
)
|
|
645
|
+
model_ep = db.create_model_endpoint(model_endpoint=model_ep)
|
|
625
646
|
|
|
626
647
|
elif model_ep:
|
|
627
648
|
attributes = {}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
649
|
+
if function_uid != model_ep.spec.function_uid:
|
|
650
|
+
attributes[ModelEndpointSchema.FUNCTION_UID] = function_uid
|
|
651
|
+
if model_name != model_ep.spec.model_name:
|
|
652
|
+
attributes[ModelEndpointSchema.MODEL_NAME] = model_name
|
|
653
|
+
if model_uid != model_ep.spec.model_uid:
|
|
654
|
+
attributes[ModelEndpointSchema.MODEL_UID] = model_uid
|
|
655
|
+
if model_tag != model_ep.spec.model_tag:
|
|
656
|
+
attributes[ModelEndpointSchema.MODEL_TAG] = model_tag
|
|
657
|
+
if model_db_key != model_ep.spec.model_db_key:
|
|
658
|
+
attributes[ModelEndpointSchema.MODEL_DB_KEY] = model_db_key
|
|
659
|
+
if model_labels != model_ep.metadata.labels:
|
|
660
|
+
attributes[ModelEndpointSchema.LABELS] = model_labels
|
|
661
|
+
if model.__class__.__name__ != model_ep.spec.model_class:
|
|
662
|
+
attributes[ModelEndpointSchema.MODEL_CLASS] = model.__class__.__name__
|
|
635
663
|
if (
|
|
636
|
-
model_ep.
|
|
664
|
+
model_ep.status.monitoring_mode
|
|
637
665
|
== mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled
|
|
638
666
|
) != model.context.server.track_models:
|
|
639
|
-
attributes[
|
|
667
|
+
attributes[ModelEndpointSchema.MONITORING_MODE] = (
|
|
640
668
|
mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled
|
|
641
669
|
if model.context.server.track_models
|
|
642
670
|
else mlrun.common.schemas.model_monitoring.ModelMonitoringMode.disabled
|
|
643
671
|
)
|
|
644
672
|
if attributes:
|
|
645
|
-
db = mlrun.get_run_db()
|
|
646
|
-
db.patch_model_endpoint(
|
|
647
|
-
project=project,
|
|
648
|
-
endpoint_id=uid,
|
|
649
|
-
attributes=attributes,
|
|
650
|
-
)
|
|
651
673
|
logger.info(
|
|
652
674
|
"Updating model endpoint attributes",
|
|
653
675
|
attributes=attributes,
|
|
654
|
-
|
|
676
|
+
project=model_ep.metadata.project,
|
|
677
|
+
name=model_ep.metadata.name,
|
|
678
|
+
function_name=model_ep.spec.function_name,
|
|
655
679
|
)
|
|
680
|
+
db = mlrun.get_run_db()
|
|
681
|
+
model_ep = db.patch_model_endpoint(
|
|
682
|
+
project=model_ep.metadata.project,
|
|
683
|
+
name=model_ep.metadata.name,
|
|
684
|
+
endpoint_id=model_ep.metadata.uid,
|
|
685
|
+
attributes=attributes,
|
|
686
|
+
)
|
|
687
|
+
else:
|
|
688
|
+
return None
|
|
656
689
|
|
|
657
|
-
return uid
|
|
690
|
+
return model_ep.metadata.uid
|
mlrun/track/__init__.py
CHANGED
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
from mlrun.track.tracker import Tracker
|
|
16
16
|
from mlrun.track.tracker_manager import TrackerManager
|
mlrun/track/tracker.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
from abc import ABC, abstractmethod
|
|
16
|
-
from typing import Any, Union
|
|
16
|
+
from typing import Any, Optional, Union
|
|
17
17
|
|
|
18
18
|
from mlrun.artifacts import Artifact, ModelArtifact
|
|
19
19
|
from mlrun.execution import MLClientCtx
|
|
@@ -63,7 +63,7 @@ class Tracker(ABC):
|
|
|
63
63
|
project: MlrunProject,
|
|
64
64
|
reference_id: Any,
|
|
65
65
|
function_name: str,
|
|
66
|
-
handler: str = None,
|
|
66
|
+
handler: Optional[str] = None,
|
|
67
67
|
**kwargs,
|
|
68
68
|
) -> RunObject:
|
|
69
69
|
"""
|