mlrun 1.7.2rc3__py3-none-any.whl → 1.8.0rc2__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 +18 -18
- mlrun/__main__.py +3 -3
- mlrun/alerts/alert.py +19 -12
- mlrun/artifacts/__init__.py +0 -2
- mlrun/artifacts/base.py +34 -11
- mlrun/artifacts/dataset.py +16 -16
- mlrun/artifacts/manager.py +13 -13
- mlrun/artifacts/model.py +66 -53
- mlrun/common/constants.py +6 -0
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/feature_set.py +1 -0
- mlrun/common/formatters/function.py +1 -0
- mlrun/common/formatters/model_endpoint.py +30 -0
- mlrun/common/formatters/pipeline.py +1 -2
- mlrun/common/formatters/project.py +9 -0
- mlrun/common/model_monitoring/__init__.py +0 -3
- mlrun/common/model_monitoring/helpers.py +1 -1
- mlrun/common/runtimes/constants.py +1 -2
- mlrun/common/schemas/__init__.py +7 -2
- mlrun/common/schemas/alert.py +31 -18
- mlrun/common/schemas/api_gateway.py +3 -3
- mlrun/common/schemas/artifact.py +7 -13
- mlrun/common/schemas/auth.py +6 -4
- mlrun/common/schemas/background_task.py +7 -7
- mlrun/common/schemas/client_spec.py +2 -2
- mlrun/common/schemas/clusterization_spec.py +2 -2
- mlrun/common/schemas/common.py +53 -3
- 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 +8 -1
- mlrun/common/schemas/model_monitoring/constants.py +62 -12
- mlrun/common/schemas/model_monitoring/grafana.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +149 -0
- mlrun/common/schemas/model_monitoring/model_endpoints.py +22 -6
- mlrun/common/schemas/notification.py +18 -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 +22 -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 +65 -15
- mlrun/data_types/__init__.py +0 -2
- mlrun/data_types/data_types.py +0 -1
- mlrun/data_types/infer.py +3 -1
- mlrun/data_types/spark.py +4 -4
- mlrun/data_types/to_pandas.py +2 -11
- mlrun/datastore/__init__.py +0 -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 +20 -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 +51 -49
- mlrun/datastore/store_resources.py +0 -2
- mlrun/datastore/targets.py +22 -23
- mlrun/datastore/utils.py +2 -2
- mlrun/datastore/v3io.py +4 -1
- mlrun/datastore/wasbfs/fs.py +13 -12
- mlrun/db/base.py +170 -64
- mlrun/db/factory.py +3 -0
- mlrun/db/httpdb.py +986 -238
- mlrun/db/nopdb.py +155 -57
- mlrun/errors.py +2 -2
- mlrun/execution.py +55 -29
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +40 -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 +110 -46
- mlrun/model_monitoring/__init__.py +1 -2
- mlrun/model_monitoring/api.py +6 -6
- mlrun/model_monitoring/applications/_application_steps.py +13 -15
- mlrun/model_monitoring/applications/histogram_data_drift.py +41 -15
- mlrun/model_monitoring/applications/results.py +55 -3
- mlrun/model_monitoring/controller.py +185 -223
- mlrun/model_monitoring/db/_schedules.py +156 -0
- mlrun/model_monitoring/db/_stats.py +189 -0
- mlrun/model_monitoring/db/stores/__init__.py +1 -1
- mlrun/model_monitoring/db/stores/base/store.py +6 -65
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -25
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -97
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +2 -58
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -15
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +6 -257
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +9 -271
- mlrun/model_monitoring/db/tsdb/base.py +76 -24
- 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 +253 -28
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +35 -17
- mlrun/model_monitoring/helpers.py +91 -1
- mlrun/model_monitoring/model_endpoint.py +4 -2
- mlrun/model_monitoring/stream_processing.py +16 -13
- mlrun/model_monitoring/tracking_policy.py +10 -3
- mlrun/model_monitoring/writer.py +47 -26
- 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 +3 -16
- mlrun/platforms/iguazio.py +4 -1
- mlrun/projects/operations.py +27 -27
- mlrun/projects/pipelines.py +34 -35
- mlrun/projects/project.py +535 -182
- mlrun/run.py +13 -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 +13 -13
- mlrun/runtimes/nuclio/serving.py +9 -9
- 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 +27 -27
- mlrun/serving/server.py +1 -1
- mlrun/serving/states.py +76 -71
- mlrun/serving/utils.py +13 -2
- mlrun/serving/v1_serving.py +3 -2
- mlrun/serving/v2_serving.py +4 -4
- 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/helpers.py +70 -16
- 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 +149 -0
- mlrun/utils/notifications/notification/slack.py +6 -6
- mlrun/utils/notifications/notification/webhook.py +18 -22
- mlrun/utils/notifications/notification_pusher.py +43 -31
- mlrun/utils/regex.py +3 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc2.dist-info}/METADATA +18 -14
- mlrun-1.8.0rc2.dist-info/RECORD +358 -0
- {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc2.dist-info}/WHEEL +1 -1
- mlrun-1.7.2rc3.dist-info/RECORD +0 -351
- {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc2.dist-info}/LICENSE +0 -0
- {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc2.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.2rc3.dist-info → mlrun-1.8.0rc2.dist-info}/top_level.txt +0 -0
mlrun/common/schemas/function.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
#
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
|
|
19
19
|
import mlrun.common.types
|
|
20
20
|
|
|
@@ -90,42 +90,42 @@ class SecurityContextEnrichmentModes(mlrun.common.types.StrEnum):
|
|
|
90
90
|
disabled = "disabled"
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
class ImagePullSecret(pydantic.BaseModel):
|
|
93
|
+
class ImagePullSecret(pydantic.v1.BaseModel):
|
|
94
94
|
default: typing.Optional[str]
|
|
95
95
|
|
|
96
96
|
|
|
97
|
-
class Pipelines(pydantic.BaseModel):
|
|
97
|
+
class Pipelines(pydantic.v1.BaseModel):
|
|
98
98
|
kfp_pod_user_unix_id: typing.Optional[int]
|
|
99
99
|
|
|
100
100
|
|
|
101
|
-
class SecurityContext(pydantic.BaseModel):
|
|
101
|
+
class SecurityContext(pydantic.v1.BaseModel):
|
|
102
102
|
default: typing.Optional[str]
|
|
103
103
|
enrichment_mode: typing.Optional[SecurityContextEnrichmentModes]
|
|
104
104
|
enrichment_group_id: typing.Optional[int]
|
|
105
105
|
pipelines: typing.Optional[Pipelines]
|
|
106
106
|
|
|
107
107
|
|
|
108
|
-
class ServiceAccount(pydantic.BaseModel):
|
|
108
|
+
class ServiceAccount(pydantic.v1.BaseModel):
|
|
109
109
|
default: typing.Optional[str]
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
class StateThresholds(pydantic.BaseModel):
|
|
112
|
+
class StateThresholds(pydantic.v1.BaseModel):
|
|
113
113
|
default: typing.Optional[dict[str, str]]
|
|
114
114
|
|
|
115
115
|
|
|
116
|
-
class FunctionSpec(pydantic.BaseModel):
|
|
116
|
+
class FunctionSpec(pydantic.v1.BaseModel):
|
|
117
117
|
image_pull_secret: typing.Optional[ImagePullSecret]
|
|
118
118
|
security_context: typing.Optional[SecurityContext]
|
|
119
119
|
service_account: typing.Optional[ServiceAccount]
|
|
120
120
|
state_thresholds: typing.Optional[StateThresholds]
|
|
121
121
|
|
|
122
122
|
class Config:
|
|
123
|
-
extra = pydantic.Extra.allow
|
|
123
|
+
extra = pydantic.v1.Extra.allow
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
class Function(pydantic.BaseModel):
|
|
126
|
+
class Function(pydantic.v1.BaseModel):
|
|
127
127
|
spec: typing.Optional[FunctionSpec]
|
|
128
128
|
application: typing.Optional[dict[str, typing.Any]]
|
|
129
129
|
|
|
130
130
|
class Config:
|
|
131
|
-
extra = pydantic.Extra.allow
|
|
131
|
+
extra = pydantic.v1.Extra.allow
|
mlrun/common/schemas/hub.py
CHANGED
mlrun/common/schemas/k8s.py
CHANGED
|
@@ -14,18 +14,18 @@
|
|
|
14
14
|
#
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
|
|
19
19
|
import mlrun.common.types
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
class ResourceSpec(pydantic.BaseModel):
|
|
22
|
+
class ResourceSpec(pydantic.v1.BaseModel):
|
|
23
23
|
cpu: typing.Optional[str]
|
|
24
24
|
memory: typing.Optional[str]
|
|
25
25
|
gpu: typing.Optional[str]
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
class Resources(pydantic.BaseModel):
|
|
28
|
+
class Resources(pydantic.v1.BaseModel):
|
|
29
29
|
requests: ResourceSpec = ResourceSpec()
|
|
30
30
|
limits: ResourceSpec = ResourceSpec()
|
|
31
31
|
|
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
|
|
16
16
|
import typing
|
|
17
17
|
|
|
18
|
-
import pydantic
|
|
18
|
+
import pydantic.v1
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class MostCommonObjectTypesReport(pydantic.BaseModel):
|
|
21
|
+
class MostCommonObjectTypesReport(pydantic.v1.BaseModel):
|
|
22
22
|
object_types: list[tuple[str, int]]
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
class ObjectTypeReport(pydantic.BaseModel):
|
|
25
|
+
class ObjectTypeReport(pydantic.v1.BaseModel):
|
|
26
26
|
object_type: str
|
|
27
27
|
sample_size: int
|
|
28
28
|
start_index: typing.Optional[int]
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from .constants import (
|
|
16
16
|
V3IO_MODEL_MONITORING_DB,
|
|
17
|
+
ApplicationEvent,
|
|
17
18
|
ControllerPolicy,
|
|
18
19
|
DriftStatus,
|
|
19
20
|
EndpointType,
|
|
@@ -26,6 +27,7 @@ from .constants import (
|
|
|
26
27
|
FunctionURI,
|
|
27
28
|
MetricData,
|
|
28
29
|
ModelEndpointMonitoringMetricType,
|
|
30
|
+
ModelEndpointSchema,
|
|
29
31
|
ModelEndpointTarget,
|
|
30
32
|
ModelEndpointTargetSchemas,
|
|
31
33
|
ModelMonitoringMode,
|
|
@@ -36,7 +38,6 @@ from .constants import (
|
|
|
36
38
|
ResultData,
|
|
37
39
|
ResultKindApp,
|
|
38
40
|
ResultStatusApp,
|
|
39
|
-
SchedulingKeys,
|
|
40
41
|
SpecialApps,
|
|
41
42
|
TDEngineSuperTables,
|
|
42
43
|
TSDBTarget,
|
|
@@ -54,6 +55,12 @@ from .grafana import (
|
|
|
54
55
|
GrafanaTable,
|
|
55
56
|
GrafanaTimeSeriesTarget,
|
|
56
57
|
)
|
|
58
|
+
from .model_endpoint_v2 import (
|
|
59
|
+
ModelEndpointV2,
|
|
60
|
+
ModelEndpointV2Metadata,
|
|
61
|
+
ModelEndpointV2Spec,
|
|
62
|
+
ModelEndpointV2Status,
|
|
63
|
+
)
|
|
57
64
|
from .model_endpoints import (
|
|
58
65
|
Features,
|
|
59
66
|
FeatureValues,
|
|
@@ -29,6 +29,46 @@ class MonitoringStrEnum(StrEnum):
|
|
|
29
29
|
return list(map(lambda c: c.value, cls))
|
|
30
30
|
|
|
31
31
|
|
|
32
|
+
class ModelEndpointSchema(MonitoringStrEnum):
|
|
33
|
+
# metadata
|
|
34
|
+
UID = "uid"
|
|
35
|
+
PROJECT = "project"
|
|
36
|
+
ENDPOINT_TYPE = "endpoint_type"
|
|
37
|
+
NAME = "name"
|
|
38
|
+
CREATED = "created"
|
|
39
|
+
UPDATED = "updated"
|
|
40
|
+
LABELS = "labels"
|
|
41
|
+
|
|
42
|
+
# spec
|
|
43
|
+
FUNCTION_NAME = "function_name"
|
|
44
|
+
FUNCTION_UID = "function_uid"
|
|
45
|
+
MODEL_NAME = "model_name"
|
|
46
|
+
MODEL_TAG = "model_tag"
|
|
47
|
+
MODEL_CLASS = "model_class"
|
|
48
|
+
MODEL_UID = "model_uid"
|
|
49
|
+
FEATURE_NAMES = "feature_names"
|
|
50
|
+
LABEL_NAMES = "label_names"
|
|
51
|
+
|
|
52
|
+
# status
|
|
53
|
+
STATE = "state"
|
|
54
|
+
MONITORING_MODE = "monitoring_mode"
|
|
55
|
+
MONITORING_FEATURE_SET_URI = "monitoring_feature_set_uri"
|
|
56
|
+
CHILDREN = "children"
|
|
57
|
+
CHILDREN_UIDS = "children_uids"
|
|
58
|
+
FIRST_REQUEST = "first_request"
|
|
59
|
+
FUNCTION_URI = "function_uri"
|
|
60
|
+
MODEL_URI = "model_uri"
|
|
61
|
+
|
|
62
|
+
# status - operative
|
|
63
|
+
LAST_REQUEST = "last_request"
|
|
64
|
+
DRIFT_STATUS = "drift_status"
|
|
65
|
+
AVG_LATENCY = "avg_latency"
|
|
66
|
+
ERROR_COUNT = "error_count"
|
|
67
|
+
FEATURE_STATS = "feature_stats"
|
|
68
|
+
CURRENT_STATS = "current_stats"
|
|
69
|
+
DRIFT_MEASURES = "drift_measures"
|
|
70
|
+
|
|
71
|
+
|
|
32
72
|
class EventFieldType:
|
|
33
73
|
FUNCTION_URI = "function_uri"
|
|
34
74
|
FUNCTION = "function"
|
|
@@ -55,6 +95,8 @@ class EventFieldType:
|
|
|
55
95
|
NAMED_PREDICTIONS = "named_predictions"
|
|
56
96
|
ERROR_COUNT = "error_count"
|
|
57
97
|
MODEL_ERROR = "model_error"
|
|
98
|
+
ERROR_TYPE = "error_type"
|
|
99
|
+
INFER_ERROR = "infer_error"
|
|
58
100
|
ENTITIES = "entities"
|
|
59
101
|
FIRST_REQUEST = "first_request"
|
|
60
102
|
LAST_REQUEST = "last_request"
|
|
@@ -114,13 +156,14 @@ class WriterEvent(MonitoringStrEnum):
|
|
|
114
156
|
ENDPOINT_ID = "endpoint_id"
|
|
115
157
|
START_INFER_TIME = "start_infer_time"
|
|
116
158
|
END_INFER_TIME = "end_infer_time"
|
|
117
|
-
EVENT_KIND = "event_kind" # metric or result
|
|
159
|
+
EVENT_KIND = "event_kind" # metric or result or stats
|
|
118
160
|
DATA = "data"
|
|
119
161
|
|
|
120
162
|
|
|
121
163
|
class WriterEventKind(MonitoringStrEnum):
|
|
122
164
|
METRIC = "metric"
|
|
123
165
|
RESULT = "result"
|
|
166
|
+
STATS = "stats"
|
|
124
167
|
|
|
125
168
|
|
|
126
169
|
class MetricData(MonitoringStrEnum):
|
|
@@ -134,7 +177,17 @@ class ResultData(MonitoringStrEnum):
|
|
|
134
177
|
RESULT_KIND = "result_kind"
|
|
135
178
|
RESULT_STATUS = "result_status"
|
|
136
179
|
RESULT_EXTRA_DATA = "result_extra_data"
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class StatsData(MonitoringStrEnum):
|
|
183
|
+
STATS_NAME = "stats_name"
|
|
184
|
+
STATS = "stats"
|
|
185
|
+
TIMESTAMP = "timestamp"
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class StatsKind(MonitoringStrEnum):
|
|
137
189
|
CURRENT_STATS = "current_stats"
|
|
190
|
+
DRIFT_MEASURES = "drift_measures"
|
|
138
191
|
|
|
139
192
|
|
|
140
193
|
class EventLiveStats:
|
|
@@ -194,13 +247,6 @@ class ModelMonitoringStoreKinds:
|
|
|
194
247
|
EVENTS = "events"
|
|
195
248
|
|
|
196
249
|
|
|
197
|
-
class SchedulingKeys:
|
|
198
|
-
LAST_ANALYZED = "last_analyzed"
|
|
199
|
-
ENDPOINT_ID = "endpoint_id"
|
|
200
|
-
APPLICATION_NAME = "application_name"
|
|
201
|
-
UID = "uid"
|
|
202
|
-
|
|
203
|
-
|
|
204
250
|
class FileTargetKind:
|
|
205
251
|
ENDPOINTS = "endpoints"
|
|
206
252
|
EVENTS = "events"
|
|
@@ -209,14 +255,13 @@ class FileTargetKind:
|
|
|
209
255
|
PARQUET = "parquet"
|
|
210
256
|
APPS_PARQUET = "apps_parquet"
|
|
211
257
|
LOG_STREAM = "log_stream"
|
|
212
|
-
APP_RESULTS = "app_results"
|
|
213
|
-
APP_METRICS = "app_metrics"
|
|
214
258
|
MONITORING_SCHEDULES = "monitoring_schedules"
|
|
215
259
|
MONITORING_APPLICATION = "monitoring_application"
|
|
216
260
|
ERRORS = "errors"
|
|
261
|
+
STATS = "stats"
|
|
217
262
|
|
|
218
263
|
|
|
219
|
-
class ModelMonitoringMode(
|
|
264
|
+
class ModelMonitoringMode(StrEnum):
|
|
220
265
|
enabled = "enabled"
|
|
221
266
|
disabled = "disabled"
|
|
222
267
|
|
|
@@ -225,6 +270,11 @@ class EndpointType(IntEnum):
|
|
|
225
270
|
NODE_EP = 1 # end point that is not a child of a router
|
|
226
271
|
ROUTER = 2 # endpoint that is router
|
|
227
272
|
LEAF_EP = 3 # end point that is a child of a router
|
|
273
|
+
BATCH_EP = 4 # endpoint that is representing an offline batch endpoint
|
|
274
|
+
|
|
275
|
+
@classmethod
|
|
276
|
+
def top_level_list(cls):
|
|
277
|
+
return [cls.NODE_EP, cls.ROUTER, cls.BATCH_EP]
|
|
228
278
|
|
|
229
279
|
|
|
230
280
|
class MonitoringFunctionNames(MonitoringStrEnum):
|
|
@@ -244,6 +294,7 @@ class TDEngineSuperTables(MonitoringStrEnum):
|
|
|
244
294
|
APP_RESULTS = "app_results"
|
|
245
295
|
METRICS = "metrics"
|
|
246
296
|
PREDICTIONS = "predictions"
|
|
297
|
+
ERRORS = "errors"
|
|
247
298
|
|
|
248
299
|
|
|
249
300
|
@dataclass
|
|
@@ -364,7 +415,6 @@ class SpecialApps:
|
|
|
364
415
|
|
|
365
416
|
_RESERVED_FUNCTION_NAMES = MonitoringFunctionNames.list() + [SpecialApps.MLRUN_INFRA]
|
|
366
417
|
|
|
367
|
-
|
|
368
418
|
V3IO_MODEL_MONITORING_DB = "v3io"
|
|
369
419
|
|
|
370
420
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Copyright 2023 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
#
|
|
15
|
+
import abc
|
|
16
|
+
from typing import Optional
|
|
17
|
+
|
|
18
|
+
from pydantic.v1 import BaseModel, Field, constr
|
|
19
|
+
|
|
20
|
+
from ..object import ObjectKind, ObjectMetadata, ObjectSpec, ObjectStatus
|
|
21
|
+
from .constants import (
|
|
22
|
+
PROJECT_PATTERN,
|
|
23
|
+
EndpointType,
|
|
24
|
+
ModelMonitoringMode,
|
|
25
|
+
)
|
|
26
|
+
from .model_endpoints import _mapping_attributes
|
|
27
|
+
|
|
28
|
+
# TODO : replace ModelEndpoint
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ModelEndpointParser(abc.ABC, BaseModel):
|
|
32
|
+
@classmethod
|
|
33
|
+
def json_parse_values(cls) -> list[str]:
|
|
34
|
+
return []
|
|
35
|
+
|
|
36
|
+
@classmethod
|
|
37
|
+
def from_flat_dict(
|
|
38
|
+
cls, endpoint_dict: dict, json_parse_values: Optional[list] = None
|
|
39
|
+
):
|
|
40
|
+
"""Create a `ModelEndpointMetadata` object from an endpoint dictionary
|
|
41
|
+
|
|
42
|
+
:param endpoint_dict: Model endpoint dictionary.
|
|
43
|
+
:param json_parse_values: List of dictionary keys with a JSON string value that will be parsed into a
|
|
44
|
+
dictionary using json.loads().
|
|
45
|
+
"""
|
|
46
|
+
if json_parse_values is None:
|
|
47
|
+
json_parse_values = cls.json_parse_values()
|
|
48
|
+
|
|
49
|
+
return _mapping_attributes(
|
|
50
|
+
model_class=cls,
|
|
51
|
+
flattened_dictionary=endpoint_dict,
|
|
52
|
+
json_parse_values=json_parse_values,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class ModelEndpointV2Metadata(ObjectMetadata, ModelEndpointParser):
|
|
57
|
+
project: constr(regex=PROJECT_PATTERN)
|
|
58
|
+
endpoint_type: Optional[EndpointType] = EndpointType.NODE_EP.value
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ModelEndpointV2Spec(ObjectSpec, ModelEndpointParser):
|
|
62
|
+
model_uid: Optional[str] = ""
|
|
63
|
+
model_name: Optional[str] = ""
|
|
64
|
+
model_tag: Optional[str] = ""
|
|
65
|
+
model_class: Optional[str] = ""
|
|
66
|
+
function_name: Optional[str] = ""
|
|
67
|
+
function_uid: Optional[str] = ""
|
|
68
|
+
feature_names: Optional[list[str]] = []
|
|
69
|
+
label_names: Optional[list[str]] = []
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class ModelEndpointV2Status(ObjectStatus, ModelEndpointParser):
|
|
73
|
+
state: Optional[str] = "unknown" # will be updated according to the function state
|
|
74
|
+
first_request: Optional[str] = ""
|
|
75
|
+
children: Optional[list[str]] = []
|
|
76
|
+
children_uids: Optional[list[str]] = []
|
|
77
|
+
monitoring_feature_set_uri: Optional[str] = ""
|
|
78
|
+
monitoring_mode: Optional[ModelMonitoringMode] = ModelMonitoringMode.disabled.value
|
|
79
|
+
function_uri: Optional[str] = "" # <project_name>/<function_name>:<tag>
|
|
80
|
+
model_uri: Optional[str] = ""
|
|
81
|
+
|
|
82
|
+
# operative
|
|
83
|
+
last_request: Optional[str] = ""
|
|
84
|
+
drift_status: Optional[str] = ""
|
|
85
|
+
avg_latency: Optional[float] = None
|
|
86
|
+
error_count: Optional[int] = 0
|
|
87
|
+
feature_stats: Optional[dict] = {}
|
|
88
|
+
current_stats: Optional[dict] = {}
|
|
89
|
+
drift_measures: Optional[dict] = {}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ModelEndpointV2(BaseModel):
|
|
93
|
+
kind: ObjectKind = Field(ObjectKind.model_endpoint, const=True)
|
|
94
|
+
metadata: ModelEndpointV2Metadata
|
|
95
|
+
spec: ModelEndpointV2Spec
|
|
96
|
+
status: ModelEndpointV2Status
|
|
97
|
+
|
|
98
|
+
def flat_dict(self, exclude: Optional[set] = None):
|
|
99
|
+
"""Generate a flattened `ModelEndpoint` dictionary. The flattened dictionary result is important for storing
|
|
100
|
+
the model endpoint object in the database.
|
|
101
|
+
|
|
102
|
+
:return: Flattened `ModelEndpoint` dictionary.
|
|
103
|
+
"""
|
|
104
|
+
# Convert the ModelEndpoint object into a dictionary using BaseModel dict() function
|
|
105
|
+
# In addition, remove the BaseModel kind as it is not required by the DB schema
|
|
106
|
+
if exclude:
|
|
107
|
+
exclude = exclude | {"kind", "tag"}
|
|
108
|
+
else:
|
|
109
|
+
exclude = {"kind", "tag"}
|
|
110
|
+
model_endpoint_dictionary = self.dict(exclude=exclude)
|
|
111
|
+
|
|
112
|
+
# Initialize a flattened dictionary that will be filled with the model endpoint dictionary attributes
|
|
113
|
+
flatten_dict = {}
|
|
114
|
+
for k_object in model_endpoint_dictionary:
|
|
115
|
+
for key in model_endpoint_dictionary[k_object]:
|
|
116
|
+
# Extract the value of the current field
|
|
117
|
+
flatten_dict[key] = model_endpoint_dictionary[k_object][key]
|
|
118
|
+
|
|
119
|
+
return flatten_dict
|
|
120
|
+
|
|
121
|
+
@classmethod
|
|
122
|
+
def from_flat_dict(cls, endpoint_dict: dict) -> "ModelEndpointV2":
|
|
123
|
+
"""Create a `ModelEndpoint` object from an endpoint flattened dictionary. Because the provided dictionary
|
|
124
|
+
is flattened, we pass it as is to the subclasses without splitting the keys into spec, metadata, and status.
|
|
125
|
+
|
|
126
|
+
:param endpoint_dict: Model endpoint dictionary.
|
|
127
|
+
"""
|
|
128
|
+
|
|
129
|
+
return cls(
|
|
130
|
+
metadata=ModelEndpointV2Metadata.from_flat_dict(
|
|
131
|
+
endpoint_dict=endpoint_dict
|
|
132
|
+
),
|
|
133
|
+
spec=ModelEndpointV2Spec.from_flat_dict(endpoint_dict=endpoint_dict),
|
|
134
|
+
status=ModelEndpointV2Status.from_flat_dict(endpoint_dict=endpoint_dict),
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
@classmethod
|
|
138
|
+
def _operative_data(cls) -> set:
|
|
139
|
+
return {
|
|
140
|
+
"last_request",
|
|
141
|
+
"drift_status",
|
|
142
|
+
"avg_latency",
|
|
143
|
+
"error_count",
|
|
144
|
+
"feature_stats",
|
|
145
|
+
"current_stats",
|
|
146
|
+
"drift_measures",
|
|
147
|
+
"function_uri",
|
|
148
|
+
"model_uri",
|
|
149
|
+
}
|
|
@@ -17,7 +17,7 @@ import json
|
|
|
17
17
|
from datetime import datetime
|
|
18
18
|
from typing import Any, NamedTuple, Optional, TypeVar
|
|
19
19
|
|
|
20
|
-
from pydantic import BaseModel, Extra, Field, constr, validator
|
|
20
|
+
from pydantic.v1 import BaseModel, Extra, Field, constr, validator
|
|
21
21
|
|
|
22
22
|
# TODO: remove the unused import below after `mlrun.datastore` and `mlrun.utils` usage is removed.
|
|
23
23
|
# At the moment `make lint` fails if this is removed.
|
|
@@ -56,7 +56,9 @@ class ModelEndpointMetadata(BaseModel):
|
|
|
56
56
|
extra = Extra.allow
|
|
57
57
|
|
|
58
58
|
@classmethod
|
|
59
|
-
def from_flat_dict(
|
|
59
|
+
def from_flat_dict(
|
|
60
|
+
cls, endpoint_dict: dict, json_parse_values: Optional[list] = None
|
|
61
|
+
):
|
|
60
62
|
"""Create a `ModelEndpointMetadata` object from an endpoint dictionary
|
|
61
63
|
|
|
62
64
|
:param endpoint_dict: Model endpoint dictionary.
|
|
@@ -87,7 +89,9 @@ class ModelEndpointSpec(ObjectSpec):
|
|
|
87
89
|
monitoring_mode: Optional[ModelMonitoringMode] = ModelMonitoringMode.disabled.value
|
|
88
90
|
|
|
89
91
|
@classmethod
|
|
90
|
-
def from_flat_dict(
|
|
92
|
+
def from_flat_dict(
|
|
93
|
+
cls, endpoint_dict: dict, json_parse_values: Optional[list] = None
|
|
94
|
+
):
|
|
91
95
|
"""Create a `ModelEndpointSpec` object from an endpoint dictionary
|
|
92
96
|
|
|
93
97
|
:param endpoint_dict: Model endpoint dictionary.
|
|
@@ -188,7 +192,9 @@ class ModelEndpointStatus(ObjectStatus):
|
|
|
188
192
|
extra = Extra.allow
|
|
189
193
|
|
|
190
194
|
@classmethod
|
|
191
|
-
def from_flat_dict(
|
|
195
|
+
def from_flat_dict(
|
|
196
|
+
cls, endpoint_dict: dict, json_parse_values: Optional[list] = None
|
|
197
|
+
):
|
|
192
198
|
"""Create a `ModelEndpointStatus` object from an endpoint dictionary
|
|
193
199
|
|
|
194
200
|
:param endpoint_dict: Model endpoint dictionary.
|
|
@@ -284,7 +290,14 @@ class ModelEndpointMonitoringMetric(BaseModel):
|
|
|
284
290
|
app: str
|
|
285
291
|
type: ModelEndpointMonitoringMetricType
|
|
286
292
|
name: str
|
|
287
|
-
full_name: str
|
|
293
|
+
full_name: Optional[str] = None
|
|
294
|
+
kind: Optional[ResultKindApp] = None
|
|
295
|
+
|
|
296
|
+
def __init__(self, **kwargs):
|
|
297
|
+
super().__init__(**kwargs)
|
|
298
|
+
self.full_name = _compose_full_name(
|
|
299
|
+
project=self.project, app=self.app, name=self.name, type=self.type
|
|
300
|
+
)
|
|
288
301
|
|
|
289
302
|
|
|
290
303
|
def _compose_full_name(
|
|
@@ -315,6 +328,7 @@ class _ResultPoint(NamedTuple):
|
|
|
315
328
|
timestamp: datetime
|
|
316
329
|
value: float
|
|
317
330
|
status: ResultStatusApp
|
|
331
|
+
extra_data: Optional[str] = ""
|
|
318
332
|
|
|
319
333
|
|
|
320
334
|
class _ModelEndpointMonitoringMetricValuesBase(BaseModel):
|
|
@@ -365,8 +379,10 @@ def _mapping_attributes(
|
|
|
365
379
|
dict_to_parse[field_key] = _json_loads_if_not_none(
|
|
366
380
|
flattened_dictionary[field_key]
|
|
367
381
|
)
|
|
368
|
-
|
|
382
|
+
elif flattened_dictionary[field_key] != "null":
|
|
369
383
|
dict_to_parse[field_key] = flattened_dictionary[field_key]
|
|
384
|
+
else:
|
|
385
|
+
dict_to_parse[field_key] = None
|
|
370
386
|
|
|
371
387
|
return model_class.parse_obj(dict_to_parse)
|
|
372
388
|
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
import datetime
|
|
16
16
|
import enum
|
|
17
17
|
import typing
|
|
18
|
+
from typing import Optional
|
|
18
19
|
|
|
19
|
-
import pydantic
|
|
20
|
+
import pydantic.v1
|
|
20
21
|
|
|
21
22
|
import mlrun.common.types
|
|
22
23
|
|
|
@@ -45,6 +46,13 @@ class NotificationKind(mlrun.common.types.StrEnum):
|
|
|
45
46
|
slack: str = "slack"
|
|
46
47
|
"""**webhook** - The slack webhook to which to send the notification."""
|
|
47
48
|
|
|
49
|
+
mail: str = "mail"
|
|
50
|
+
"""
|
|
51
|
+
**email_addresses** - The target mails\n
|
|
52
|
+
**subject** - The subject of the mail\n
|
|
53
|
+
**body** - The body of the mail\n
|
|
54
|
+
"""
|
|
55
|
+
|
|
48
56
|
webhook: str = "webhook"
|
|
49
57
|
"""
|
|
50
58
|
**url** - The webhook url to which to send the notification.\n
|
|
@@ -86,7 +94,7 @@ class NotificationLimits(enum.Enum):
|
|
|
86
94
|
) # 900KB (k8s secret size limit is 1MB minus buffer for metadata)
|
|
87
95
|
|
|
88
96
|
|
|
89
|
-
class Notification(pydantic.BaseModel):
|
|
97
|
+
class Notification(pydantic.v1.BaseModel):
|
|
90
98
|
"""
|
|
91
99
|
Notification object schema
|
|
92
100
|
|
|
@@ -120,5 +128,12 @@ class Notification(pydantic.BaseModel):
|
|
|
120
128
|
reason: typing.Optional[str] = None
|
|
121
129
|
|
|
122
130
|
|
|
123
|
-
class SetNotificationRequest(pydantic.BaseModel):
|
|
131
|
+
class SetNotificationRequest(pydantic.v1.BaseModel):
|
|
124
132
|
notifications: list[Notification] = None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class NotificationState(pydantic.v1.BaseModel):
|
|
136
|
+
kind: str
|
|
137
|
+
err: Optional[
|
|
138
|
+
str
|
|
139
|
+
] # empty error means that the notifications were sent successfully
|
mlrun/common/schemas/object.py
CHANGED
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
|
|
15
15
|
import typing
|
|
16
16
|
|
|
17
|
-
import pydantic
|
|
17
|
+
import pydantic.v1
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
class PaginationInfo(pydantic.BaseModel):
|
|
20
|
+
class PaginationInfo(pydantic.v1.BaseModel):
|
|
21
21
|
class Config:
|
|
22
22
|
allow_population_by_field_name = True
|
|
23
23
|
|
|
24
24
|
page: typing.Optional[int]
|
|
25
|
-
page_size: typing.Optional[int] = pydantic.Field(alias="page-size")
|
|
26
|
-
page_token: typing.Optional[str] = pydantic.Field(alias="page-token")
|
|
25
|
+
page_size: typing.Optional[int] = pydantic.v1.Field(alias="page-size")
|
|
26
|
+
page_token: typing.Optional[str] = pydantic.v1.Field(alias="page-token")
|