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.

Files changed (160) hide show
  1. mlrun/__init__.py +10 -1
  2. mlrun/__main__.py +23 -111
  3. mlrun/alerts/__init__.py +15 -0
  4. mlrun/alerts/alert.py +169 -0
  5. mlrun/api/schemas/__init__.py +4 -3
  6. mlrun/artifacts/__init__.py +8 -3
  7. mlrun/artifacts/base.py +36 -253
  8. mlrun/artifacts/dataset.py +9 -190
  9. mlrun/artifacts/manager.py +46 -42
  10. mlrun/artifacts/model.py +9 -141
  11. mlrun/artifacts/plots.py +14 -375
  12. mlrun/common/constants.py +65 -3
  13. mlrun/common/formatters/__init__.py +19 -0
  14. mlrun/{runtimes/mpijob/v1alpha1.py → common/formatters/artifact.py} +6 -14
  15. mlrun/common/formatters/base.py +113 -0
  16. mlrun/common/formatters/function.py +46 -0
  17. mlrun/common/formatters/pipeline.py +53 -0
  18. mlrun/common/formatters/project.py +51 -0
  19. mlrun/{runtimes → common/runtimes}/constants.py +32 -4
  20. mlrun/common/schemas/__init__.py +10 -5
  21. mlrun/common/schemas/alert.py +92 -11
  22. mlrun/common/schemas/api_gateway.py +56 -0
  23. mlrun/common/schemas/artifact.py +15 -5
  24. mlrun/common/schemas/auth.py +2 -0
  25. mlrun/common/schemas/client_spec.py +1 -0
  26. mlrun/common/schemas/frontend_spec.py +1 -0
  27. mlrun/common/schemas/function.py +4 -0
  28. mlrun/common/schemas/model_monitoring/__init__.py +15 -3
  29. mlrun/common/schemas/model_monitoring/constants.py +58 -7
  30. mlrun/common/schemas/model_monitoring/grafana.py +9 -5
  31. mlrun/common/schemas/model_monitoring/model_endpoints.py +86 -2
  32. mlrun/common/schemas/pipeline.py +0 -9
  33. mlrun/common/schemas/project.py +5 -11
  34. mlrun/common/types.py +1 -0
  35. mlrun/config.py +30 -9
  36. mlrun/data_types/to_pandas.py +9 -9
  37. mlrun/datastore/base.py +41 -9
  38. mlrun/datastore/datastore.py +6 -2
  39. mlrun/datastore/datastore_profile.py +56 -4
  40. mlrun/datastore/inmem.py +2 -2
  41. mlrun/datastore/redis.py +2 -2
  42. mlrun/datastore/s3.py +5 -0
  43. mlrun/datastore/sources.py +147 -7
  44. mlrun/datastore/store_resources.py +7 -7
  45. mlrun/datastore/targets.py +110 -42
  46. mlrun/datastore/utils.py +42 -0
  47. mlrun/db/base.py +54 -10
  48. mlrun/db/httpdb.py +282 -79
  49. mlrun/db/nopdb.py +52 -10
  50. mlrun/errors.py +11 -0
  51. mlrun/execution.py +26 -9
  52. mlrun/feature_store/__init__.py +0 -2
  53. mlrun/feature_store/api.py +12 -47
  54. mlrun/feature_store/feature_set.py +9 -0
  55. mlrun/feature_store/feature_vector.py +8 -0
  56. mlrun/feature_store/ingestion.py +7 -6
  57. mlrun/feature_store/retrieval/base.py +9 -4
  58. mlrun/feature_store/retrieval/conversion.py +9 -9
  59. mlrun/feature_store/retrieval/dask_merger.py +2 -0
  60. mlrun/feature_store/retrieval/job.py +9 -3
  61. mlrun/feature_store/retrieval/local_merger.py +2 -0
  62. mlrun/feature_store/retrieval/spark_merger.py +16 -0
  63. mlrun/frameworks/__init__.py +6 -0
  64. mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +7 -12
  65. mlrun/frameworks/parallel_coordinates.py +2 -1
  66. mlrun/frameworks/tf_keras/__init__.py +4 -1
  67. mlrun/k8s_utils.py +10 -11
  68. mlrun/launcher/base.py +4 -3
  69. mlrun/launcher/client.py +5 -3
  70. mlrun/launcher/local.py +12 -2
  71. mlrun/launcher/remote.py +9 -2
  72. mlrun/lists.py +6 -2
  73. mlrun/model.py +47 -21
  74. mlrun/model_monitoring/__init__.py +1 -1
  75. mlrun/model_monitoring/api.py +42 -18
  76. mlrun/model_monitoring/application.py +5 -305
  77. mlrun/model_monitoring/applications/__init__.py +11 -0
  78. mlrun/model_monitoring/applications/_application_steps.py +157 -0
  79. mlrun/model_monitoring/applications/base.py +280 -0
  80. mlrun/model_monitoring/applications/context.py +214 -0
  81. mlrun/model_monitoring/applications/evidently_base.py +211 -0
  82. mlrun/model_monitoring/applications/histogram_data_drift.py +132 -91
  83. mlrun/model_monitoring/applications/results.py +99 -0
  84. mlrun/model_monitoring/controller.py +3 -1
  85. mlrun/model_monitoring/db/__init__.py +2 -0
  86. mlrun/model_monitoring/db/stores/__init__.py +0 -2
  87. mlrun/model_monitoring/db/stores/base/store.py +22 -37
  88. mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +43 -21
  89. mlrun/model_monitoring/db/stores/sqldb/models/base.py +39 -8
  90. mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +27 -7
  91. mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +5 -0
  92. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +246 -224
  93. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +232 -216
  94. mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
  95. mlrun/model_monitoring/db/tsdb/base.py +316 -0
  96. mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
  97. mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
  98. mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +240 -0
  99. mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
  100. mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +401 -0
  101. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  102. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  103. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +658 -0
  104. mlrun/model_monitoring/evidently_application.py +6 -118
  105. mlrun/model_monitoring/helpers.py +63 -1
  106. mlrun/model_monitoring/model_endpoint.py +3 -2
  107. mlrun/model_monitoring/stream_processing.py +57 -216
  108. mlrun/model_monitoring/writer.py +134 -124
  109. mlrun/package/__init__.py +13 -1
  110. mlrun/package/packagers/__init__.py +6 -1
  111. mlrun/package/utils/_formatter.py +2 -2
  112. mlrun/platforms/__init__.py +10 -9
  113. mlrun/platforms/iguazio.py +21 -202
  114. mlrun/projects/operations.py +24 -12
  115. mlrun/projects/pipelines.py +79 -102
  116. mlrun/projects/project.py +271 -103
  117. mlrun/render.py +15 -14
  118. mlrun/run.py +16 -46
  119. mlrun/runtimes/__init__.py +6 -3
  120. mlrun/runtimes/base.py +14 -7
  121. mlrun/runtimes/daskjob.py +1 -0
  122. mlrun/runtimes/databricks_job/databricks_runtime.py +1 -0
  123. mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
  124. mlrun/runtimes/funcdoc.py +0 -28
  125. mlrun/runtimes/kubejob.py +2 -1
  126. mlrun/runtimes/local.py +12 -3
  127. mlrun/runtimes/mpijob/__init__.py +0 -20
  128. mlrun/runtimes/mpijob/v1.py +1 -1
  129. mlrun/runtimes/nuclio/api_gateway.py +194 -84
  130. mlrun/runtimes/nuclio/application/application.py +170 -8
  131. mlrun/runtimes/nuclio/function.py +39 -49
  132. mlrun/runtimes/pod.py +16 -36
  133. mlrun/runtimes/remotesparkjob.py +9 -3
  134. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  135. mlrun/runtimes/utils.py +6 -45
  136. mlrun/serving/__init__.py +8 -1
  137. mlrun/serving/server.py +2 -1
  138. mlrun/serving/states.py +51 -8
  139. mlrun/serving/utils.py +19 -11
  140. mlrun/serving/v2_serving.py +5 -1
  141. mlrun/track/tracker.py +2 -1
  142. mlrun/utils/async_http.py +25 -5
  143. mlrun/utils/helpers.py +157 -83
  144. mlrun/utils/logger.py +39 -7
  145. mlrun/utils/notifications/notification/__init__.py +14 -9
  146. mlrun/utils/notifications/notification/base.py +1 -1
  147. mlrun/utils/notifications/notification/slack.py +34 -7
  148. mlrun/utils/notifications/notification/webhook.py +1 -1
  149. mlrun/utils/notifications/notification_pusher.py +147 -16
  150. mlrun/utils/regex.py +9 -0
  151. mlrun/utils/v3io_clients.py +0 -1
  152. mlrun/utils/version/version.json +2 -2
  153. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/METADATA +14 -6
  154. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/RECORD +158 -138
  155. mlrun/kfpops.py +0 -865
  156. mlrun/platforms/other.py +0 -305
  157. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/LICENSE +0 -0
  158. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/WHEEL +0 -0
  159. {mlrun-1.7.0rc14.dist-info → mlrun-1.7.0rc22.dist-info}/entry_points.txt +0 -0
  160. {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})
