mlrun 1.8.0rc5__py3-none-any.whl → 1.8.0rc9__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 +1 -0
- mlrun/artifacts/__init__.py +1 -1
- mlrun/artifacts/base.py +21 -1
- mlrun/artifacts/document.py +62 -39
- mlrun/artifacts/manager.py +12 -5
- mlrun/common/constants.py +1 -0
- mlrun/common/model_monitoring/__init__.py +0 -2
- mlrun/common/model_monitoring/helpers.py +0 -28
- mlrun/common/schemas/__init__.py +2 -4
- mlrun/common/schemas/alert.py +77 -1
- mlrun/common/schemas/client_spec.py +0 -1
- mlrun/common/schemas/model_monitoring/__init__.py +0 -6
- mlrun/common/schemas/model_monitoring/constants.py +11 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +77 -149
- mlrun/common/schemas/notification.py +6 -0
- mlrun/common/schemas/project.py +3 -0
- mlrun/config.py +2 -3
- mlrun/datastore/datastore_profile.py +57 -17
- mlrun/datastore/sources.py +1 -2
- mlrun/datastore/store_resources.py +7 -2
- mlrun/datastore/vectorstore.py +99 -62
- mlrun/db/base.py +34 -20
- mlrun/db/httpdb.py +249 -163
- mlrun/db/nopdb.py +40 -17
- mlrun/execution.py +14 -7
- mlrun/feature_store/api.py +1 -0
- mlrun/model.py +3 -0
- mlrun/model_monitoring/__init__.py +3 -2
- mlrun/model_monitoring/api.py +64 -53
- mlrun/model_monitoring/applications/_application_steps.py +3 -1
- mlrun/model_monitoring/applications/base.py +115 -15
- mlrun/model_monitoring/applications/context.py +42 -24
- mlrun/model_monitoring/applications/histogram_data_drift.py +1 -1
- mlrun/model_monitoring/controller.py +43 -37
- mlrun/model_monitoring/db/__init__.py +0 -2
- mlrun/model_monitoring/db/tsdb/base.py +2 -1
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +2 -1
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +43 -0
- mlrun/model_monitoring/helpers.py +78 -66
- mlrun/model_monitoring/stream_processing.py +83 -270
- mlrun/model_monitoring/writer.py +1 -10
- mlrun/projects/pipelines.py +37 -1
- mlrun/projects/project.py +173 -70
- mlrun/run.py +40 -0
- mlrun/runtimes/nuclio/function.py +7 -6
- mlrun/runtimes/nuclio/serving.py +9 -4
- mlrun/serving/routers.py +158 -145
- mlrun/serving/server.py +6 -0
- mlrun/serving/states.py +21 -7
- mlrun/serving/v2_serving.py +94 -68
- mlrun/utils/helpers.py +23 -33
- mlrun/utils/notifications/notification/mail.py +17 -6
- mlrun/utils/notifications/notification_pusher.py +9 -5
- mlrun/utils/regex.py +8 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.8.0rc5.dist-info → mlrun-1.8.0rc9.dist-info}/METADATA +2 -2
- {mlrun-1.8.0rc5.dist-info → mlrun-1.8.0rc9.dist-info}/RECORD +61 -74
- mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +0 -149
- mlrun/model_monitoring/db/stores/__init__.py +0 -136
- mlrun/model_monitoring/db/stores/base/__init__.py +0 -15
- mlrun/model_monitoring/db/stores/base/store.py +0 -154
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -46
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -93
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -47
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -25
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -408
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -464
- mlrun/model_monitoring/model_endpoint.py +0 -120
- {mlrun-1.8.0rc5.dist-info → mlrun-1.8.0rc9.dist-info}/LICENSE +0 -0
- {mlrun-1.8.0rc5.dist-info → mlrun-1.8.0rc9.dist-info}/WHEEL +0 -0
- {mlrun-1.8.0rc5.dist-info → mlrun-1.8.0rc9.dist-info}/entry_points.txt +0 -0
- {mlrun-1.8.0rc5.dist-info → mlrun-1.8.0rc9.dist-info}/top_level.txt +0 -0
|
@@ -1,408 +0,0 @@
|
|
|
1
|
-
# Copyright 2024 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 datetime
|
|
16
|
-
import typing
|
|
17
|
-
|
|
18
|
-
import pandas as pd
|
|
19
|
-
import sqlalchemy
|
|
20
|
-
import sqlalchemy.exc
|
|
21
|
-
import sqlalchemy.orm
|
|
22
|
-
from sqlalchemy.engine import Engine, make_url
|
|
23
|
-
from sqlalchemy.sql.elements import BinaryExpression
|
|
24
|
-
|
|
25
|
-
import mlrun.common.model_monitoring.helpers
|
|
26
|
-
import mlrun.common.schemas.model_monitoring as mm_schemas
|
|
27
|
-
import mlrun.model_monitoring.db.stores.sqldb.models
|
|
28
|
-
import mlrun.model_monitoring.helpers
|
|
29
|
-
from mlrun.common.db.sql_session import create_session, get_engine
|
|
30
|
-
from mlrun.model_monitoring.db import StoreBase
|
|
31
|
-
from mlrun.utils import datetime_now, logger
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class SQLStoreBase(StoreBase):
|
|
35
|
-
type: typing.ClassVar[str] = mm_schemas.ModelEndpointTarget.SQL
|
|
36
|
-
"""
|
|
37
|
-
Handles the DB operations when the DB target is from type SQL. For the SQL operations, we use SQLAlchemy, a Python
|
|
38
|
-
SQL toolkit that handles the communication with the database. When using SQL for storing the model monitoring
|
|
39
|
-
data, the user needs to provide a valid connection string for the database.
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
_tables = {}
|
|
43
|
-
|
|
44
|
-
def __init__(
|
|
45
|
-
self,
|
|
46
|
-
project: str,
|
|
47
|
-
**kwargs,
|
|
48
|
-
):
|
|
49
|
-
"""
|
|
50
|
-
Initialize SQL store target object.
|
|
51
|
-
|
|
52
|
-
:param project: The name of the project.
|
|
53
|
-
"""
|
|
54
|
-
|
|
55
|
-
super().__init__(project=project)
|
|
56
|
-
|
|
57
|
-
if "store_connection_string" not in kwargs:
|
|
58
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
59
|
-
"connection_string is a required parameter for SQLStoreBase."
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
self._sql_connection_string = kwargs.get("store_connection_string")
|
|
63
|
-
self._engine = None
|
|
64
|
-
self._init_tables()
|
|
65
|
-
|
|
66
|
-
@property
|
|
67
|
-
def engine(self) -> Engine:
|
|
68
|
-
if not self._engine:
|
|
69
|
-
self._engine = get_engine(dsn=self._sql_connection_string)
|
|
70
|
-
return self._engine
|
|
71
|
-
|
|
72
|
-
def create_tables(self):
|
|
73
|
-
self._create_tables_if_not_exist()
|
|
74
|
-
|
|
75
|
-
def _init_tables(self):
|
|
76
|
-
self._init_model_endpoints_table()
|
|
77
|
-
|
|
78
|
-
def _init_model_endpoints_table(self):
|
|
79
|
-
self.model_endpoints_table = (
|
|
80
|
-
mlrun.model_monitoring.db.stores.sqldb.models._get_model_endpoints_table(
|
|
81
|
-
connection_string=self._sql_connection_string
|
|
82
|
-
)
|
|
83
|
-
)
|
|
84
|
-
self._tables[mm_schemas.EventFieldType.MODEL_ENDPOINTS] = (
|
|
85
|
-
self.model_endpoints_table
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
def _write(self, table_name: str, event: dict[str, typing.Any]) -> None:
|
|
89
|
-
"""
|
|
90
|
-
Create a new record in the SQL table.
|
|
91
|
-
|
|
92
|
-
:param table_name: Target table name.
|
|
93
|
-
:param event: Event dictionary that will be written into the DB.
|
|
94
|
-
"""
|
|
95
|
-
with self.engine.connect() as connection:
|
|
96
|
-
# Convert the result into a pandas Dataframe and write it into the database
|
|
97
|
-
event_df = pd.DataFrame([event])
|
|
98
|
-
event_df.to_sql(table_name, con=connection, index=False, if_exists="append")
|
|
99
|
-
|
|
100
|
-
def _update(
|
|
101
|
-
self,
|
|
102
|
-
attributes: dict[str, typing.Any],
|
|
103
|
-
table: sqlalchemy.orm.decl_api.DeclarativeMeta,
|
|
104
|
-
criteria: list[BinaryExpression],
|
|
105
|
-
) -> None:
|
|
106
|
-
"""
|
|
107
|
-
Update a record in the SQL table.
|
|
108
|
-
|
|
109
|
-
:param attributes: Dictionary of attributes that will be used for update the record. Note that the keys
|
|
110
|
-
of the attributes dictionary should exist in the SQL table.
|
|
111
|
-
:param table: SQLAlchemy declarative table.
|
|
112
|
-
:param criteria: A list of binary expressions that filter the query.
|
|
113
|
-
"""
|
|
114
|
-
with create_session(dsn=self._sql_connection_string) as session:
|
|
115
|
-
# Generate and commit the update session query
|
|
116
|
-
session.query(
|
|
117
|
-
table # pyright: ignore[reportOptionalCall]
|
|
118
|
-
).filter(*criteria).update(attributes, synchronize_session=False)
|
|
119
|
-
session.commit()
|
|
120
|
-
|
|
121
|
-
def _get(
|
|
122
|
-
self,
|
|
123
|
-
table: sqlalchemy.orm.decl_api.DeclarativeMeta,
|
|
124
|
-
criteria: list[BinaryExpression],
|
|
125
|
-
):
|
|
126
|
-
"""
|
|
127
|
-
Get a record from the SQL table.
|
|
128
|
-
|
|
129
|
-
param table: SQLAlchemy declarative table.
|
|
130
|
-
:param criteria: A list of binary expressions that filter the query.
|
|
131
|
-
"""
|
|
132
|
-
with create_session(dsn=self._sql_connection_string) as session:
|
|
133
|
-
logger.debug(
|
|
134
|
-
"Querying the DB",
|
|
135
|
-
table=table.__name__,
|
|
136
|
-
criteria=[str(criterion) for criterion in criteria],
|
|
137
|
-
)
|
|
138
|
-
# Generate the get query
|
|
139
|
-
return (
|
|
140
|
-
session.query(table) # pyright: ignore[reportOptionalCall]
|
|
141
|
-
.filter(*criteria)
|
|
142
|
-
.one_or_none()
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
def _delete(
|
|
146
|
-
self,
|
|
147
|
-
table: sqlalchemy.orm.decl_api.DeclarativeMeta,
|
|
148
|
-
criteria: list[BinaryExpression],
|
|
149
|
-
) -> None:
|
|
150
|
-
"""
|
|
151
|
-
Delete records from the SQL table.
|
|
152
|
-
|
|
153
|
-
param table: SQLAlchemy declarative table.
|
|
154
|
-
:param criteria: A list of binary expressions that filter the query.
|
|
155
|
-
"""
|
|
156
|
-
if not self.engine.has_table(table.__tablename__):
|
|
157
|
-
logger.debug(
|
|
158
|
-
f"Table {table.__tablename__} does not exist in the database. Skipping deletion."
|
|
159
|
-
)
|
|
160
|
-
return
|
|
161
|
-
with create_session(dsn=self._sql_connection_string) as session:
|
|
162
|
-
# Generate and commit the delete query
|
|
163
|
-
session.query(
|
|
164
|
-
table # pyright: ignore[reportOptionalCall]
|
|
165
|
-
).filter(*criteria).delete(synchronize_session=False)
|
|
166
|
-
session.commit()
|
|
167
|
-
|
|
168
|
-
def write_model_endpoint(self, endpoint: dict[str, typing.Any]):
|
|
169
|
-
"""
|
|
170
|
-
Create a new endpoint record in the SQL table. This method also creates the model endpoints table within the
|
|
171
|
-
SQL database if not exist.
|
|
172
|
-
|
|
173
|
-
:param endpoint: model endpoint dictionary that will be written into the DB.
|
|
174
|
-
"""
|
|
175
|
-
|
|
176
|
-
# Adjust timestamps fields
|
|
177
|
-
endpoint[mm_schemas.EventFieldType.FIRST_REQUEST] = (endpoint)[
|
|
178
|
-
mm_schemas.EventFieldType.LAST_REQUEST
|
|
179
|
-
] = datetime_now()
|
|
180
|
-
|
|
181
|
-
self._write(
|
|
182
|
-
table_name=mm_schemas.EventFieldType.MODEL_ENDPOINTS, event=endpoint
|
|
183
|
-
)
|
|
184
|
-
|
|
185
|
-
def update_model_endpoint(
|
|
186
|
-
self, endpoint_id: str, attributes: dict[str, typing.Any]
|
|
187
|
-
):
|
|
188
|
-
"""
|
|
189
|
-
Update a model endpoint record with a given attributes.
|
|
190
|
-
|
|
191
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
192
|
-
:param attributes: Dictionary of attributes that will be used for update the model endpoint. Note that the keys
|
|
193
|
-
of the attributes dictionary should exist in the SQL table.
|
|
194
|
-
|
|
195
|
-
"""
|
|
196
|
-
|
|
197
|
-
attributes.pop(mm_schemas.EventFieldType.ENDPOINT_ID, None)
|
|
198
|
-
|
|
199
|
-
self._update(
|
|
200
|
-
attributes=attributes,
|
|
201
|
-
table=self.model_endpoints_table,
|
|
202
|
-
criteria=[self.model_endpoints_table.uid == endpoint_id],
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
def delete_model_endpoint(self, endpoint_id: str) -> None:
|
|
206
|
-
"""
|
|
207
|
-
Deletes the SQL record of a given model endpoint id.
|
|
208
|
-
|
|
209
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
210
|
-
"""
|
|
211
|
-
# Delete the model endpoint record using sqlalchemy ORM
|
|
212
|
-
self._delete(
|
|
213
|
-
table=self.model_endpoints_table,
|
|
214
|
-
criteria=[self.model_endpoints_table.uid == endpoint_id],
|
|
215
|
-
)
|
|
216
|
-
|
|
217
|
-
def get_model_endpoint(
|
|
218
|
-
self,
|
|
219
|
-
endpoint_id: str,
|
|
220
|
-
) -> dict[str, typing.Any]:
|
|
221
|
-
"""
|
|
222
|
-
Get a single model endpoint record.
|
|
223
|
-
|
|
224
|
-
:param endpoint_id: The unique id of the model endpoint.
|
|
225
|
-
|
|
226
|
-
:return: A model endpoint record as a dictionary.
|
|
227
|
-
|
|
228
|
-
:raise MLRunNotFoundError: If the model endpoints table was not found or the model endpoint id was not found.
|
|
229
|
-
"""
|
|
230
|
-
|
|
231
|
-
# Get the model endpoint record
|
|
232
|
-
endpoint_record = self._get(
|
|
233
|
-
table=self.model_endpoints_table,
|
|
234
|
-
criteria=[self.model_endpoints_table.uid == endpoint_id],
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
if not endpoint_record:
|
|
238
|
-
raise mlrun.errors.MLRunNotFoundError(f"Endpoint {endpoint_id} not found")
|
|
239
|
-
|
|
240
|
-
# Convert the database values and the table columns into a python dictionary
|
|
241
|
-
return endpoint_record.to_dict()
|
|
242
|
-
|
|
243
|
-
def list_model_endpoints(
|
|
244
|
-
self,
|
|
245
|
-
model: typing.Optional[str] = None,
|
|
246
|
-
function: typing.Optional[str] = None,
|
|
247
|
-
labels: typing.Optional[list[str]] = None,
|
|
248
|
-
top_level: typing.Optional[bool] = None,
|
|
249
|
-
uids: typing.Optional[list] = None,
|
|
250
|
-
include_stats: typing.Optional[bool] = None,
|
|
251
|
-
) -> list[dict[str, typing.Any]]:
|
|
252
|
-
# Generate an empty model endpoints that will be filled afterwards with model endpoint dictionaries
|
|
253
|
-
endpoint_list = []
|
|
254
|
-
|
|
255
|
-
model_endpoints_table = (
|
|
256
|
-
self.model_endpoints_table.__table__ # pyright: ignore[reportAttributeAccessIssue]
|
|
257
|
-
)
|
|
258
|
-
# Get the model endpoints records using sqlalchemy ORM
|
|
259
|
-
with create_session(dsn=self._sql_connection_string) as session:
|
|
260
|
-
# Generate the list query
|
|
261
|
-
query = session.query(self.model_endpoints_table).filter_by(
|
|
262
|
-
project=self.project
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
# Apply filters
|
|
266
|
-
if model:
|
|
267
|
-
model = model if ":" in model else f"{model}:latest"
|
|
268
|
-
query = self._filter_values(
|
|
269
|
-
query=query,
|
|
270
|
-
model_endpoints_table=model_endpoints_table,
|
|
271
|
-
key_filter=mm_schemas.EventFieldType.MODEL,
|
|
272
|
-
filtered_values=[model],
|
|
273
|
-
)
|
|
274
|
-
if function:
|
|
275
|
-
function_uri = f"{self.project}/{function}"
|
|
276
|
-
query = self._filter_values(
|
|
277
|
-
query=query,
|
|
278
|
-
model_endpoints_table=model_endpoints_table,
|
|
279
|
-
key_filter=mm_schemas.EventFieldType.FUNCTION_URI,
|
|
280
|
-
filtered_values=[function_uri],
|
|
281
|
-
)
|
|
282
|
-
if uids:
|
|
283
|
-
query = self._filter_values(
|
|
284
|
-
query=query,
|
|
285
|
-
model_endpoints_table=model_endpoints_table,
|
|
286
|
-
key_filter=mm_schemas.EventFieldType.UID,
|
|
287
|
-
filtered_values=uids,
|
|
288
|
-
combined=False,
|
|
289
|
-
)
|
|
290
|
-
if top_level:
|
|
291
|
-
node_ep = str(mm_schemas.EndpointType.NODE_EP.value)
|
|
292
|
-
router_ep = str(mm_schemas.EndpointType.ROUTER.value)
|
|
293
|
-
endpoint_types = [node_ep, router_ep]
|
|
294
|
-
query = self._filter_values(
|
|
295
|
-
query=query,
|
|
296
|
-
model_endpoints_table=model_endpoints_table,
|
|
297
|
-
key_filter=mm_schemas.EventFieldType.ENDPOINT_TYPE,
|
|
298
|
-
filtered_values=endpoint_types,
|
|
299
|
-
combined=False,
|
|
300
|
-
)
|
|
301
|
-
# Convert the results from the DB into a ModelEndpoint object and append it to the model endpoints list
|
|
302
|
-
for endpoint_record in query.all():
|
|
303
|
-
endpoint_dict = endpoint_record.to_dict()
|
|
304
|
-
|
|
305
|
-
# Filter labels
|
|
306
|
-
if labels and not self._validate_labels(
|
|
307
|
-
endpoint_dict=endpoint_dict, labels=labels
|
|
308
|
-
):
|
|
309
|
-
continue
|
|
310
|
-
|
|
311
|
-
if not include_stats:
|
|
312
|
-
# Exclude these fields when listing model endpoints to avoid returning too much data (ML-6594)
|
|
313
|
-
# TODO: Remove stats from table schema (ML-7196)
|
|
314
|
-
endpoint_dict.pop(mm_schemas.EventFieldType.FEATURE_STATS)
|
|
315
|
-
endpoint_dict.pop(mm_schemas.EventFieldType.CURRENT_STATS)
|
|
316
|
-
|
|
317
|
-
endpoint_list.append(endpoint_dict)
|
|
318
|
-
|
|
319
|
-
return endpoint_list
|
|
320
|
-
|
|
321
|
-
@staticmethod
|
|
322
|
-
def _convert_to_datetime(event: dict[str, typing.Any], key: str) -> None:
|
|
323
|
-
if isinstance(event[key], str):
|
|
324
|
-
event[key] = datetime.datetime.fromisoformat(event[key])
|
|
325
|
-
event[key] = event[key].astimezone(tz=datetime.timezone.utc)
|
|
326
|
-
|
|
327
|
-
def _create_tables_if_not_exist(self):
|
|
328
|
-
self._init_tables()
|
|
329
|
-
|
|
330
|
-
for table in self._tables:
|
|
331
|
-
# Create table if not exist. The `metadata` contains the `ModelEndpointsTable`
|
|
332
|
-
db_name = make_url(self._sql_connection_string).database
|
|
333
|
-
if not self.engine.has_table(table):
|
|
334
|
-
logger.info(f"Creating table {table} on {db_name} db.")
|
|
335
|
-
self._tables[table].metadata.create_all(bind=self.engine)
|
|
336
|
-
else:
|
|
337
|
-
logger.info(f"Table {table} already exists on {db_name} db.")
|
|
338
|
-
|
|
339
|
-
@staticmethod
|
|
340
|
-
def _filter_values(
|
|
341
|
-
query: sqlalchemy.orm.query.Query,
|
|
342
|
-
model_endpoints_table: sqlalchemy.Table,
|
|
343
|
-
key_filter: str,
|
|
344
|
-
filtered_values: list,
|
|
345
|
-
combined=True,
|
|
346
|
-
) -> sqlalchemy.orm.query.Query:
|
|
347
|
-
"""Filtering the SQL query object according to the provided filters.
|
|
348
|
-
|
|
349
|
-
:param query: SQLAlchemy ORM query object. Includes the SELECT statements generated by the ORM
|
|
350
|
-
for getting the model endpoint data from the SQL table.
|
|
351
|
-
:param model_endpoints_table: SQLAlchemy table object that represents the model endpoints table.
|
|
352
|
-
:param key_filter: Key column to filter by.
|
|
353
|
-
:param filtered_values: List of values to filter the query the result.
|
|
354
|
-
:param combined: If true, then apply AND operator on the filtered values list. Otherwise, apply OR
|
|
355
|
-
operator.
|
|
356
|
-
|
|
357
|
-
return: SQLAlchemy ORM query object that represents the updated query with the provided
|
|
358
|
-
filters.
|
|
359
|
-
"""
|
|
360
|
-
|
|
361
|
-
if combined and len(filtered_values) > 1:
|
|
362
|
-
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
363
|
-
"Can't apply combined policy with multiple values"
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
if not combined:
|
|
367
|
-
return query.filter(
|
|
368
|
-
model_endpoints_table.c[key_filter].in_(filtered_values)
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
# Generating a tuple with the relevant filters
|
|
372
|
-
filter_query = []
|
|
373
|
-
for _filter in filtered_values:
|
|
374
|
-
filter_query.append(model_endpoints_table.c[key_filter] == _filter)
|
|
375
|
-
|
|
376
|
-
# Apply AND operator on the SQL query object with the filters tuple
|
|
377
|
-
return query.filter(sqlalchemy.and_(*filter_query))
|
|
378
|
-
|
|
379
|
-
def delete_model_endpoints_resources(self) -> None:
|
|
380
|
-
"""
|
|
381
|
-
Delete all the model monitoring resources of the project in the SQL tables.
|
|
382
|
-
"""
|
|
383
|
-
logger.debug(
|
|
384
|
-
"Deleting model monitoring endpoints resources from the SQL tables",
|
|
385
|
-
project=self.project,
|
|
386
|
-
)
|
|
387
|
-
endpoints = self.list_model_endpoints()
|
|
388
|
-
|
|
389
|
-
for endpoint_dict in endpoints:
|
|
390
|
-
endpoint_id = endpoint_dict[mm_schemas.EventFieldType.UID]
|
|
391
|
-
logger.debug(
|
|
392
|
-
"Deleting model endpoint resources from the SQL tables",
|
|
393
|
-
endpoint_id=endpoint_id,
|
|
394
|
-
project=self.project,
|
|
395
|
-
)
|
|
396
|
-
|
|
397
|
-
# Delete model endpoint record
|
|
398
|
-
self.delete_model_endpoint(endpoint_id=endpoint_id)
|
|
399
|
-
logger.debug(
|
|
400
|
-
"Successfully deleted model endpoint resources",
|
|
401
|
-
endpoint_id=endpoint_id,
|
|
402
|
-
project=self.project,
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
logger.debug(
|
|
406
|
-
"Successfully deleted model monitoring endpoints resources from the SQL tables",
|
|
407
|
-
project=self.project,
|
|
408
|
-
)
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
# Copyright 2024 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.
|