mlrun 1.6.4rc2__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 +26 -112
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +144 -0
- mlrun/api/schemas/__init__.py +5 -4
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +46 -257
- mlrun/artifacts/dataset.py +11 -192
- mlrun/artifacts/manager.py +47 -48
- mlrun/artifacts/model.py +31 -159
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +69 -0
- mlrun/common/db/sql_session.py +2 -3
- mlrun/common/formatters/__init__.py +19 -0
- mlrun/common/formatters/artifact.py +21 -0
- 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/common/helpers.py +1 -2
- mlrun/common/model_monitoring/helpers.py +9 -5
- mlrun/{runtimes → common/runtimes}/constants.py +37 -9
- mlrun/common/schemas/__init__.py +24 -4
- mlrun/common/schemas/alert.py +203 -0
- mlrun/common/schemas/api_gateway.py +148 -0
- mlrun/common/schemas/artifact.py +18 -8
- mlrun/common/schemas/auth.py +11 -5
- mlrun/common/schemas/background_task.py +1 -1
- mlrun/common/schemas/client_spec.py +4 -1
- mlrun/common/schemas/feature_store.py +16 -16
- mlrun/common/schemas/frontend_spec.py +8 -7
- mlrun/common/schemas/function.py +5 -1
- mlrun/common/schemas/hub.py +11 -18
- mlrun/common/schemas/memory_reports.py +2 -2
- mlrun/common/schemas/model_monitoring/__init__.py +18 -3
- mlrun/common/schemas/model_monitoring/constants.py +83 -26
- mlrun/common/schemas/model_monitoring/grafana.py +13 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +99 -16
- mlrun/common/schemas/notification.py +4 -4
- mlrun/common/schemas/object.py +2 -2
- mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
- mlrun/common/schemas/pipeline.py +1 -10
- mlrun/common/schemas/project.py +24 -23
- mlrun/common/schemas/runtime_resource.py +8 -12
- mlrun/common/schemas/schedule.py +3 -3
- mlrun/common/schemas/tag.py +1 -2
- mlrun/common/schemas/workflow.py +2 -2
- mlrun/common/types.py +7 -1
- mlrun/config.py +54 -17
- mlrun/data_types/to_pandas.py +10 -12
- mlrun/datastore/__init__.py +5 -8
- mlrun/datastore/alibaba_oss.py +130 -0
- mlrun/datastore/azure_blob.py +17 -5
- mlrun/datastore/base.py +62 -39
- mlrun/datastore/datastore.py +28 -9
- mlrun/datastore/datastore_profile.py +146 -20
- mlrun/datastore/filestore.py +0 -1
- mlrun/datastore/google_cloud_storage.py +6 -2
- mlrun/datastore/hdfs.py +56 -0
- mlrun/datastore/inmem.py +2 -2
- mlrun/datastore/redis.py +6 -2
- mlrun/datastore/s3.py +9 -0
- mlrun/datastore/snowflake_utils.py +43 -0
- mlrun/datastore/sources.py +201 -96
- mlrun/datastore/spark_utils.py +1 -2
- mlrun/datastore/store_resources.py +7 -7
- mlrun/datastore/targets.py +358 -104
- mlrun/datastore/utils.py +72 -58
- mlrun/datastore/v3io.py +5 -1
- mlrun/db/base.py +185 -35
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +614 -179
- mlrun/db/nopdb.py +210 -26
- mlrun/errors.py +12 -1
- mlrun/execution.py +41 -24
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +40 -72
- mlrun/feature_store/common.py +1 -1
- mlrun/feature_store/feature_set.py +76 -55
- mlrun/feature_store/feature_vector.py +28 -30
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +16 -11
- mlrun/feature_store/retrieval/conversion.py +11 -13
- 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 +37 -34
- mlrun/features.py +9 -20
- mlrun/frameworks/_common/artifacts_library.py +9 -9
- mlrun/frameworks/_common/mlrun_interface.py +5 -5
- mlrun/frameworks/_common/model_handler.py +48 -48
- mlrun/frameworks/_common/plan.py +2 -3
- mlrun/frameworks/_common/producer.py +3 -4
- mlrun/frameworks/_common/utils.py +5 -5
- mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
- mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
- mlrun/frameworks/_ml_common/model_handler.py +24 -24
- mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
- mlrun/frameworks/_ml_common/plan.py +1 -1
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
- mlrun/frameworks/_ml_common/utils.py +4 -4
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
- mlrun/frameworks/huggingface/model_server.py +4 -4
- mlrun/frameworks/lgbm/__init__.py +33 -33
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
- mlrun/frameworks/lgbm/model_handler.py +10 -10
- mlrun/frameworks/lgbm/model_server.py +6 -6
- mlrun/frameworks/lgbm/utils.py +5 -5
- mlrun/frameworks/onnx/dataset.py +8 -8
- mlrun/frameworks/onnx/mlrun_interface.py +3 -3
- mlrun/frameworks/onnx/model_handler.py +6 -6
- mlrun/frameworks/onnx/model_server.py +7 -7
- mlrun/frameworks/parallel_coordinates.py +4 -3
- mlrun/frameworks/pytorch/__init__.py +18 -18
- mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
- mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
- mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
- mlrun/frameworks/pytorch/model_handler.py +17 -17
- mlrun/frameworks/pytorch/model_server.py +7 -7
- mlrun/frameworks/sklearn/__init__.py +13 -13
- mlrun/frameworks/sklearn/estimator.py +4 -4
- mlrun/frameworks/sklearn/metrics_library.py +14 -14
- mlrun/frameworks/sklearn/mlrun_interface.py +3 -6
- mlrun/frameworks/sklearn/model_handler.py +2 -2
- mlrun/frameworks/tf_keras/__init__.py +10 -7
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
- mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
- mlrun/frameworks/tf_keras/model_handler.py +14 -14
- mlrun/frameworks/tf_keras/model_server.py +6 -6
- mlrun/frameworks/xgboost/__init__.py +13 -13
- mlrun/frameworks/xgboost/model_handler.py +6 -6
- mlrun/k8s_utils.py +14 -16
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +16 -15
- mlrun/launcher/client.py +8 -6
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +17 -11
- mlrun/launcher/remote.py +16 -10
- mlrun/lists.py +7 -6
- mlrun/model.py +238 -73
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +138 -315
- mlrun/model_monitoring/application.py +5 -296
- mlrun/model_monitoring/applications/__init__.py +24 -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 +349 -0
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +104 -84
- mlrun/model_monitoring/controller_handler.py +13 -5
- 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} +64 -40
- 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} +310 -165
- 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 +134 -106
- mlrun/model_monitoring/helpers.py +127 -28
- mlrun/model_monitoring/metrics/__init__.py +13 -0
- mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/prometheus.py +1 -4
- mlrun/model_monitoring/stream_processing.py +62 -231
- mlrun/model_monitoring/tracking_policy.py +9 -2
- mlrun/model_monitoring/writer.py +152 -124
- mlrun/package/__init__.py +6 -6
- mlrun/package/context_handler.py +5 -5
- mlrun/package/packager.py +7 -7
- mlrun/package/packagers/default_packager.py +6 -6
- mlrun/package/packagers/numpy_packagers.py +15 -15
- mlrun/package/packagers/pandas_packagers.py +5 -5
- mlrun/package/packagers/python_standard_library_packagers.py +10 -10
- mlrun/package/packagers_manager.py +19 -23
- mlrun/package/utils/_formatter.py +6 -6
- mlrun/package/utils/_pickler.py +2 -2
- mlrun/package/utils/_supported_format.py +4 -4
- mlrun/package/utils/log_hint_utils.py +2 -2
- mlrun/package/utils/type_hint_utils.py +4 -9
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +24 -203
- mlrun/projects/operations.py +35 -21
- mlrun/projects/pipelines.py +68 -99
- mlrun/projects/project.py +830 -266
- mlrun/render.py +3 -11
- mlrun/run.py +162 -166
- mlrun/runtimes/__init__.py +62 -7
- mlrun/runtimes/base.py +39 -32
- mlrun/runtimes/daskjob.py +8 -8
- mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +7 -7
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +0 -28
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/kubejob.py +28 -122
- mlrun/runtimes/local.py +6 -3
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +9 -10
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
- 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/{function.py → nuclio/function.py} +112 -73
- mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
- mlrun/runtimes/{serving.py → nuclio/serving.py} +45 -51
- mlrun/runtimes/pod.py +286 -88
- mlrun/runtimes/remotesparkjob.py +2 -2
- mlrun/runtimes/sparkjob/spark3job.py +51 -34
- mlrun/runtimes/utils.py +7 -75
- mlrun/secrets.py +9 -5
- mlrun/serving/remote.py +2 -7
- mlrun/serving/routers.py +13 -10
- mlrun/serving/server.py +22 -26
- mlrun/serving/states.py +99 -25
- mlrun/serving/utils.py +3 -3
- mlrun/serving/v1_serving.py +6 -7
- mlrun/serving/v2_serving.py +59 -20
- mlrun/track/tracker.py +2 -1
- mlrun/track/tracker_manager.py +3 -3
- mlrun/track/trackers/mlflow_tracker.py +1 -2
- mlrun/utils/async_http.py +5 -7
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +1 -2
- mlrun/utils/condition_evaluator.py +3 -3
- mlrun/utils/db.py +3 -3
- mlrun/utils/helpers.py +183 -197
- mlrun/utils/http.py +2 -5
- mlrun/utils/logger.py +76 -14
- mlrun/utils/notifications/notification/__init__.py +17 -12
- mlrun/utils/notifications/notification/base.py +14 -2
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +3 -1
- mlrun/utils/notifications/notification/ipython.py +3 -1
- mlrun/utils/notifications/notification/slack.py +101 -21
- mlrun/utils/notifications/notification/webhook.py +11 -1
- mlrun/utils/notifications/notification_pusher.py +155 -30
- mlrun/utils/retryer.py +208 -0
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +2 -4
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +2 -6
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +31 -19
- mlrun-1.7.0rc20.dist-info/RECORD +353 -0
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/batch.py +0 -1095
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
- mlrun/platforms/other.py +0 -306
- mlrun-1.6.4rc2.dist-info/RECORD +0 -314
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
mlrun/model.py
CHANGED
|
@@ -22,18 +22,18 @@ from collections import OrderedDict
|
|
|
22
22
|
from copy import deepcopy
|
|
23
23
|
from datetime import datetime
|
|
24
24
|
from os import environ
|
|
25
|
-
from typing import Any,
|
|
25
|
+
from typing import Any, Optional, Union
|
|
26
26
|
|
|
27
27
|
import pydantic.error_wrappers
|
|
28
28
|
|
|
29
29
|
import mlrun
|
|
30
|
+
import mlrun.common.constants as mlrun_constants
|
|
30
31
|
import mlrun.common.schemas.notification
|
|
31
32
|
|
|
32
33
|
from .utils import (
|
|
33
34
|
dict_to_json,
|
|
34
35
|
dict_to_yaml,
|
|
35
36
|
get_artifact_target,
|
|
36
|
-
is_legacy_artifact,
|
|
37
37
|
logger,
|
|
38
38
|
template_artifact_path,
|
|
39
39
|
)
|
|
@@ -44,6 +44,15 @@ RUN_ID_PLACE_HOLDER = "{run_id}" # IMPORTANT: shouldn't be changed.
|
|
|
44
44
|
|
|
45
45
|
class ModelObj:
|
|
46
46
|
_dict_fields = []
|
|
47
|
+
# Bellow attributes are used in to_dict method
|
|
48
|
+
# Fields to strip from the object by default if strip=True
|
|
49
|
+
_default_fields_to_strip = []
|
|
50
|
+
# Fields that will be serialized by the object's _serialize_field method
|
|
51
|
+
_fields_to_serialize = []
|
|
52
|
+
# Fields that will be enriched by the object's _enrich_field method
|
|
53
|
+
_fields_to_enrich = []
|
|
54
|
+
# Fields that will be ignored by the object's _is_valid_field_value_for_serialization method
|
|
55
|
+
_fields_to_skip_validation = []
|
|
47
56
|
|
|
48
57
|
@staticmethod
|
|
49
58
|
def _verify_list(param, name):
|
|
@@ -63,26 +72,145 @@ class ModelObj:
|
|
|
63
72
|
return param
|
|
64
73
|
|
|
65
74
|
@mlrun.utils.filter_warnings("ignore", FutureWarning)
|
|
66
|
-
def to_dict(
|
|
67
|
-
|
|
75
|
+
def to_dict(
|
|
76
|
+
self, fields: list = None, exclude: list = None, strip: bool = False
|
|
77
|
+
) -> dict:
|
|
78
|
+
"""
|
|
79
|
+
Convert the object to a dict
|
|
80
|
+
|
|
81
|
+
:param fields: A list of fields to include in the dictionary. If not provided, the default value is taken
|
|
82
|
+
from `self._dict_fields` or from the object __init__ params.
|
|
83
|
+
:param exclude: A list of fields to exclude from the dictionary.
|
|
84
|
+
:param strip: If True, the object's `_default_fields_to_strip` attribute is appended to the exclude list.
|
|
85
|
+
Strip purpose is to remove fields that are context / environment specific and not required for actually
|
|
86
|
+
define the object.
|
|
68
87
|
|
|
69
|
-
:
|
|
70
|
-
:param exclude: list of fields to exclude from the dict
|
|
88
|
+
:return: A dictionary representation of the object.
|
|
71
89
|
"""
|
|
72
90
|
struct = {}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
|
|
92
|
+
fields = self._resolve_initial_to_dict_fields(fields)
|
|
93
|
+
fields_to_exclude = exclude or []
|
|
94
|
+
if strip:
|
|
95
|
+
fields_to_exclude += self._default_fields_to_strip
|
|
96
|
+
|
|
97
|
+
# fields_to_save is built from the fields list minus the fields to exclude minus the fields that requires
|
|
98
|
+
# serialization and enrichment (because they will be added later to the struct)
|
|
99
|
+
fields_to_save = (
|
|
100
|
+
set(fields)
|
|
101
|
+
- set(fields_to_exclude)
|
|
102
|
+
- set(self._fields_to_serialize)
|
|
103
|
+
- set(self._fields_to_enrich)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Iterating over the fields to save and adding them to the struct
|
|
107
|
+
for field_name in fields_to_save:
|
|
108
|
+
field_value = getattr(self, field_name, None)
|
|
109
|
+
if self._is_valid_field_value_for_serialization(
|
|
110
|
+
field_name, field_value, strip
|
|
111
|
+
):
|
|
112
|
+
# If the field value has attribute to_dict, we call it.
|
|
113
|
+
# If one of the attributes is a third party object that has to_dict method (such as k8s objects), then
|
|
114
|
+
# add it to the object's _fields_to_serialize attribute and handle it in the _serialize_field method.
|
|
115
|
+
if hasattr(field_value, "to_dict"):
|
|
116
|
+
field_value = field_value.to_dict(strip=strip)
|
|
117
|
+
if self._is_valid_field_value_for_serialization(
|
|
118
|
+
field_name, field_value, strip
|
|
119
|
+
):
|
|
120
|
+
struct[field_name] = field_value
|
|
121
|
+
else:
|
|
122
|
+
struct[field_name] = field_value
|
|
123
|
+
|
|
124
|
+
# Subtracting the fields_to_exclude from the fields_to_serialize because if we want to exclude a field there
|
|
125
|
+
# is no need to serialize it.
|
|
126
|
+
fields_to_serialize = list(
|
|
127
|
+
set(self._fields_to_serialize) - set(fields_to_exclude)
|
|
128
|
+
)
|
|
129
|
+
self._resolve_field_value_by_method(
|
|
130
|
+
struct, self._serialize_field, fields_to_serialize, strip
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Subtracting the fields_to_exclude from the fields_to_enrich because if we want to exclude a field there
|
|
134
|
+
# is no need to enrich it.
|
|
135
|
+
fields_to_enrich = list(set(self._fields_to_enrich) - set(fields_to_exclude))
|
|
136
|
+
self._resolve_field_value_by_method(
|
|
137
|
+
struct, self._enrich_field, fields_to_enrich, strip
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
self._apply_enrichment_before_to_dict_completion(struct, strip=strip)
|
|
141
|
+
return struct
|
|
142
|
+
|
|
143
|
+
def _resolve_initial_to_dict_fields(self, fields: list = None) -> list:
|
|
144
|
+
"""
|
|
145
|
+
Resolve fields to be used in to_dict method.
|
|
146
|
+
If fields is None, use `_dict_fields` attribute of the object.
|
|
147
|
+
If fields is None and `_dict_fields` is empty, use the object's __init__ parameters.
|
|
148
|
+
:param fields: List of fields to iterate over.
|
|
149
|
+
|
|
150
|
+
:return: List of fields to iterate over.
|
|
151
|
+
"""
|
|
152
|
+
return (
|
|
153
|
+
fields
|
|
154
|
+
or self._dict_fields
|
|
155
|
+
or list(inspect.signature(self.__init__).parameters.keys())
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
def _is_valid_field_value_for_serialization(
|
|
159
|
+
self, field_name: str, field_value: str, strip: bool = False
|
|
160
|
+
) -> bool:
|
|
161
|
+
"""
|
|
162
|
+
Check if the field value is valid for serialization.
|
|
163
|
+
If field name is in `_fields_to_skip_validation` attribute, skip validation and return True.
|
|
164
|
+
If strip is False skip validation and return True.
|
|
165
|
+
If field value is None or empty dict/list, then no need to store it.
|
|
166
|
+
:param field_name: Field name.
|
|
167
|
+
:param field_value: Field value.
|
|
168
|
+
|
|
169
|
+
:return: True if the field value is valid for serialization, False otherwise.
|
|
170
|
+
"""
|
|
171
|
+
if field_name in self._fields_to_skip_validation:
|
|
172
|
+
return True
|
|
173
|
+
# TODO: remove when Runtime initialization will be refactored and enrichment will be moved to BE
|
|
174
|
+
# if not strip:
|
|
175
|
+
# return True
|
|
176
|
+
|
|
177
|
+
return field_value is not None and not (
|
|
178
|
+
(isinstance(field_value, dict) or isinstance(field_value, list))
|
|
179
|
+
and not field_value
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def _resolve_field_value_by_method(
|
|
183
|
+
self,
|
|
184
|
+
struct: dict,
|
|
185
|
+
method: typing.Callable,
|
|
186
|
+
fields: typing.Union[list, set] = None,
|
|
187
|
+
strip: bool = False,
|
|
188
|
+
) -> dict:
|
|
189
|
+
for field_name in fields:
|
|
190
|
+
field_value = method(struct=struct, field_name=field_name, strip=strip)
|
|
191
|
+
if self._is_valid_field_value_for_serialization(
|
|
192
|
+
field_name, field_value, strip
|
|
193
|
+
):
|
|
194
|
+
struct[field_name] = field_value
|
|
195
|
+
return struct
|
|
196
|
+
|
|
197
|
+
def _serialize_field(
|
|
198
|
+
self, struct: dict, field_name: str = None, strip: bool = False
|
|
199
|
+
) -> typing.Any:
|
|
200
|
+
# We pull the field from self and not from struct because it was excluded from the struct when looping over
|
|
201
|
+
# the fields to save.
|
|
202
|
+
return getattr(self, field_name, None)
|
|
203
|
+
|
|
204
|
+
def _enrich_field(
|
|
205
|
+
self, struct: dict, field_name: str = None, strip: bool = False
|
|
206
|
+
) -> typing.Any:
|
|
207
|
+
# We first try to pull from struct because the field might have been already serialized and if not,
|
|
208
|
+
# we pull from self
|
|
209
|
+
return struct.get(field_name, None) or getattr(self, field_name, None)
|
|
210
|
+
|
|
211
|
+
def _apply_enrichment_before_to_dict_completion(
|
|
212
|
+
self, struct: dict, strip: bool = False
|
|
213
|
+
) -> dict:
|
|
86
214
|
return struct
|
|
87
215
|
|
|
88
216
|
@classmethod
|
|
@@ -111,19 +239,21 @@ class ModelObj:
|
|
|
111
239
|
|
|
112
240
|
return new_obj
|
|
113
241
|
|
|
114
|
-
def to_yaml(self, exclude=None) -> str:
|
|
242
|
+
def to_yaml(self, exclude=None, strip: bool = False) -> str:
|
|
115
243
|
"""convert the object to yaml
|
|
116
244
|
|
|
117
245
|
:param exclude: list of fields to exclude from the yaml
|
|
246
|
+
:param strip: if True, strip fields that are not required for actually define the object
|
|
118
247
|
"""
|
|
119
|
-
return dict_to_yaml(self.to_dict(exclude=exclude))
|
|
248
|
+
return dict_to_yaml(self.to_dict(exclude=exclude, strip=strip))
|
|
120
249
|
|
|
121
|
-
def to_json(self, exclude=None):
|
|
250
|
+
def to_json(self, exclude=None, strip: bool = False):
|
|
122
251
|
"""convert the object to json
|
|
123
252
|
|
|
124
253
|
:param exclude: list of fields to exclude from the json
|
|
254
|
+
:param strip: if True, strip fields that are not required for actually define the object
|
|
125
255
|
"""
|
|
126
|
-
return dict_to_json(self.to_dict(exclude=exclude))
|
|
256
|
+
return dict_to_json(self.to_dict(exclude=exclude, strip=strip))
|
|
127
257
|
|
|
128
258
|
def to_str(self):
|
|
129
259
|
"""convert the object to string (with dict layout)"""
|
|
@@ -175,8 +305,8 @@ class ObjectDict:
|
|
|
175
305
|
self._children[key] = child
|
|
176
306
|
return child
|
|
177
307
|
|
|
178
|
-
def to_dict(self):
|
|
179
|
-
return {k: v.to_dict() for k, v in self._children.items()}
|
|
308
|
+
def to_dict(self, strip: bool = False):
|
|
309
|
+
return {k: v.to_dict(strip=strip) for k, v in self._children.items()}
|
|
180
310
|
|
|
181
311
|
@classmethod
|
|
182
312
|
def from_dict(cls, classes_map: dict, children=None, default_kind=""):
|
|
@@ -258,9 +388,9 @@ class ObjectList:
|
|
|
258
388
|
def __delitem__(self, key):
|
|
259
389
|
del self._children[key]
|
|
260
390
|
|
|
261
|
-
def to_dict(self):
|
|
391
|
+
def to_dict(self, strip: bool = False):
|
|
262
392
|
# method used by ModelObj class to serialize the object to nested dict
|
|
263
|
-
return [t.to_dict() for t in self._children.values()]
|
|
393
|
+
return [t.to_dict(strip=strip) for t in self._children.values()]
|
|
264
394
|
|
|
265
395
|
@classmethod
|
|
266
396
|
def from_list(cls, child_class, children=None):
|
|
@@ -305,6 +435,18 @@ class Credentials(ModelObj):
|
|
|
305
435
|
|
|
306
436
|
|
|
307
437
|
class BaseMetadata(ModelObj):
|
|
438
|
+
_default_fields_to_strip = ModelObj._default_fields_to_strip + [
|
|
439
|
+
"hash",
|
|
440
|
+
# Below are environment specific fields, no need to keep when stripping
|
|
441
|
+
"namespace",
|
|
442
|
+
"project",
|
|
443
|
+
"labels",
|
|
444
|
+
"annotations",
|
|
445
|
+
"credentials",
|
|
446
|
+
# Below are state fields, no need to keep when stripping
|
|
447
|
+
"updated",
|
|
448
|
+
]
|
|
449
|
+
|
|
308
450
|
def __init__(
|
|
309
451
|
self,
|
|
310
452
|
name=None,
|
|
@@ -449,7 +591,7 @@ class ImageBuilder(ModelObj):
|
|
|
449
591
|
|
|
450
592
|
def with_commands(
|
|
451
593
|
self,
|
|
452
|
-
commands:
|
|
594
|
+
commands: list[str],
|
|
453
595
|
overwrite: bool = False,
|
|
454
596
|
):
|
|
455
597
|
"""add commands to build spec.
|
|
@@ -476,7 +618,7 @@ class ImageBuilder(ModelObj):
|
|
|
476
618
|
|
|
477
619
|
def with_requirements(
|
|
478
620
|
self,
|
|
479
|
-
requirements: Optional[
|
|
621
|
+
requirements: Optional[list[str]] = None,
|
|
480
622
|
requirements_file: str = "",
|
|
481
623
|
overwrite: bool = False,
|
|
482
624
|
):
|
|
@@ -509,7 +651,7 @@ class ImageBuilder(ModelObj):
|
|
|
509
651
|
|
|
510
652
|
# handle the requirements_file argument
|
|
511
653
|
if requirements_file:
|
|
512
|
-
with open(requirements_file
|
|
654
|
+
with open(requirements_file) as fp:
|
|
513
655
|
requirements_to_resolve.extend(fp.read().splitlines())
|
|
514
656
|
|
|
515
657
|
# handle the requirements argument
|
|
@@ -540,10 +682,14 @@ class Notification(ModelObj):
|
|
|
540
682
|
|
|
541
683
|
def __init__(
|
|
542
684
|
self,
|
|
543
|
-
kind=
|
|
685
|
+
kind: mlrun.common.schemas.notification.NotificationKind = (
|
|
686
|
+
mlrun.common.schemas.notification.NotificationKind.slack
|
|
687
|
+
),
|
|
544
688
|
name=None,
|
|
545
689
|
message=None,
|
|
546
|
-
severity=
|
|
690
|
+
severity: mlrun.common.schemas.notification.NotificationSeverity = (
|
|
691
|
+
mlrun.common.schemas.notification.NotificationSeverity.INFO
|
|
692
|
+
),
|
|
547
693
|
when=None,
|
|
548
694
|
condition=None,
|
|
549
695
|
secret_params=None,
|
|
@@ -552,12 +698,10 @@ class Notification(ModelObj):
|
|
|
552
698
|
sent_time=None,
|
|
553
699
|
reason=None,
|
|
554
700
|
):
|
|
555
|
-
self.kind = kind
|
|
701
|
+
self.kind = kind
|
|
556
702
|
self.name = name or ""
|
|
557
703
|
self.message = message or ""
|
|
558
|
-
self.severity =
|
|
559
|
-
severity or mlrun.common.schemas.notification.NotificationSeverity.INFO
|
|
560
|
-
)
|
|
704
|
+
self.severity = severity
|
|
561
705
|
self.when = when or ["completed"]
|
|
562
706
|
self.condition = condition or ""
|
|
563
707
|
self.secret_params = secret_params or {}
|
|
@@ -588,7 +732,7 @@ class Notification(ModelObj):
|
|
|
588
732
|
)
|
|
589
733
|
|
|
590
734
|
@staticmethod
|
|
591
|
-
def validate_notification_uniqueness(notifications:
|
|
735
|
+
def validate_notification_uniqueness(notifications: list["Notification"]):
|
|
592
736
|
"""Validate that all notifications in the list are unique by name"""
|
|
593
737
|
names = [notification.name for notification in notifications]
|
|
594
738
|
if len(names) != len(set(names)):
|
|
@@ -627,7 +771,10 @@ class RunMetadata(ModelObj):
|
|
|
627
771
|
def is_workflow_runner(self):
|
|
628
772
|
if not self.labels:
|
|
629
773
|
return False
|
|
630
|
-
return
|
|
774
|
+
return (
|
|
775
|
+
self.labels.get(mlrun_constants.MLRunInternalLabels.job_type, "")
|
|
776
|
+
== "workflow-runner"
|
|
777
|
+
)
|
|
631
778
|
|
|
632
779
|
|
|
633
780
|
class HyperParamStrategies:
|
|
@@ -697,6 +844,10 @@ class HyperParamOptions(ModelObj):
|
|
|
697
844
|
class RunSpec(ModelObj):
|
|
698
845
|
"""Run specification"""
|
|
699
846
|
|
|
847
|
+
_fields_to_serialize = ModelObj._fields_to_serialize + [
|
|
848
|
+
"handler",
|
|
849
|
+
]
|
|
850
|
+
|
|
700
851
|
def __init__(
|
|
701
852
|
self,
|
|
702
853
|
parameters=None,
|
|
@@ -757,18 +908,22 @@ class RunSpec(ModelObj):
|
|
|
757
908
|
self._notifications = notifications or []
|
|
758
909
|
self.state_thresholds = state_thresholds or {}
|
|
759
910
|
|
|
760
|
-
def
|
|
761
|
-
struct =
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
911
|
+
def _serialize_field(
|
|
912
|
+
self, struct: dict, field_name: str = None, strip: bool = False
|
|
913
|
+
) -> Optional[str]:
|
|
914
|
+
# We pull the field from self and not from struct because it was excluded from the struct
|
|
915
|
+
if field_name == "handler":
|
|
916
|
+
if self.handler and isinstance(self.handler, str):
|
|
917
|
+
return self.handler
|
|
918
|
+
return None
|
|
919
|
+
return super()._serialize_field(struct, field_name, strip)
|
|
765
920
|
|
|
766
921
|
def is_hyper_job(self):
|
|
767
922
|
param_file = self.param_file or self.hyper_param_options.param_file
|
|
768
923
|
return param_file or self.hyperparams
|
|
769
924
|
|
|
770
925
|
@property
|
|
771
|
-
def inputs(self) ->
|
|
926
|
+
def inputs(self) -> dict[str, str]:
|
|
772
927
|
"""
|
|
773
928
|
Get the inputs dictionary. A dictionary of parameter names as keys and paths as values.
|
|
774
929
|
|
|
@@ -777,7 +932,7 @@ class RunSpec(ModelObj):
|
|
|
777
932
|
return self._inputs
|
|
778
933
|
|
|
779
934
|
@inputs.setter
|
|
780
|
-
def inputs(self, inputs:
|
|
935
|
+
def inputs(self, inputs: dict[str, str]):
|
|
781
936
|
"""
|
|
782
937
|
Set the given inputs in the spec. Inputs can include a type hint string in their keys following a colon, meaning
|
|
783
938
|
following this structure: "<input key : type hint>".
|
|
@@ -786,7 +941,7 @@ class RunSpec(ModelObj):
|
|
|
786
941
|
|
|
787
942
|
>>> run_spec.inputs = {
|
|
788
943
|
... "my_input": "...",
|
|
789
|
-
... "my_hinted_input : pandas.DataFrame": "..."
|
|
944
|
+
... "my_hinted_input : pandas.DataFrame": "...",
|
|
790
945
|
... }
|
|
791
946
|
|
|
792
947
|
:param inputs: The inputs to set.
|
|
@@ -800,7 +955,7 @@ class RunSpec(ModelObj):
|
|
|
800
955
|
self._inputs = self._verify_dict(inputs, "inputs")
|
|
801
956
|
|
|
802
957
|
@property
|
|
803
|
-
def inputs_type_hints(self) ->
|
|
958
|
+
def inputs_type_hints(self) -> dict[str, str]:
|
|
804
959
|
"""
|
|
805
960
|
Get the input type hints. A dictionary of parameter names as keys and their type hints as values.
|
|
806
961
|
|
|
@@ -809,7 +964,7 @@ class RunSpec(ModelObj):
|
|
|
809
964
|
return self._inputs_type_hints
|
|
810
965
|
|
|
811
966
|
@inputs_type_hints.setter
|
|
812
|
-
def inputs_type_hints(self, inputs_type_hints:
|
|
967
|
+
def inputs_type_hints(self, inputs_type_hints: dict[str, str]):
|
|
813
968
|
"""
|
|
814
969
|
Set the inputs type hints to parse during a run.
|
|
815
970
|
|
|
@@ -830,7 +985,7 @@ class RunSpec(ModelObj):
|
|
|
830
985
|
return self._returns
|
|
831
986
|
|
|
832
987
|
@returns.setter
|
|
833
|
-
def returns(self, returns:
|
|
988
|
+
def returns(self, returns: list[Union[str, dict[str, str]]]):
|
|
834
989
|
"""
|
|
835
990
|
Set the returns list to log the returning values at the end of a run.
|
|
836
991
|
|
|
@@ -864,7 +1019,7 @@ class RunSpec(ModelObj):
|
|
|
864
1019
|
)
|
|
865
1020
|
|
|
866
1021
|
@property
|
|
867
|
-
def outputs(self) ->
|
|
1022
|
+
def outputs(self) -> list[str]:
|
|
868
1023
|
"""
|
|
869
1024
|
Get the expected outputs. The list is constructed from keys of both the `outputs` and `returns` properties.
|
|
870
1025
|
|
|
@@ -929,7 +1084,7 @@ class RunSpec(ModelObj):
|
|
|
929
1084
|
return self._state_thresholds
|
|
930
1085
|
|
|
931
1086
|
@state_thresholds.setter
|
|
932
|
-
def state_thresholds(self, state_thresholds:
|
|
1087
|
+
def state_thresholds(self, state_thresholds: dict[str, str]):
|
|
933
1088
|
"""
|
|
934
1089
|
Set the dictionary of k8s resource states to thresholds time strings.
|
|
935
1090
|
The state will be matched against the pod's status. The threshold should be a time string that conforms
|
|
@@ -981,8 +1136,8 @@ class RunSpec(ModelObj):
|
|
|
981
1136
|
|
|
982
1137
|
@staticmethod
|
|
983
1138
|
def join_outputs_and_returns(
|
|
984
|
-
outputs:
|
|
985
|
-
) ->
|
|
1139
|
+
outputs: list[str], returns: list[Union[str, dict[str, str]]]
|
|
1140
|
+
) -> list[str]:
|
|
986
1141
|
"""
|
|
987
1142
|
Get the outputs set in the spec. The outputs are constructed from both the 'outputs' and 'returns' properties
|
|
988
1143
|
that were set by the user.
|
|
@@ -1013,7 +1168,7 @@ class RunSpec(ModelObj):
|
|
|
1013
1168
|
return outputs
|
|
1014
1169
|
|
|
1015
1170
|
@staticmethod
|
|
1016
|
-
def _separate_type_hint_from_input_key(input_key: str) ->
|
|
1171
|
+
def _separate_type_hint_from_input_key(input_key: str) -> tuple[str, str]:
|
|
1017
1172
|
"""
|
|
1018
1173
|
An input key in the `inputs` dictionary parameter of a task (or `Runtime.run` method) or the docs setting of a
|
|
1019
1174
|
`Runtime` handler can be provided with a colon to specify its type hint in the following structure:
|
|
@@ -1057,7 +1212,7 @@ class RunStatus(ModelObj):
|
|
|
1057
1212
|
iterations=None,
|
|
1058
1213
|
ui_url=None,
|
|
1059
1214
|
reason: str = None,
|
|
1060
|
-
notifications:
|
|
1215
|
+
notifications: dict[str, Notification] = None,
|
|
1061
1216
|
artifact_uris: dict[str, str] = None,
|
|
1062
1217
|
):
|
|
1063
1218
|
self.state = state or "created"
|
|
@@ -1146,7 +1301,7 @@ class RunTemplate(ModelObj):
|
|
|
1146
1301
|
|
|
1147
1302
|
example::
|
|
1148
1303
|
|
|
1149
|
-
grid_params = {"p1": [2,4,1], "p2": [10,20]}
|
|
1304
|
+
grid_params = {"p1": [2, 4, 1], "p2": [10, 20]}
|
|
1150
1305
|
task = mlrun.new_task("grid-search")
|
|
1151
1306
|
task.with_hyper_params(grid_params, selector="max.accuracy")
|
|
1152
1307
|
"""
|
|
@@ -1288,11 +1443,14 @@ class RunObject(RunTemplate):
|
|
|
1288
1443
|
unknown_error = ""
|
|
1289
1444
|
if (
|
|
1290
1445
|
self.status.state
|
|
1291
|
-
in mlrun.runtimes.constants.RunStates.abortion_states()
|
|
1446
|
+
in mlrun.common.runtimes.constants.RunStates.abortion_states()
|
|
1292
1447
|
):
|
|
1293
1448
|
unknown_error = "Run was aborted"
|
|
1294
1449
|
|
|
1295
|
-
elif
|
|
1450
|
+
elif (
|
|
1451
|
+
self.status.state
|
|
1452
|
+
in mlrun.common.runtimes.constants.RunStates.error_states()
|
|
1453
|
+
):
|
|
1296
1454
|
unknown_error = "Unknown error"
|
|
1297
1455
|
|
|
1298
1456
|
return (
|
|
@@ -1318,7 +1476,7 @@ class RunObject(RunTemplate):
|
|
|
1318
1476
|
"""UI URL (for relevant runtimes)"""
|
|
1319
1477
|
self.refresh()
|
|
1320
1478
|
if not self._status.ui_url:
|
|
1321
|
-
print("UI currently not available (status={
|
|
1479
|
+
print(f"UI currently not available (status={self._status.state})")
|
|
1322
1480
|
return self._status.ui_url
|
|
1323
1481
|
|
|
1324
1482
|
@property
|
|
@@ -1330,7 +1488,7 @@ class RunObject(RunTemplate):
|
|
|
1330
1488
|
outputs = {k: v for k, v in self.status.results.items()}
|
|
1331
1489
|
if self.status.artifacts:
|
|
1332
1490
|
for a in self.status.artifacts:
|
|
1333
|
-
key = a["
|
|
1491
|
+
key = a["metadata"]["key"]
|
|
1334
1492
|
outputs[key] = get_artifact_target(a, self.metadata.project)
|
|
1335
1493
|
return outputs
|
|
1336
1494
|
|
|
@@ -1373,7 +1531,10 @@ class RunObject(RunTemplate):
|
|
|
1373
1531
|
|
|
1374
1532
|
def state(self):
|
|
1375
1533
|
"""current run state"""
|
|
1376
|
-
if
|
|
1534
|
+
if (
|
|
1535
|
+
self.status.state
|
|
1536
|
+
in mlrun.common.runtimes.constants.RunStates.terminal_states()
|
|
1537
|
+
):
|
|
1377
1538
|
return self.status.state
|
|
1378
1539
|
self.refresh()
|
|
1379
1540
|
return self.status.state or "unknown"
|
|
@@ -1437,7 +1598,7 @@ class RunObject(RunTemplate):
|
|
|
1437
1598
|
last_pull_log_time = None
|
|
1438
1599
|
logs_enabled = show_logs is not False
|
|
1439
1600
|
state = self.state()
|
|
1440
|
-
if state not in mlrun.runtimes.constants.RunStates.terminal_states():
|
|
1601
|
+
if state not in mlrun.common.runtimes.constants.RunStates.terminal_states():
|
|
1441
1602
|
logger.info(
|
|
1442
1603
|
f"run {self.metadata.name} is not completed yet, waiting for it to complete",
|
|
1443
1604
|
current_state=state,
|
|
@@ -1447,7 +1608,8 @@ class RunObject(RunTemplate):
|
|
|
1447
1608
|
if (
|
|
1448
1609
|
logs_enabled
|
|
1449
1610
|
and logs_interval
|
|
1450
|
-
and state
|
|
1611
|
+
and state
|
|
1612
|
+
not in mlrun.common.runtimes.constants.RunStates.terminal_states()
|
|
1451
1613
|
and (
|
|
1452
1614
|
last_pull_log_time is None
|
|
1453
1615
|
or (datetime.now() - last_pull_log_time).seconds > logs_interval
|
|
@@ -1456,7 +1618,7 @@ class RunObject(RunTemplate):
|
|
|
1456
1618
|
last_pull_log_time = datetime.now()
|
|
1457
1619
|
state, offset = self.logs(watch=False, offset=offset)
|
|
1458
1620
|
|
|
1459
|
-
if state in mlrun.runtimes.constants.RunStates.terminal_states():
|
|
1621
|
+
if state in mlrun.common.runtimes.constants.RunStates.terminal_states():
|
|
1460
1622
|
if logs_enabled and logs_interval:
|
|
1461
1623
|
self.logs(watch=False, offset=offset)
|
|
1462
1624
|
break
|
|
@@ -1468,7 +1630,10 @@ class RunObject(RunTemplate):
|
|
|
1468
1630
|
)
|
|
1469
1631
|
if logs_enabled and not logs_interval:
|
|
1470
1632
|
self.logs(watch=False)
|
|
1471
|
-
if
|
|
1633
|
+
if (
|
|
1634
|
+
raise_on_failure
|
|
1635
|
+
and state != mlrun.common.runtimes.constants.RunStates.completed
|
|
1636
|
+
):
|
|
1472
1637
|
raise mlrun.errors.MLRunRuntimeError(
|
|
1473
1638
|
f"Task {self.metadata.name} did not complete (state={state})"
|
|
1474
1639
|
)
|
|
@@ -1483,7 +1648,7 @@ class RunObject(RunTemplate):
|
|
|
1483
1648
|
return f"{project}@{uid}#{iteration}{tag}"
|
|
1484
1649
|
|
|
1485
1650
|
@staticmethod
|
|
1486
|
-
def parse_uri(uri: str) ->
|
|
1651
|
+
def parse_uri(uri: str) -> tuple[str, str, str, str]:
|
|
1487
1652
|
uri_pattern = (
|
|
1488
1653
|
r"^(?P<project>.*)@(?P<uid>.*)\#(?P<iteration>.*?)(:(?P<tag>.*))?$"
|
|
1489
1654
|
)
|
|
@@ -1704,7 +1869,7 @@ class DataSource(ModelObj):
|
|
|
1704
1869
|
self,
|
|
1705
1870
|
name: str = None,
|
|
1706
1871
|
path: str = None,
|
|
1707
|
-
attributes:
|
|
1872
|
+
attributes: dict[str, object] = None,
|
|
1708
1873
|
key_field: str = None,
|
|
1709
1874
|
time_field: str = None,
|
|
1710
1875
|
schedule: str = None,
|
|
@@ -1770,16 +1935,16 @@ class DataTargetBase(ModelObj):
|
|
|
1770
1935
|
kind: str = None,
|
|
1771
1936
|
name: str = "",
|
|
1772
1937
|
path=None,
|
|
1773
|
-
attributes:
|
|
1938
|
+
attributes: dict[str, str] = None,
|
|
1774
1939
|
after_step=None,
|
|
1775
1940
|
partitioned: bool = False,
|
|
1776
1941
|
key_bucketing_number: Optional[int] = None,
|
|
1777
|
-
partition_cols: Optional[
|
|
1942
|
+
partition_cols: Optional[list[str]] = None,
|
|
1778
1943
|
time_partitioning_granularity: Optional[str] = None,
|
|
1779
1944
|
max_events: Optional[int] = None,
|
|
1780
1945
|
flush_after_seconds: Optional[int] = None,
|
|
1781
|
-
storage_options:
|
|
1782
|
-
schema:
|
|
1946
|
+
storage_options: dict[str, str] = None,
|
|
1947
|
+
schema: dict[str, Any] = None,
|
|
1783
1948
|
credentials_prefix=None,
|
|
1784
1949
|
):
|
|
1785
1950
|
self.name = name
|
|
@@ -1866,8 +2031,8 @@ class VersionedObjMetadata(ModelObj):
|
|
|
1866
2031
|
tag: str = None,
|
|
1867
2032
|
uid: str = None,
|
|
1868
2033
|
project: str = None,
|
|
1869
|
-
labels:
|
|
1870
|
-
annotations:
|
|
2034
|
+
labels: dict[str, str] = None,
|
|
2035
|
+
annotations: dict[str, str] = None,
|
|
1871
2036
|
updated=None,
|
|
1872
2037
|
):
|
|
1873
2038
|
self.name = name
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
16
16
|
# for backwards compatibility
|
|
17
17
|
|
|
18
|
+
from .db import get_store_object, get_tsdb_connector
|
|
18
19
|
from .helpers import get_stream_path
|
|
19
20
|
from .model_endpoint import ModelEndpoint
|
|
20
|
-
from .stores import ModelEndpointStore, ModelEndpointStoreType, get_model_endpoint_store
|
|
21
21
|
from .tracking_policy import TrackingPolicy
|