mlrun 1.7.0rc14__py3-none-any.whl → 1.7.0rc22__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 +10 -1
- mlrun/__main__.py +23 -111
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +169 -0
- mlrun/api/schemas/__init__.py +4 -3
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +36 -253
- mlrun/artifacts/dataset.py +9 -190
- mlrun/artifacts/manager.py +46 -42
- mlrun/artifacts/model.py +9 -141
- mlrun/artifacts/plots.py +14 -375
- mlrun/common/constants.py +65 -3
- mlrun/common/formatters/__init__.py +19 -0
- mlrun/{runtimes/mpijob/v1alpha1.py → common/formatters/artifact.py} +6 -14
- mlrun/common/formatters/base.py +113 -0
- mlrun/common/formatters/function.py +46 -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 +10 -5
- mlrun/common/schemas/alert.py +92 -11
- mlrun/common/schemas/api_gateway.py +56 -0
- mlrun/common/schemas/artifact.py +15 -5
- mlrun/common/schemas/auth.py +2 -0
- mlrun/common/schemas/client_spec.py +1 -0
- mlrun/common/schemas/frontend_spec.py +1 -0
- mlrun/common/schemas/function.py +4 -0
- mlrun/common/schemas/model_monitoring/__init__.py +15 -3
- mlrun/common/schemas/model_monitoring/constants.py +58 -7
- mlrun/common/schemas/model_monitoring/grafana.py +9 -5
- mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
- mlrun/common/schemas/pipeline.py +0 -9
- mlrun/common/schemas/project.py +5 -11
- mlrun/common/types.py +1 -0
- mlrun/config.py +30 -9
- mlrun/data_types/to_pandas.py +9 -9
- mlrun/datastore/base.py +41 -9
- mlrun/datastore/datastore.py +6 -2
- mlrun/datastore/datastore_profile.py +56 -4
- mlrun/datastore/inmem.py +2 -2
- mlrun/datastore/redis.py +2 -2
- mlrun/datastore/s3.py +5 -0
- mlrun/datastore/sources.py +147 -7
- mlrun/datastore/store_resources.py +7 -7
- mlrun/datastore/targets.py +110 -42
- mlrun/datastore/utils.py +42 -0
- mlrun/db/base.py +54 -10
- mlrun/db/httpdb.py +282 -79
- mlrun/db/nopdb.py +52 -10
- mlrun/errors.py +11 -0
- mlrun/execution.py +26 -9
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +12 -47
- mlrun/feature_store/feature_set.py +9 -0
- mlrun/feature_store/feature_vector.py +8 -0
- 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 +16 -0
- mlrun/frameworks/__init__.py +6 -0
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
- mlrun/frameworks/parallel_coordinates.py +2 -1
- mlrun/frameworks/tf_keras/__init__.py +4 -1
- mlrun/k8s_utils.py +10 -11
- mlrun/launcher/base.py +4 -3
- mlrun/launcher/client.py +5 -3
- mlrun/launcher/local.py +12 -2
- mlrun/launcher/remote.py +9 -2
- mlrun/lists.py +6 -2
- mlrun/model.py +47 -21
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +42 -18
- mlrun/model_monitoring/application.py +5 -305
- mlrun/model_monitoring/applications/__init__.py +11 -0
- mlrun/model_monitoring/applications/_application_steps.py +157 -0
- mlrun/model_monitoring/applications/base.py +280 -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 +132 -91
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +3 -1
- mlrun/model_monitoring/db/__init__.py +2 -0
- mlrun/model_monitoring/db/stores/__init__.py +0 -2
- mlrun/model_monitoring/db/stores/base/store.py +22 -37
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +43 -21
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +39 -8
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +27 -7
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +5 -0
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +246 -224
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +232 -216
- mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
- mlrun/model_monitoring/db/tsdb/base.py +316 -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 +401 -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 +658 -0
- mlrun/model_monitoring/evidently_application.py +6 -118
- mlrun/model_monitoring/helpers.py +63 -1
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/stream_processing.py +57 -216
- mlrun/model_monitoring/writer.py +134 -124
- mlrun/package/__init__.py +13 -1
- mlrun/package/packagers/__init__.py +6 -1
- mlrun/package/utils/_formatter.py +2 -2
- mlrun/platforms/__init__.py +10 -9
- mlrun/platforms/iguazio.py +21 -202
- mlrun/projects/operations.py +24 -12
- mlrun/projects/pipelines.py +79 -102
- mlrun/projects/project.py +271 -103
- mlrun/render.py +15 -14
- mlrun/run.py +16 -46
- mlrun/runtimes/__init__.py +6 -3
- mlrun/runtimes/base.py +14 -7
- mlrun/runtimes/daskjob.py +1 -0
- mlrun/runtimes/databricks_job/databricks_runtime.py +1 -0
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +0 -28
- mlrun/runtimes/kubejob.py +2 -1
- mlrun/runtimes/local.py +12 -3
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/runtimes/nuclio/api_gateway.py +194 -84
- mlrun/runtimes/nuclio/application/application.py +170 -8
- mlrun/runtimes/nuclio/function.py +39 -49
- mlrun/runtimes/pod.py +16 -36
- mlrun/runtimes/remotesparkjob.py +9 -3
- mlrun/runtimes/sparkjob/spark3job.py +1 -1
- mlrun/runtimes/utils.py +6 -45
- mlrun/serving/__init__.py +8 -1
- mlrun/serving/server.py +2 -1
- mlrun/serving/states.py +51 -8
- mlrun/serving/utils.py +19 -11
- mlrun/serving/v2_serving.py +5 -1
- mlrun/track/tracker.py +2 -1
- mlrun/utils/async_http.py +25 -5
- mlrun/utils/helpers.py +157 -83
- mlrun/utils/logger.py +39 -7
- mlrun/utils/notifications/notification/__init__.py +14 -9
- mlrun/utils/notifications/notification/base.py +1 -1
- mlrun/utils/notifications/notification/slack.py +34 -7
- mlrun/utils/notifications/notification/webhook.py +1 -1
- mlrun/utils/notifications/notification_pusher.py +147 -16
- mlrun/utils/regex.py +9 -0
- mlrun/utils/v3io_clients.py +0 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/METADATA +14 -6
- {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/RECORD +158 -138
- mlrun/kfpops.py +0 -865
- mlrun/platforms/other.py +0 -305
- {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/WHEEL +0 -0
- {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/top_level.txt +0 -0
|
@@ -457,6 +457,7 @@ class MonitoringApplicationController:
|
|
|
457
457
|
)
|
|
458
458
|
|
|
459
459
|
for start_infer_time, end_infer_time in batch_window.get_intervals():
|
|
460
|
+
# start - TODO : delete in 1.9.0 (V1 app deprecation)
|
|
460
461
|
try:
|
|
461
462
|
# Get application sample data
|
|
462
463
|
offline_response = cls._get_sample_df(
|
|
@@ -504,7 +505,7 @@ class MonitoringApplicationController:
|
|
|
504
505
|
current_stats = calculate_inputs_statistics(
|
|
505
506
|
sample_set_statistics=feature_stats, inputs=df
|
|
506
507
|
)
|
|
507
|
-
|
|
508
|
+
# end - TODO : delete in 1.9.0 (V1 app deprecation)
|
|
508
509
|
cls._push_to_applications(
|
|
509
510
|
current_stats=current_stats,
|
|
510
511
|
feature_stats=feature_stats,
|
|
@@ -613,6 +614,7 @@ class MonitoringApplicationController:
|
|
|
613
614
|
project=project,
|
|
614
615
|
function_name=mm_constants.MonitoringFunctionNames.WRITER,
|
|
615
616
|
),
|
|
617
|
+
mm_constants.ApplicationEvent.MLRUN_CONTEXT: {}, # TODO : for future use by ad-hoc batch infer
|
|
616
618
|
}
|
|
617
619
|
for app_name in applications_names:
|
|
618
620
|
data.update({mm_constants.ApplicationEvent.APPLICATION_NAME: app_name})
|
|
@@ -12,8 +12,6 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
16
|
-
|
|
17
15
|
import enum
|
|
18
16
|
import typing
|
|
19
17
|
import warnings
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
import typing
|
|
16
16
|
from abc import ABC, abstractmethod
|
|
17
17
|
|
|
18
|
+
import mlrun.common.schemas.model_monitoring as mm_schemas
|
|
19
|
+
|
|
18
20
|
|
|
19
21
|
class StoreBase(ABC):
|
|
20
22
|
"""
|
|
@@ -62,12 +64,10 @@ class StoreBase(ABC):
|
|
|
62
64
|
pass
|
|
63
65
|
|
|
64
66
|
@abstractmethod
|
|
65
|
-
def delete_model_endpoints_resources(self
|
|
67
|
+
def delete_model_endpoints_resources(self):
|
|
66
68
|
"""
|
|
67
69
|
Delete all model endpoints resources.
|
|
68
70
|
|
|
69
|
-
:param endpoints: A list of model endpoints flattened dictionaries.
|
|
70
|
-
|
|
71
71
|
"""
|
|
72
72
|
pass
|
|
73
73
|
|
|
@@ -112,47 +112,19 @@ class StoreBase(ABC):
|
|
|
112
112
|
pass
|
|
113
113
|
|
|
114
114
|
@abstractmethod
|
|
115
|
-
def
|
|
115
|
+
def write_application_event(
|
|
116
116
|
self,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
end: str = "now",
|
|
121
|
-
access_key: str = None,
|
|
122
|
-
) -> dict[str, list[tuple[str, float]]]:
|
|
123
|
-
"""
|
|
124
|
-
Getting metrics from the time series DB. There are pre-defined metrics for model endpoints such as
|
|
125
|
-
`predictions_per_second` and `latency_avg_5m` but also custom metrics defined by the user.
|
|
126
|
-
|
|
127
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
128
|
-
:param metrics: A list of real-time metrics to return for the model endpoint.
|
|
129
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
130
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
131
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
132
|
-
earliest time.
|
|
133
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339
|
|
134
|
-
time, a Unix timestamp in milliseconds, a relative time (`'now'` or
|
|
135
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` = days), or 0 for the
|
|
136
|
-
earliest time.
|
|
137
|
-
:param access_key: V3IO access key that will be used for generating Frames client object. If not
|
|
138
|
-
provided, the access key will be retrieved from the environment variables.
|
|
139
|
-
|
|
140
|
-
:return: A dictionary of metrics in which the key is a metric name and the value is a list of tuples that
|
|
141
|
-
includes timestamps and the values.
|
|
142
|
-
"""
|
|
143
|
-
|
|
144
|
-
pass
|
|
145
|
-
|
|
146
|
-
@abstractmethod
|
|
147
|
-
def write_application_result(self, event: dict[str, typing.Any]):
|
|
117
|
+
event: dict[str, typing.Any],
|
|
118
|
+
kind: mm_schemas.WriterEventKind = mm_schemas.WriterEventKind.RESULT,
|
|
119
|
+
) -> None:
|
|
148
120
|
"""
|
|
149
|
-
Write a new
|
|
121
|
+
Write a new event in the target table.
|
|
150
122
|
|
|
151
123
|
:param event: An event dictionary that represents the application result, should be corresponded to the
|
|
152
124
|
schema defined in the :py:class:`~mlrun.common.schemas.model_monitoring.constants.WriterEvent`
|
|
153
125
|
object.
|
|
126
|
+
:param kind: The type of the event, can be either "result" or "metric".
|
|
154
127
|
"""
|
|
155
|
-
pass
|
|
156
128
|
|
|
157
129
|
@abstractmethod
|
|
158
130
|
def get_last_analyzed(self, endpoint_id: str, application_name: str) -> int:
|
|
@@ -184,3 +156,16 @@ class StoreBase(ABC):
|
|
|
184
156
|
|
|
185
157
|
"""
|
|
186
158
|
pass
|
|
159
|
+
|
|
160
|
+
@abstractmethod
|
|
161
|
+
def get_model_endpoint_metrics(
|
|
162
|
+
self, endpoint_id: str, type: mm_schemas.ModelEndpointMonitoringMetricType
|
|
163
|
+
) -> list[mm_schemas.ModelEndpointMonitoringMetric]:
|
|
164
|
+
"""
|
|
165
|
+
Get the model monitoring results and metrics of the requested model endpoint.
|
|
166
|
+
|
|
167
|
+
:param: endpoint_id: The model endpoint identifier.
|
|
168
|
+
:param: type: The type of the requested metrics ("result" or "metric").
|
|
169
|
+
|
|
170
|
+
:return: A list of the available metrics.
|
|
171
|
+
"""
|
|
@@ -12,38 +12,60 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from functools import partial
|
|
16
|
+
from typing import Optional, TypeVar, Union
|
|
16
17
|
|
|
18
|
+
from .mysql import ApplicationMetricsTable as MySQLApplicationMetricsTable
|
|
17
19
|
from .mysql import ApplicationResultTable as MySQLApplicationResultTable
|
|
18
20
|
from .mysql import ModelEndpointsTable as MySQLModelEndpointsTable
|
|
19
21
|
from .mysql import MonitoringSchedulesTable as MySQLMonitoringSchedulesTable
|
|
22
|
+
from .sqlite import ApplicationMetricsTable as SQLiteApplicationMetricsTable
|
|
20
23
|
from .sqlite import ApplicationResultTable as SQLiteApplicationResultTable
|
|
21
24
|
from .sqlite import ModelEndpointsTable as SQLiteModelEndpointsTable
|
|
22
25
|
from .sqlite import MonitoringSchedulesTable as SQLiteMonitoringSchedulesTable
|
|
23
26
|
|
|
27
|
+
MySQLTableType = TypeVar("MySQLTableType")
|
|
28
|
+
SQLiteTableType = TypeVar("SQLiteTableType")
|
|
24
29
|
|
|
25
|
-
|
|
26
|
-
connection_string: Optional[str] = None,
|
|
27
|
-
) -> Union[type[MySQLModelEndpointsTable], type[SQLiteModelEndpointsTable]]:
|
|
28
|
-
"""Return ModelEndpointsTable based on the provided connection string"""
|
|
29
|
-
if connection_string and "mysql:" in connection_string:
|
|
30
|
-
return MySQLModelEndpointsTable
|
|
31
|
-
return SQLiteModelEndpointsTable
|
|
30
|
+
_MYSQL_SCHEME = "mysql:"
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
def
|
|
33
|
+
def _get_sql_table(
|
|
34
|
+
*,
|
|
35
|
+
mysql_table: MySQLTableType,
|
|
36
|
+
sqlite_table: SQLiteTableType,
|
|
35
37
|
connection_string: Optional[str] = None,
|
|
36
|
-
) -> Union[
|
|
37
|
-
"""
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
) -> Union[MySQLTableType, SQLiteTableType]:
|
|
39
|
+
"""
|
|
40
|
+
Return a SQLAlchemy table for MySQL or SQLite according to the connection string.
|
|
41
|
+
Note: this function should not be directly used in other modules.
|
|
42
|
+
"""
|
|
43
|
+
if connection_string and _MYSQL_SCHEME in connection_string:
|
|
44
|
+
return mysql_table
|
|
45
|
+
return sqlite_table
|
|
41
46
|
|
|
42
47
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
_get_model_endpoints_table = partial(
|
|
49
|
+
_get_sql_table,
|
|
50
|
+
mysql_table=MySQLModelEndpointsTable,
|
|
51
|
+
sqlite_table=SQLiteModelEndpointsTable,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_get_application_result_table = partial(
|
|
56
|
+
_get_sql_table,
|
|
57
|
+
mysql_table=MySQLApplicationResultTable,
|
|
58
|
+
sqlite_table=SQLiteApplicationResultTable,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
_get_application_metrics_table = partial(
|
|
62
|
+
_get_sql_table,
|
|
63
|
+
mysql_table=MySQLApplicationMetricsTable,
|
|
64
|
+
sqlite_table=SQLiteApplicationMetricsTable,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
_get_monitoring_schedules_table = partial(
|
|
68
|
+
_get_sql_table,
|
|
69
|
+
mysql_table=MySQLMonitoringSchedulesTable,
|
|
70
|
+
sqlite_table=SQLiteMonitoringSchedulesTable,
|
|
71
|
+
)
|
|
@@ -24,6 +24,8 @@ from sqlalchemy import (
|
|
|
24
24
|
from mlrun.common.schemas.model_monitoring import (
|
|
25
25
|
EventFieldType,
|
|
26
26
|
FileTargetKind,
|
|
27
|
+
MetricData,
|
|
28
|
+
ResultData,
|
|
27
29
|
SchedulingKeys,
|
|
28
30
|
WriterEvent,
|
|
29
31
|
)
|
|
@@ -88,11 +90,11 @@ class ModelEndpointsBaseTable(BaseModel):
|
|
|
88
90
|
metrics = Column(EventFieldType.METRICS, Text)
|
|
89
91
|
first_request = Column(
|
|
90
92
|
EventFieldType.FIRST_REQUEST,
|
|
91
|
-
TIMESTAMP,
|
|
93
|
+
TIMESTAMP(timezone=True),
|
|
92
94
|
)
|
|
93
95
|
last_request = Column(
|
|
94
96
|
EventFieldType.LAST_REQUEST,
|
|
95
|
-
TIMESTAMP,
|
|
97
|
+
TIMESTAMP(timezone=True),
|
|
96
98
|
)
|
|
97
99
|
|
|
98
100
|
|
|
@@ -114,7 +116,7 @@ class ApplicationResultBaseTable(BaseModel):
|
|
|
114
116
|
)
|
|
115
117
|
|
|
116
118
|
result_name = Column(
|
|
117
|
-
|
|
119
|
+
ResultData.RESULT_NAME,
|
|
118
120
|
String(40),
|
|
119
121
|
)
|
|
120
122
|
|
|
@@ -127,11 +129,40 @@ class ApplicationResultBaseTable(BaseModel):
|
|
|
127
129
|
TIMESTAMP(timezone=True),
|
|
128
130
|
)
|
|
129
131
|
|
|
130
|
-
result_status = Column(
|
|
131
|
-
result_kind = Column(
|
|
132
|
-
result_value = Column(
|
|
133
|
-
result_extra_data = Column(
|
|
134
|
-
current_stats = Column(
|
|
132
|
+
result_status = Column(ResultData.RESULT_STATUS, String(10))
|
|
133
|
+
result_kind = Column(ResultData.RESULT_KIND, String(40))
|
|
134
|
+
result_value = Column(ResultData.RESULT_VALUE, Float)
|
|
135
|
+
result_extra_data = Column(ResultData.RESULT_EXTRA_DATA, Text)
|
|
136
|
+
current_stats = Column(ResultData.CURRENT_STATS, Text)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class ApplicationMetricsBaseTable(BaseModel):
|
|
140
|
+
__tablename__ = FileTargetKind.APP_METRICS
|
|
141
|
+
|
|
142
|
+
uid = Column(EventFieldType.UID, String(120), primary_key=True)
|
|
143
|
+
application_name = Column(
|
|
144
|
+
WriterEvent.APPLICATION_NAME,
|
|
145
|
+
String(40),
|
|
146
|
+
nullable=True,
|
|
147
|
+
)
|
|
148
|
+
endpoint_id = Column(
|
|
149
|
+
WriterEvent.ENDPOINT_ID,
|
|
150
|
+
String(40),
|
|
151
|
+
nullable=True,
|
|
152
|
+
)
|
|
153
|
+
start_infer_time = Column(
|
|
154
|
+
WriterEvent.START_INFER_TIME,
|
|
155
|
+
TIMESTAMP(timezone=True),
|
|
156
|
+
)
|
|
157
|
+
end_infer_time = Column(
|
|
158
|
+
WriterEvent.END_INFER_TIME,
|
|
159
|
+
TIMESTAMP(timezone=True),
|
|
160
|
+
)
|
|
161
|
+
metric_name = Column(
|
|
162
|
+
MetricData.METRIC_NAME,
|
|
163
|
+
String(40),
|
|
164
|
+
)
|
|
165
|
+
metric_value = Column(MetricData.METRIC_VALUE, Float)
|
|
135
166
|
|
|
136
167
|
|
|
137
168
|
class MonitoringSchedulesBaseTable(BaseModel):
|
|
@@ -22,6 +22,7 @@ from mlrun.common.schemas.model_monitoring import (
|
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
from .base import (
|
|
25
|
+
ApplicationMetricsBaseTable,
|
|
25
26
|
ApplicationResultBaseTable,
|
|
26
27
|
ModelEndpointsBaseTable,
|
|
27
28
|
MonitoringSchedulesBaseTable,
|
|
@@ -33,35 +34,54 @@ Base = declarative_base()
|
|
|
33
34
|
class ModelEndpointsTable(Base, ModelEndpointsBaseTable):
|
|
34
35
|
first_request = Column(
|
|
35
36
|
EventFieldType.FIRST_REQUEST,
|
|
36
|
-
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3),
|
|
37
|
+
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3, timezone=True),
|
|
37
38
|
)
|
|
38
39
|
last_request = Column(
|
|
39
40
|
EventFieldType.LAST_REQUEST,
|
|
40
|
-
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3),
|
|
41
|
+
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3, timezone=True),
|
|
41
42
|
)
|
|
42
43
|
|
|
43
44
|
|
|
44
|
-
class
|
|
45
|
+
class _ApplicationResultOrMetric:
|
|
46
|
+
"""
|
|
47
|
+
This class sets common columns of `ApplicationResultTable` and `ApplicationMetricsTable`
|
|
48
|
+
to the correct values in MySQL.
|
|
49
|
+
Note: This class must come before the base tables in the inheritance order to override
|
|
50
|
+
the relevant columns.
|
|
51
|
+
"""
|
|
52
|
+
|
|
45
53
|
start_infer_time = Column(
|
|
46
54
|
WriterEvent.START_INFER_TIME,
|
|
47
|
-
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3),
|
|
55
|
+
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3, timezone=True),
|
|
48
56
|
)
|
|
49
57
|
end_infer_time = Column(
|
|
50
58
|
WriterEvent.END_INFER_TIME,
|
|
51
|
-
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3),
|
|
59
|
+
sqlalchemy.dialects.mysql.TIMESTAMP(fsp=3, timezone=True),
|
|
52
60
|
)
|
|
53
61
|
|
|
54
62
|
@declared_attr
|
|
55
|
-
def endpoint_id(
|
|
63
|
+
def endpoint_id(self):
|
|
56
64
|
return Column(
|
|
57
65
|
String(40),
|
|
58
66
|
ForeignKey(f"{EventFieldType.MODEL_ENDPOINTS}.{EventFieldType.UID}"),
|
|
59
67
|
)
|
|
60
68
|
|
|
61
69
|
|
|
70
|
+
class ApplicationResultTable(
|
|
71
|
+
Base, _ApplicationResultOrMetric, ApplicationResultBaseTable
|
|
72
|
+
):
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class ApplicationMetricsTable(
|
|
77
|
+
Base, _ApplicationResultOrMetric, ApplicationMetricsBaseTable
|
|
78
|
+
):
|
|
79
|
+
pass
|
|
80
|
+
|
|
81
|
+
|
|
62
82
|
class MonitoringSchedulesTable(Base, MonitoringSchedulesBaseTable):
|
|
63
83
|
@declared_attr
|
|
64
|
-
def endpoint_id(
|
|
84
|
+
def endpoint_id(self):
|
|
65
85
|
return Column(
|
|
66
86
|
String(40),
|
|
67
87
|
ForeignKey(f"{EventFieldType.MODEL_ENDPOINTS}.{EventFieldType.UID}"),
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
from sqlalchemy.ext.declarative import declarative_base
|
|
16
16
|
|
|
17
17
|
from .base import (
|
|
18
|
+
ApplicationMetricsBaseTable,
|
|
18
19
|
ApplicationResultBaseTable,
|
|
19
20
|
ModelEndpointsBaseTable,
|
|
20
21
|
MonitoringSchedulesBaseTable,
|
|
@@ -31,5 +32,9 @@ class ApplicationResultTable(Base, ApplicationResultBaseTable):
|
|
|
31
32
|
pass
|
|
32
33
|
|
|
33
34
|
|
|
35
|
+
class ApplicationMetricsTable(Base, ApplicationMetricsBaseTable):
|
|
36
|
+
pass
|
|
37
|
+
|
|
38
|
+
|
|
34
39
|
class MonitoringSchedulesTable(Base, MonitoringSchedulesBaseTable):
|
|
35
40
|
pass
|