@@ -14,3 +14,5 @@
14
14
 
15
15
  from .stores import ObjectStoreFactory, get_store_object
16
16
  from .stores.base import StoreBase
17
+ from .tsdb import get_tsdb_connector
18
+ from .tsdb.base import TSDBConnector
@@ -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, endpoints: list[dict[str, typing.Any]]):
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 get_endpoint_real_time_metrics(
115
+ def write_application_event(
116
116
  self,
117
- endpoint_id: str,
118
- metrics: list[str],
119
- start: str = "now-1h",
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 application result event in the target table.
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 typing import Optional, Union
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
- def _get_model_endpoints_table(
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 _get_application_result_table(
33
+ def _get_sql_table(
34
+ *,
35
+ mysql_table: MySQLTableType,
36
+ sqlite_table: SQLiteTableType,
35
37
  connection_string: Optional[str] = None,
36
- ) -> Union[type[MySQLApplicationResultTable], type[SQLiteApplicationResultTable]]:
37
- """Return ModelEndpointsTable based on the provided connection string"""
38
- if connection_string and "mysql:" in connection_string:
39
- return MySQLApplicationResultTable
40
- return SQLiteApplicationResultTable
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
- def _get_monitoring_schedules_table(
44
- connection_string: Optional[str] = None,
45
- ) -> Union[type[MySQLMonitoringSchedulesTable], type[SQLiteMonitoringSchedulesTable]]:
46
- """Return ModelEndpointsTable based on the provided connection string"""
47
- if connection_string and "mysql:" in connection_string:
48
- return MySQLMonitoringSchedulesTable
49
- return SQLiteMonitoringSchedulesTable
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
- WriterEvent.RESULT_NAME,
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(WriterEvent.RESULT_STATUS, String(10))
131
- result_kind = Column(WriterEvent.RESULT_KIND, String(40))
132
- result_value = Column(WriterEvent.RESULT_VALUE, Float)
133
- result_extra_data = Column(WriterEvent.RESULT_EXTRA_DATA, Text)
134
- current_stats = Column(WriterEvent.CURRENT_STATS, Text)
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 ApplicationResultTable(Base, ApplicationResultBaseTable):
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(cls):
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(cls):
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