mlrun 1.7.0rc4__py3-none-any.whl → 1.7.0rc20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__init__.py +11 -1
- mlrun/__main__.py +25 -111
- mlrun/{datastore/helpers.py → alerts/__init__.py} +2 -5
- mlrun/alerts/alert.py +144 -0
- mlrun/api/schemas/__init__.py +4 -3
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +38 -254
- mlrun/artifacts/dataset.py +9 -190
- mlrun/artifacts/manager.py +41 -47
- mlrun/artifacts/model.py +30 -158
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +68 -0
- mlrun/common/formatters/__init__.py +19 -0
- mlrun/{model_monitoring/stores/models/sqlite.py → common/formatters/artifact.py} +6 -8
- mlrun/common/formatters/base.py +78 -0
- mlrun/common/formatters/function.py +41 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/{runtimes → common/runtimes}/constants.py +32 -4
- mlrun/common/schemas/__init__.py +25 -4
- mlrun/common/schemas/alert.py +203 -0
- mlrun/common/schemas/api_gateway.py +148 -0
- mlrun/common/schemas/artifact.py +15 -5
- mlrun/common/schemas/auth.py +8 -2
- mlrun/common/schemas/client_spec.py +2 -0
- mlrun/common/schemas/frontend_spec.py +1 -0
- mlrun/common/schemas/function.py +4 -0
- mlrun/common/schemas/hub.py +7 -9
- mlrun/common/schemas/model_monitoring/__init__.py +19 -3
- mlrun/common/schemas/model_monitoring/constants.py +96 -26
- mlrun/common/schemas/model_monitoring/grafana.py +9 -5
- mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
- mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
- mlrun/common/schemas/pipeline.py +0 -9
- mlrun/common/schemas/project.py +22 -21
- mlrun/common/types.py +7 -1
- mlrun/config.py +87 -19
- mlrun/data_types/data_types.py +4 -0
- mlrun/data_types/to_pandas.py +9 -9
- mlrun/datastore/__init__.py +5 -8
- mlrun/datastore/alibaba_oss.py +130 -0
- mlrun/datastore/azure_blob.py +4 -5
- mlrun/datastore/base.py +69 -30
- mlrun/datastore/datastore.py +10 -2
- mlrun/datastore/datastore_profile.py +90 -6
- mlrun/datastore/google_cloud_storage.py +1 -1
- mlrun/datastore/hdfs.py +5 -0
- mlrun/datastore/inmem.py +2 -2
- mlrun/datastore/redis.py +2 -2
- mlrun/datastore/s3.py +5 -0
- mlrun/datastore/snowflake_utils.py +43 -0
- mlrun/datastore/sources.py +172 -44
- mlrun/datastore/store_resources.py +7 -7
- mlrun/datastore/targets.py +285 -41
- mlrun/datastore/utils.py +68 -5
- mlrun/datastore/v3io.py +27 -50
- mlrun/db/auth_utils.py +152 -0
- mlrun/db/base.py +149 -14
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +608 -178
- mlrun/db/nopdb.py +191 -7
- mlrun/errors.py +11 -0
- mlrun/execution.py +37 -20
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +21 -52
- mlrun/feature_store/feature_set.py +48 -23
- mlrun/feature_store/feature_vector.py +2 -1
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +9 -4
- mlrun/feature_store/retrieval/conversion.py +9 -9
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +9 -3
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +34 -24
- mlrun/feature_store/steps.py +30 -19
- mlrun/features.py +4 -13
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +2 -2
- mlrun/frameworks/lgbm/__init__.py +1 -1
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/model_handler.py +1 -1
- mlrun/frameworks/parallel_coordinates.py +2 -1
- mlrun/frameworks/pytorch/__init__.py +2 -2
- mlrun/frameworks/sklearn/__init__.py +1 -1
- mlrun/frameworks/tf_keras/__init__.py +5 -2
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +1 -1
- mlrun/frameworks/tf_keras/mlrun_interface.py +2 -2
- mlrun/frameworks/xgboost/__init__.py +1 -1
- mlrun/k8s_utils.py +10 -11
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +6 -5
- mlrun/launcher/client.py +8 -6
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +9 -3
- mlrun/launcher/remote.py +9 -3
- mlrun/lists.py +6 -2
- mlrun/model.py +58 -19
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +127 -301
- mlrun/model_monitoring/application.py +5 -296
- mlrun/model_monitoring/applications/__init__.py +11 -0
- mlrun/model_monitoring/applications/_application_steps.py +157 -0
- mlrun/model_monitoring/applications/base.py +282 -0
- mlrun/model_monitoring/applications/context.py +214 -0
- mlrun/model_monitoring/applications/evidently_base.py +211 -0
- mlrun/model_monitoring/applications/histogram_data_drift.py +224 -93
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +30 -36
- mlrun/model_monitoring/db/__init__.py +18 -0
- mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +58 -32
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -0
- mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +684 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +302 -155
- mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
- mlrun/model_monitoring/db/tsdb/base.py +329 -0
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
- mlrun/model_monitoring/evidently_application.py +6 -118
- mlrun/model_monitoring/features_drift_table.py +34 -22
- mlrun/model_monitoring/helpers.py +100 -7
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/stream_processing.py +93 -228
- mlrun/model_monitoring/tracking_policy.py +7 -1
- mlrun/model_monitoring/writer.py +152 -124
- mlrun/package/packagers_manager.py +1 -0
- mlrun/package/utils/_formatter.py +2 -2
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +21 -202
- mlrun/projects/operations.py +30 -16
- mlrun/projects/pipelines.py +92 -99
- mlrun/projects/project.py +757 -268
- mlrun/render.py +15 -14
- mlrun/run.py +160 -162
- mlrun/runtimes/__init__.py +55 -3
- mlrun/runtimes/base.py +33 -19
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +0 -28
- mlrun/runtimes/kubejob.py +28 -122
- mlrun/runtimes/local.py +5 -2
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +8 -8
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/runtimes/nuclio/__init__.py +1 -0
- mlrun/runtimes/nuclio/api_gateway.py +709 -0
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +523 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/nuclio/function.py +98 -58
- mlrun/runtimes/nuclio/serving.py +36 -42
- mlrun/runtimes/pod.py +196 -45
- mlrun/runtimes/remotesparkjob.py +1 -1
- mlrun/runtimes/sparkjob/spark3job.py +1 -1
- mlrun/runtimes/utils.py +6 -73
- mlrun/secrets.py +6 -2
- mlrun/serving/remote.py +2 -3
- mlrun/serving/routers.py +7 -4
- mlrun/serving/server.py +7 -8
- mlrun/serving/states.py +73 -43
- mlrun/serving/v2_serving.py +8 -7
- mlrun/track/tracker.py +2 -1
- mlrun/utils/async_http.py +25 -5
- mlrun/utils/helpers.py +141 -75
- mlrun/utils/http.py +1 -1
- mlrun/utils/logger.py +39 -7
- mlrun/utils/notifications/notification/__init__.py +14 -9
- mlrun/utils/notifications/notification/base.py +12 -0
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +3 -1
- mlrun/utils/notifications/notification/ipython.py +2 -0
- mlrun/utils/notifications/notification/slack.py +101 -21
- mlrun/utils/notifications/notification/webhook.py +11 -1
- mlrun/utils/notifications/notification_pusher.py +147 -16
- mlrun/utils/retryer.py +3 -2
- mlrun/utils/v3io_clients.py +0 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +33 -18
- mlrun-1.7.0rc20.dist-info/RECORD +353 -0
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +1 -1
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/batch.py +0 -974
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -382
- mlrun/platforms/other.py +0 -305
- mlrun-1.7.0rc4.dist-info/RECORD +0 -321
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc4.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
mlrun/common/schemas/function.py
CHANGED
|
@@ -45,6 +45,9 @@ class FunctionState:
|
|
|
45
45
|
# same goes for the build which is not coming from the pod, but is used and we can't just omit it for BC reasons
|
|
46
46
|
build = "build"
|
|
47
47
|
|
|
48
|
+
# for pipeline steps
|
|
49
|
+
skipped = "skipped"
|
|
50
|
+
|
|
48
51
|
@classmethod
|
|
49
52
|
def get_function_state_from_pod_state(cls, pod_state: str):
|
|
50
53
|
if pod_state == "succeeded":
|
|
@@ -60,6 +63,7 @@ class FunctionState:
|
|
|
60
63
|
return [
|
|
61
64
|
cls.ready,
|
|
62
65
|
cls.error,
|
|
66
|
+
cls.skipped,
|
|
63
67
|
]
|
|
64
68
|
|
|
65
69
|
|
mlrun/common/schemas/hub.py
CHANGED
|
@@ -59,28 +59,26 @@ class HubSource(BaseModel):
|
|
|
59
59
|
return f"{self.spec.path}/{self.spec.object_type}/{self.spec.channel}/{relative_path}"
|
|
60
60
|
|
|
61
61
|
def get_catalog_uri(self):
|
|
62
|
-
return self.get_full_uri(mlrun.
|
|
62
|
+
return self.get_full_uri(mlrun.mlconf.hub.catalog_filename)
|
|
63
63
|
|
|
64
64
|
@classmethod
|
|
65
65
|
def generate_default_source(cls):
|
|
66
|
-
if not mlrun.
|
|
66
|
+
if not mlrun.mlconf.hub.default_source.create:
|
|
67
67
|
return None
|
|
68
68
|
|
|
69
69
|
now = datetime.now(timezone.utc)
|
|
70
70
|
hub_metadata = HubObjectMetadata(
|
|
71
|
-
name=mlrun.
|
|
72
|
-
description=mlrun.
|
|
71
|
+
name=mlrun.mlconf.hub.default_source.name,
|
|
72
|
+
description=mlrun.mlconf.hub.default_source.description,
|
|
73
73
|
created=now,
|
|
74
74
|
updated=now,
|
|
75
75
|
)
|
|
76
76
|
return cls(
|
|
77
77
|
metadata=hub_metadata,
|
|
78
78
|
spec=HubSourceSpec(
|
|
79
|
-
path=mlrun.
|
|
80
|
-
channel=mlrun.
|
|
81
|
-
object_type=HubSourceType(
|
|
82
|
-
mlrun.config.config.hub.default_source.object_type
|
|
83
|
-
),
|
|
79
|
+
path=mlrun.mlconf.hub.default_source.url,
|
|
80
|
+
channel=mlrun.mlconf.hub.default_source.channel,
|
|
81
|
+
object_type=HubSourceType(mlrun.mlconf.hub.default_source.object_type),
|
|
84
82
|
),
|
|
85
83
|
status=ObjectStatus(state="created"),
|
|
86
84
|
)
|
|
@@ -11,8 +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
|
-
#
|
|
15
|
-
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
16
14
|
|
|
17
15
|
from .constants import (
|
|
18
16
|
ControllerPolicy,
|
|
@@ -22,19 +20,32 @@ from .constants import (
|
|
|
22
20
|
EventFieldType,
|
|
23
21
|
EventKeyMetrics,
|
|
24
22
|
EventLiveStats,
|
|
23
|
+
FeatureSetFeatures,
|
|
25
24
|
FileTargetKind,
|
|
26
25
|
FunctionURI,
|
|
26
|
+
MetricData,
|
|
27
27
|
ModelEndpointTarget,
|
|
28
28
|
ModelMonitoringMode,
|
|
29
29
|
ModelMonitoringStoreKinds,
|
|
30
30
|
MonitoringFunctionNames,
|
|
31
|
+
PredictionsQueryConstants,
|
|
31
32
|
ProjectSecretKeys,
|
|
33
|
+
PrometheusEndpoints,
|
|
32
34
|
PrometheusMetric,
|
|
33
|
-
|
|
35
|
+
ResultData,
|
|
36
|
+
ResultKindApp,
|
|
37
|
+
SchedulingKeys,
|
|
38
|
+
SpecialApps,
|
|
39
|
+
TDEngineSuperTables,
|
|
40
|
+
TSDBTarget,
|
|
41
|
+
V3IOTSDBTables,
|
|
34
42
|
VersionedModel,
|
|
43
|
+
WriterEvent,
|
|
44
|
+
WriterEventKind,
|
|
35
45
|
)
|
|
36
46
|
from .grafana import (
|
|
37
47
|
GrafanaColumn,
|
|
48
|
+
GrafanaColumnType,
|
|
38
49
|
GrafanaDataPoint,
|
|
39
50
|
GrafanaNumberColumn,
|
|
40
51
|
GrafanaStringColumn,
|
|
@@ -47,6 +58,11 @@ from .model_endpoints import (
|
|
|
47
58
|
ModelEndpoint,
|
|
48
59
|
ModelEndpointList,
|
|
49
60
|
ModelEndpointMetadata,
|
|
61
|
+
ModelEndpointMonitoringMetric,
|
|
62
|
+
ModelEndpointMonitoringMetricNoData,
|
|
63
|
+
ModelEndpointMonitoringMetricType,
|
|
64
|
+
ModelEndpointMonitoringMetricValues,
|
|
65
|
+
ModelEndpointMonitoringResultValues,
|
|
50
66
|
ModelEndpointSpec,
|
|
51
67
|
ModelEndpointStatus,
|
|
52
68
|
)
|
|
@@ -21,6 +21,12 @@ import mlrun.common.helpers
|
|
|
21
21
|
from mlrun.common.types import StrEnum
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
class MonitoringStrEnum(StrEnum):
|
|
25
|
+
@classmethod
|
|
26
|
+
def list(cls):
|
|
27
|
+
return list(map(lambda c: c.value, cls))
|
|
28
|
+
|
|
29
|
+
|
|
24
30
|
class EventFieldType:
|
|
25
31
|
FUNCTION_URI = "function_uri"
|
|
26
32
|
FUNCTION = "function"
|
|
@@ -75,25 +81,59 @@ class EventFieldType:
|
|
|
75
81
|
DRIFT_DETECTED_THRESHOLD = "drift_detected_threshold"
|
|
76
82
|
POSSIBLE_DRIFT_THRESHOLD = "possible_drift_threshold"
|
|
77
83
|
SAMPLE_PARQUET_PATH = "sample_parquet_path"
|
|
84
|
+
TIME = "time"
|
|
85
|
+
TABLE_COLUMN = "table_column"
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class FeatureSetFeatures(MonitoringStrEnum):
|
|
89
|
+
LATENCY = EventFieldType.LATENCY
|
|
90
|
+
ERROR_COUNT = EventFieldType.ERROR_COUNT
|
|
91
|
+
METRICS = EventFieldType.METRICS
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def time_stamp(cls):
|
|
95
|
+
return EventFieldType.TIMESTAMP
|
|
96
|
+
|
|
97
|
+
@classmethod
|
|
98
|
+
def entity(cls):
|
|
99
|
+
return EventFieldType.ENDPOINT_ID
|
|
78
100
|
|
|
79
101
|
|
|
80
102
|
class ApplicationEvent:
|
|
81
103
|
APPLICATION_NAME = "application_name"
|
|
82
|
-
CURRENT_STATS = "current_stats"
|
|
83
|
-
FEATURE_STATS = "feature_stats"
|
|
84
|
-
SAMPLE_PARQUET_PATH = "sample_parquet_path"
|
|
85
104
|
START_INFER_TIME = "start_infer_time"
|
|
86
105
|
END_INFER_TIME = "end_infer_time"
|
|
87
106
|
LAST_REQUEST = "last_request"
|
|
88
107
|
ENDPOINT_ID = "endpoint_id"
|
|
89
108
|
OUTPUT_STREAM_URI = "output_stream_uri"
|
|
109
|
+
MLRUN_CONTEXT = "mlrun_context"
|
|
110
|
+
|
|
111
|
+
# Deprecated fields - TODO : delete in 1.9.0 (V1 app deprecation)
|
|
112
|
+
SAMPLE_PARQUET_PATH = "sample_parquet_path"
|
|
113
|
+
CURRENT_STATS = "current_stats"
|
|
114
|
+
FEATURE_STATS = "feature_stats"
|
|
90
115
|
|
|
91
116
|
|
|
92
|
-
class WriterEvent(
|
|
117
|
+
class WriterEvent(MonitoringStrEnum):
|
|
93
118
|
APPLICATION_NAME = "application_name"
|
|
94
119
|
ENDPOINT_ID = "endpoint_id"
|
|
95
120
|
START_INFER_TIME = "start_infer_time"
|
|
96
121
|
END_INFER_TIME = "end_infer_time"
|
|
122
|
+
EVENT_KIND = "event_kind" # metric or result
|
|
123
|
+
DATA = "data"
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class WriterEventKind(MonitoringStrEnum):
|
|
127
|
+
METRIC = "metric"
|
|
128
|
+
RESULT = "result"
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class MetricData(MonitoringStrEnum):
|
|
132
|
+
METRIC_NAME = "metric_name"
|
|
133
|
+
METRIC_VALUE = "metric_value"
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class ResultData(MonitoringStrEnum):
|
|
97
137
|
RESULT_NAME = "result_name"
|
|
98
138
|
RESULT_VALUE = "result_value"
|
|
99
139
|
RESULT_KIND = "result_kind"
|
|
@@ -101,10 +141,6 @@ class WriterEvent(StrEnum):
|
|
|
101
141
|
RESULT_EXTRA_DATA = "result_extra_data"
|
|
102
142
|
CURRENT_STATS = "current_stats"
|
|
103
143
|
|
|
104
|
-
@classmethod
|
|
105
|
-
def list(cls):
|
|
106
|
-
return list(map(lambda c: c.value, cls))
|
|
107
|
-
|
|
108
144
|
|
|
109
145
|
class EventLiveStats:
|
|
110
146
|
LATENCY_AVG_5M = "latency_avg_5m"
|
|
@@ -122,10 +158,6 @@ class EventKeyMetrics:
|
|
|
122
158
|
REAL_TIME = "real_time"
|
|
123
159
|
|
|
124
160
|
|
|
125
|
-
class TimeSeriesTarget:
|
|
126
|
-
TSDB = "tsdb"
|
|
127
|
-
|
|
128
|
-
|
|
129
161
|
class ModelEndpointTarget:
|
|
130
162
|
V3IO_NOSQL = "v3io-nosql"
|
|
131
163
|
SQL = "sql"
|
|
@@ -135,8 +167,9 @@ class ProjectSecretKeys:
|
|
|
135
167
|
ENDPOINT_STORE_CONNECTION = "MODEL_MONITORING_ENDPOINT_STORE_CONNECTION"
|
|
136
168
|
ACCESS_KEY = "MODEL_MONITORING_ACCESS_KEY"
|
|
137
169
|
PIPELINES_ACCESS_KEY = "MODEL_MONITORING_PIPELINES_ACCESS_KEY"
|
|
138
|
-
|
|
170
|
+
KAFKA_BROKERS = "KAFKA_BROKERS"
|
|
139
171
|
STREAM_PATH = "STREAM_PATH"
|
|
172
|
+
TSDB_CONNECTION = "TSDB_CONNECTION"
|
|
140
173
|
|
|
141
174
|
|
|
142
175
|
class ModelMonitoringStoreKinds:
|
|
@@ -146,15 +179,23 @@ class ModelMonitoringStoreKinds:
|
|
|
146
179
|
|
|
147
180
|
class SchedulingKeys:
|
|
148
181
|
LAST_ANALYZED = "last_analyzed"
|
|
182
|
+
ENDPOINT_ID = "endpoint_id"
|
|
183
|
+
APPLICATION_NAME = "application_name"
|
|
184
|
+
UID = "uid"
|
|
149
185
|
|
|
150
186
|
|
|
151
187
|
class FileTargetKind:
|
|
152
188
|
ENDPOINTS = "endpoints"
|
|
153
189
|
EVENTS = "events"
|
|
190
|
+
PREDICTIONS = "predictions"
|
|
154
191
|
STREAM = "stream"
|
|
155
192
|
PARQUET = "parquet"
|
|
156
193
|
APPS_PARQUET = "apps_parquet"
|
|
157
194
|
LOG_STREAM = "log_stream"
|
|
195
|
+
APP_RESULTS = "app_results"
|
|
196
|
+
APP_METRICS = "app_metrics"
|
|
197
|
+
MONITORING_SCHEDULES = "monitoring_schedules"
|
|
198
|
+
MONITORING_APPLICATION = "monitoring_application"
|
|
158
199
|
|
|
159
200
|
|
|
160
201
|
class ModelMonitoringMode(str, Enum):
|
|
@@ -177,20 +218,28 @@ class PrometheusMetric:
|
|
|
177
218
|
DRIFT_STATUS = "drift_status"
|
|
178
219
|
|
|
179
220
|
|
|
180
|
-
class
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
221
|
+
class PrometheusEndpoints(MonitoringStrEnum):
|
|
222
|
+
MODEL_MONITORING_METRICS = "/model-monitoring-metrics"
|
|
223
|
+
MONITORING_BATCH_METRICS = "/monitoring-batch-metrics"
|
|
224
|
+
MONITORING_DRIFT_STATUS = "/monitoring-drift-status"
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
class MonitoringFunctionNames(MonitoringStrEnum):
|
|
184
228
|
STREAM = "model-monitoring-stream"
|
|
229
|
+
APPLICATION_CONTROLLER = "model-monitoring-controller"
|
|
230
|
+
WRITER = "model-monitoring-writer"
|
|
185
231
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
232
|
+
|
|
233
|
+
class V3IOTSDBTables(MonitoringStrEnum):
|
|
234
|
+
APP_RESULTS = "app-results"
|
|
235
|
+
METRICS = "metrics"
|
|
236
|
+
EVENTS = "events"
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
class TDEngineSuperTables(MonitoringStrEnum):
|
|
240
|
+
APP_RESULTS = "app_results"
|
|
241
|
+
METRICS = "metrics"
|
|
242
|
+
PREDICTIONS = "predictions"
|
|
194
243
|
|
|
195
244
|
|
|
196
245
|
@dataclass
|
|
@@ -269,6 +318,7 @@ class ResultKindApp(Enum):
|
|
|
269
318
|
concept_drift = 1
|
|
270
319
|
model_performance = 2
|
|
271
320
|
system_performance = 3
|
|
321
|
+
custom = 4
|
|
272
322
|
|
|
273
323
|
|
|
274
324
|
class ResultStatusApp(IntEnum):
|
|
@@ -286,9 +336,29 @@ class ModelMonitoringAppLabel:
|
|
|
286
336
|
KEY = "mlrun__type"
|
|
287
337
|
VAL = "mlrun__model-monitoring-application"
|
|
288
338
|
|
|
339
|
+
def __str__(self) -> str:
|
|
340
|
+
return f"{self.KEY}={self.VAL}"
|
|
341
|
+
|
|
289
342
|
|
|
290
343
|
class ControllerPolicy:
|
|
291
344
|
BASE_PERIOD = "base_period"
|
|
292
345
|
|
|
293
346
|
|
|
294
|
-
|
|
347
|
+
class TSDBTarget:
|
|
348
|
+
V3IO_TSDB = "v3io-tsdb"
|
|
349
|
+
TDEngine = "tdengine"
|
|
350
|
+
PROMETHEUS = "prometheus"
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
class HistogramDataDriftApplicationConstants:
|
|
354
|
+
NAME = "histogram-data-drift"
|
|
355
|
+
GENERAL_RESULT_NAME = "general_drift"
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
class PredictionsQueryConstants:
|
|
359
|
+
DEFAULT_AGGREGATION_GRANULARITY = "10m"
|
|
360
|
+
INVOCATIONS = "invocations"
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
class SpecialApps:
|
|
364
|
+
MLRUN_INFRA = "mlrun-infra"
|
|
@@ -11,12 +11,18 @@
|
|
|
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
|
-
#
|
|
15
14
|
|
|
16
15
|
from typing import Optional, Union
|
|
17
16
|
|
|
18
17
|
from pydantic import BaseModel
|
|
19
18
|
|
|
19
|
+
import mlrun.common.types
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class GrafanaColumnType(mlrun.common.types.StrEnum):
|
|
23
|
+
NUMBER = "number"
|
|
24
|
+
STRING = "string"
|
|
25
|
+
|
|
20
26
|
|
|
21
27
|
class GrafanaColumn(BaseModel):
|
|
22
28
|
text: str
|
|
@@ -24,13 +30,11 @@ class GrafanaColumn(BaseModel):
|
|
|
24
30
|
|
|
25
31
|
|
|
26
32
|
class GrafanaNumberColumn(GrafanaColumn):
|
|
27
|
-
|
|
28
|
-
type: str = "number"
|
|
33
|
+
type: str = GrafanaColumnType.NUMBER
|
|
29
34
|
|
|
30
35
|
|
|
31
36
|
class GrafanaStringColumn(GrafanaColumn):
|
|
32
|
-
|
|
33
|
-
type: str = "string"
|
|
37
|
+
type: str = GrafanaColumnType.STRING
|
|
34
38
|
|
|
35
39
|
|
|
36
40
|
class GrafanaTable(BaseModel):
|
|
@@ -11,16 +11,18 @@
|
|
|
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
|
-
#
|
|
15
14
|
|
|
16
15
|
import enum
|
|
17
16
|
import json
|
|
18
|
-
|
|
17
|
+
import re
|
|
18
|
+
from datetime import datetime
|
|
19
|
+
from typing import Any, NamedTuple, Optional
|
|
19
20
|
|
|
20
21
|
from pydantic import BaseModel, Field, validator
|
|
21
22
|
from pydantic.main import Extra
|
|
22
23
|
|
|
23
24
|
import mlrun.common.model_monitoring
|
|
25
|
+
import mlrun.common.types
|
|
24
26
|
|
|
25
27
|
from ..object import ObjectKind, ObjectSpec, ObjectStatus
|
|
26
28
|
from .constants import (
|
|
@@ -29,6 +31,8 @@ from .constants import (
|
|
|
29
31
|
EventKeyMetrics,
|
|
30
32
|
EventLiveStats,
|
|
31
33
|
ModelMonitoringMode,
|
|
34
|
+
ResultKindApp,
|
|
35
|
+
ResultStatusApp,
|
|
32
36
|
)
|
|
33
37
|
|
|
34
38
|
|
|
@@ -100,6 +104,7 @@ class ModelEndpointSpec(ObjectSpec):
|
|
|
100
104
|
)
|
|
101
105
|
|
|
102
106
|
@validator("monitor_configuration")
|
|
107
|
+
@classmethod
|
|
103
108
|
def set_name(cls, monitor_configuration):
|
|
104
109
|
return monitor_configuration or {
|
|
105
110
|
EventFieldType.DRIFT_DETECTED_THRESHOLD: (
|
|
@@ -111,6 +116,7 @@ class ModelEndpointSpec(ObjectSpec):
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
@validator("model_uri")
|
|
119
|
+
@classmethod
|
|
114
120
|
def validate_model_uri(cls, model_uri):
|
|
115
121
|
"""Validate that the model uri includes the required prefix"""
|
|
116
122
|
prefix, uri = mlrun.datastore.parse_store_uri(model_uri)
|
|
@@ -292,6 +298,84 @@ class ModelEndpointList(BaseModel):
|
|
|
292
298
|
endpoints: list[ModelEndpoint] = []
|
|
293
299
|
|
|
294
300
|
|
|
301
|
+
class ModelEndpointMonitoringMetricType(mlrun.common.types.StrEnum):
|
|
302
|
+
RESULT = "result"
|
|
303
|
+
METRIC = "metric"
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
class ModelEndpointMonitoringMetric(BaseModel):
|
|
307
|
+
project: str
|
|
308
|
+
app: str
|
|
309
|
+
type: ModelEndpointMonitoringMetricType
|
|
310
|
+
name: str
|
|
311
|
+
full_name: str
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
def _compose_full_name(
|
|
315
|
+
*,
|
|
316
|
+
project: str,
|
|
317
|
+
app: str,
|
|
318
|
+
name: str,
|
|
319
|
+
type: ModelEndpointMonitoringMetricType = ModelEndpointMonitoringMetricType.RESULT,
|
|
320
|
+
) -> str:
|
|
321
|
+
return ".".join([project, app, type, name])
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
_FQN_PART_PATTERN = r"[a-zA-Z0-9_-]+"
|
|
325
|
+
_FQN_PATTERN = (
|
|
326
|
+
rf"^(?P<project>{_FQN_PART_PATTERN})\."
|
|
327
|
+
rf"(?P<app>{_FQN_PART_PATTERN})\."
|
|
328
|
+
rf"(?P<type>{ModelEndpointMonitoringMetricType.RESULT}|{ModelEndpointMonitoringMetricType.METRIC})\."
|
|
329
|
+
rf"(?P<name>{_FQN_PART_PATTERN})$"
|
|
330
|
+
)
|
|
331
|
+
_FQN_REGEX = re.compile(_FQN_PATTERN)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _parse_metric_fqn_to_monitoring_metric(fqn: str) -> ModelEndpointMonitoringMetric:
|
|
335
|
+
match = _FQN_REGEX.fullmatch(fqn)
|
|
336
|
+
if match is None:
|
|
337
|
+
raise ValueError("The fully qualified name is not in the expected format")
|
|
338
|
+
return ModelEndpointMonitoringMetric.parse_obj(
|
|
339
|
+
match.groupdict() | {"full_name": fqn}
|
|
340
|
+
)
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
class _MetricPoint(NamedTuple):
|
|
344
|
+
timestamp: datetime
|
|
345
|
+
value: float
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
class _ResultPoint(NamedTuple):
|
|
349
|
+
timestamp: datetime
|
|
350
|
+
value: float
|
|
351
|
+
status: ResultStatusApp
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
class _ModelEndpointMonitoringMetricValuesBase(BaseModel):
|
|
355
|
+
full_name: str
|
|
356
|
+
type: ModelEndpointMonitoringMetricType
|
|
357
|
+
data: bool
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
class ModelEndpointMonitoringMetricValues(_ModelEndpointMonitoringMetricValuesBase):
|
|
361
|
+
type: ModelEndpointMonitoringMetricType = ModelEndpointMonitoringMetricType.METRIC
|
|
362
|
+
values: list[_MetricPoint]
|
|
363
|
+
data: bool = True
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
class ModelEndpointMonitoringResultValues(_ModelEndpointMonitoringMetricValuesBase):
|
|
367
|
+
type: ModelEndpointMonitoringMetricType = ModelEndpointMonitoringMetricType.RESULT
|
|
368
|
+
result_kind: ResultKindApp
|
|
369
|
+
values: list[_ResultPoint]
|
|
370
|
+
data: bool = True
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
class ModelEndpointMonitoringMetricNoData(_ModelEndpointMonitoringMetricValuesBase):
|
|
374
|
+
full_name: str
|
|
375
|
+
type: ModelEndpointMonitoringMetricType
|
|
376
|
+
data: bool = False
|
|
377
|
+
|
|
378
|
+
|
|
295
379
|
def _mapping_attributes(
|
|
296
380
|
base_model: BaseModel,
|
|
297
381
|
flattened_dictionary: dict,
|
|
@@ -11,19 +11,16 @@
|
|
|
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
|
-
from deprecated import deprecated
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
from mlrun.runtimes.mpijob.abstract import AbstractMPIJobRuntime
|
|
15
|
+
import typing
|
|
18
16
|
|
|
17
|
+
import pydantic
|
|
19
18
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
crd_version = MPIJobCRDVersions.v1alpha1
|
|
29
|
-
crd_plural = "mpijobs"
|
|
19
|
+
|
|
20
|
+
class PaginationInfo(pydantic.BaseModel):
|
|
21
|
+
class Config:
|
|
22
|
+
allow_population_by_field_name = True
|
|
23
|
+
|
|
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")
|
mlrun/common/schemas/pipeline.py
CHANGED
|
@@ -16,15 +16,6 @@ import typing
|
|
|
16
16
|
|
|
17
17
|
import pydantic
|
|
18
18
|
|
|
19
|
-
import mlrun.common.types
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class PipelinesFormat(mlrun.common.types.StrEnum):
|
|
23
|
-
full = "full"
|
|
24
|
-
metadata_only = "metadata_only"
|
|
25
|
-
summary = "summary"
|
|
26
|
-
name_only = "name_only"
|
|
27
|
-
|
|
28
19
|
|
|
29
20
|
class PipelinesPagination(str):
|
|
30
21
|
default_page_size = 20
|
mlrun/common/schemas/project.py
CHANGED
|
@@ -23,16 +23,6 @@ from .common import ImageBuilder
|
|
|
23
23
|
from .object import ObjectKind, ObjectStatus
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
class ProjectsFormat(mlrun.common.types.StrEnum):
|
|
27
|
-
full = "full"
|
|
28
|
-
name_only = "name_only"
|
|
29
|
-
# minimal format removes large fields from the response (e.g. functions, workflows, artifacts)
|
|
30
|
-
# and is used for faster response times (in the UI)
|
|
31
|
-
minimal = "minimal"
|
|
32
|
-
# internal - allowed only in follower mode, only for the leader for upgrade purposes
|
|
33
|
-
leader = "leader"
|
|
34
|
-
|
|
35
|
-
|
|
36
26
|
class ProjectMetadata(pydantic.BaseModel):
|
|
37
27
|
name: str
|
|
38
28
|
created: typing.Optional[datetime.datetime] = None
|
|
@@ -87,6 +77,7 @@ class ProjectSpec(pydantic.BaseModel):
|
|
|
87
77
|
custom_packagers: typing.Optional[list[tuple[str, bool]]] = None
|
|
88
78
|
default_image: typing.Optional[str] = None
|
|
89
79
|
build: typing.Optional[ImageBuilder] = None
|
|
80
|
+
default_function_node_selector: typing.Optional[dict] = {}
|
|
90
81
|
|
|
91
82
|
class Config:
|
|
92
83
|
extra = pydantic.Extra.allow
|
|
@@ -109,9 +100,14 @@ class ProjectSummary(pydantic.BaseModel):
|
|
|
109
100
|
files_count: int
|
|
110
101
|
feature_sets_count: int
|
|
111
102
|
models_count: int
|
|
103
|
+
runs_completed_recent_count: int
|
|
112
104
|
runs_failed_recent_count: int
|
|
113
105
|
runs_running_count: int
|
|
114
|
-
|
|
106
|
+
distinct_schedules_count: int
|
|
107
|
+
distinct_scheduled_jobs_pending_count: int
|
|
108
|
+
distinct_scheduled_pipelines_pending_count: int
|
|
109
|
+
pipelines_completed_recent_count: typing.Optional[int] = None
|
|
110
|
+
pipelines_failed_recent_count: typing.Optional[int] = None
|
|
115
111
|
pipelines_running_count: typing.Optional[int] = None
|
|
116
112
|
|
|
117
113
|
|
|
@@ -119,17 +115,22 @@ class IguazioProject(pydantic.BaseModel):
|
|
|
119
115
|
data: dict
|
|
120
116
|
|
|
121
117
|
|
|
118
|
+
# The format query param controls the project type used:
|
|
119
|
+
# full - Project
|
|
120
|
+
# name_only - str
|
|
121
|
+
# summary - ProjectSummary
|
|
122
|
+
# leader - currently only IguazioProject supported
|
|
123
|
+
# The way pydantic handles typing.Union is that it takes the object and tries to coerce it to be the types of the
|
|
124
|
+
# union by the definition order. Therefore we can't currently add generic dict for all leader formats, but we need
|
|
125
|
+
# to add a specific classes for them. it's frustrating but couldn't find other workaround, see:
|
|
126
|
+
# https://github.com/samuelcolvin/pydantic/issues/1423, https://github.com/samuelcolvin/pydantic/issues/619
|
|
127
|
+
ProjectOutput = typing.TypeVar(
|
|
128
|
+
"ProjectOutput", Project, str, ProjectSummary, IguazioProject
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
|
|
122
132
|
class ProjectsOutput(pydantic.BaseModel):
|
|
123
|
-
|
|
124
|
-
# full - Project
|
|
125
|
-
# name_only - str
|
|
126
|
-
# summary - ProjectSummary
|
|
127
|
-
# leader - currently only IguazioProject supported
|
|
128
|
-
# The way pydantic handles typing.Union is that it takes the object and tries to coerce it to be the types of the
|
|
129
|
-
# union by the definition order. Therefore we can't currently add generic dict for all leader formats, but we need
|
|
130
|
-
# to add a specific classes for them. it's frustrating but couldn't find other workaround, see:
|
|
131
|
-
# https://github.com/samuelcolvin/pydantic/issues/1423, https://github.com/samuelcolvin/pydantic/issues/619
|
|
132
|
-
projects: list[typing.Union[Project, str, ProjectSummary, IguazioProject]]
|
|
133
|
+
projects: list[ProjectOutput]
|
|
133
134
|
|
|
134
135
|
|
|
135
136
|
class ProjectSummariesOutput(pydantic.BaseModel):
|
mlrun/common/types.py
CHANGED
|
@@ -11,7 +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
|
-
#
|
|
15
14
|
|
|
16
15
|
import enum
|
|
17
16
|
|
|
@@ -23,3 +22,10 @@ class StrEnum(str, enum.Enum):
|
|
|
23
22
|
|
|
24
23
|
def __repr__(self):
|
|
25
24
|
return self.value
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# Partial backport from Python 3.11
|
|
28
|
+
# https://docs.python.org/3/library/http.html#http.HTTPMethod
|
|
29
|
+
class HTTPMethod(StrEnum):
|
|
30
|
+
GET = "GET"
|
|
31
|
+
POST = "POST"
|