mlrun 1.8.0rc1__py3-none-any.whl → 1.8.0rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__init__.py +5 -7
- mlrun/__main__.py +1 -1
- mlrun/common/formatters/project.py +9 -0
- mlrun/common/schemas/__init__.py +3 -0
- mlrun/common/schemas/alert.py +31 -18
- mlrun/common/schemas/api_gateway.py +3 -3
- mlrun/common/schemas/artifact.py +7 -7
- mlrun/common/schemas/auth.py +6 -4
- mlrun/common/schemas/background_task.py +7 -7
- mlrun/common/schemas/client_spec.py +2 -2
- mlrun/common/schemas/clusterization_spec.py +2 -2
- mlrun/common/schemas/common.py +5 -5
- mlrun/common/schemas/datastore_profile.py +1 -1
- mlrun/common/schemas/feature_store.py +9 -9
- mlrun/common/schemas/frontend_spec.py +4 -4
- mlrun/common/schemas/function.py +10 -10
- mlrun/common/schemas/hub.py +1 -1
- mlrun/common/schemas/k8s.py +3 -3
- mlrun/common/schemas/memory_reports.py +3 -3
- mlrun/common/schemas/model_monitoring/grafana.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoint_v2.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoints.py +1 -1
- mlrun/common/schemas/notification.py +18 -3
- mlrun/common/schemas/object.py +1 -1
- mlrun/common/schemas/pagination.py +4 -4
- mlrun/common/schemas/partition.py +16 -1
- mlrun/common/schemas/pipeline.py +2 -2
- mlrun/common/schemas/project.py +22 -17
- mlrun/common/schemas/runs.py +2 -2
- mlrun/common/schemas/runtime_resource.py +5 -5
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/schemas/secret.py +1 -1
- mlrun/common/schemas/tag.py +3 -3
- mlrun/common/schemas/workflow.py +5 -5
- mlrun/config.py +22 -0
- mlrun/datastore/datastore_profile.py +19 -19
- mlrun/db/base.py +48 -6
- mlrun/db/httpdb.py +221 -9
- mlrun/db/nopdb.py +34 -5
- mlrun/model.py +2 -2
- mlrun/model_monitoring/applications/results.py +2 -2
- mlrun/model_monitoring/db/tsdb/base.py +2 -2
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +37 -13
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +32 -40
- mlrun/model_monitoring/helpers.py +4 -10
- mlrun/model_monitoring/stream_processing.py +14 -11
- mlrun/platforms/__init__.py +0 -13
- mlrun/projects/__init__.py +6 -1
- mlrun/projects/pipelines.py +184 -55
- mlrun/projects/project.py +95 -28
- mlrun/run.py +4 -1
- mlrun/runtimes/base.py +2 -1
- mlrun/runtimes/mounts.py +572 -0
- mlrun/runtimes/nuclio/function.py +1 -2
- mlrun/runtimes/pod.py +82 -18
- mlrun/runtimes/remotesparkjob.py +1 -1
- mlrun/runtimes/sparkjob/spark3job.py +1 -1
- mlrun/utils/helpers.py +12 -2
- mlrun/utils/logger.py +2 -2
- mlrun/utils/notifications/notification/__init__.py +22 -19
- mlrun/utils/notifications/notification/base.py +12 -12
- mlrun/utils/notifications/notification/console.py +6 -6
- mlrun/utils/notifications/notification/git.py +6 -6
- mlrun/utils/notifications/notification/ipython.py +6 -6
- mlrun/utils/notifications/notification/mail.py +149 -0
- mlrun/utils/notifications/notification/slack.py +6 -6
- mlrun/utils/notifications/notification/webhook.py +6 -6
- mlrun/utils/notifications/notification_pusher.py +20 -12
- mlrun/utils/regex.py +2 -0
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/METADATA +190 -186
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/RECORD +76 -74
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/WHEEL +1 -1
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/LICENSE +0 -0
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/entry_points.txt +0 -0
- {mlrun-1.8.0rc1.dist-info → mlrun-1.8.0rc2.dist-info}/top_level.txt +0 -0
mlrun/db/base.py
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import datetime
|
|
16
16
|
from abc import ABC, abstractmethod
|
|
17
|
-
from typing import Optional, Union
|
|
17
|
+
from typing import Literal, Optional, Union
|
|
18
18
|
|
|
19
19
|
from deprecated import deprecated
|
|
20
20
|
|
|
@@ -23,6 +23,7 @@ import mlrun.common
|
|
|
23
23
|
import mlrun.common.formatters
|
|
24
24
|
import mlrun.common.runtimes.constants
|
|
25
25
|
import mlrun.common.schemas
|
|
26
|
+
import mlrun.common.schemas.model_monitoring.model_endpoints as mm_endpoints
|
|
26
27
|
import mlrun.model_monitoring
|
|
27
28
|
|
|
28
29
|
|
|
@@ -213,11 +214,13 @@ class RunDBInterface(ABC):
|
|
|
213
214
|
def list_functions(
|
|
214
215
|
self,
|
|
215
216
|
name: Optional[str] = None,
|
|
216
|
-
project: Optional[str] =
|
|
217
|
-
tag: Optional[str] =
|
|
217
|
+
project: Optional[str] = None,
|
|
218
|
+
tag: Optional[str] = None,
|
|
219
|
+
kind: Optional[str] = None,
|
|
218
220
|
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
219
|
-
|
|
220
|
-
|
|
221
|
+
format_: mlrun.common.formatters.FunctionFormat = mlrun.common.formatters.FunctionFormat.full,
|
|
222
|
+
since: Optional[datetime.datetime] = None,
|
|
223
|
+
until: Optional[datetime.datetime] = None,
|
|
221
224
|
):
|
|
222
225
|
pass
|
|
223
226
|
|
|
@@ -306,6 +309,14 @@ class RunDBInterface(ABC):
|
|
|
306
309
|
kind="artifact", identifiers=artifact_identifiers
|
|
307
310
|
)
|
|
308
311
|
|
|
312
|
+
def get_model_endpoint_monitoring_metrics(
|
|
313
|
+
self,
|
|
314
|
+
project: str,
|
|
315
|
+
endpoint_id: str,
|
|
316
|
+
type: Literal["results", "metrics", "all"] = "all",
|
|
317
|
+
) -> list[mm_endpoints.ModelEndpointMonitoringMetric]:
|
|
318
|
+
pass
|
|
319
|
+
|
|
309
320
|
@abstractmethod
|
|
310
321
|
def delete_project(
|
|
311
322
|
self,
|
|
@@ -666,7 +677,9 @@ class RunDBInterface(ABC):
|
|
|
666
677
|
start: str = "now-1h",
|
|
667
678
|
end: str = "now",
|
|
668
679
|
metrics: Optional[list[str]] = None,
|
|
669
|
-
|
|
680
|
+
top_level: bool = False,
|
|
681
|
+
uids: Optional[list[str]] = None,
|
|
682
|
+
) -> list[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
|
|
670
683
|
pass
|
|
671
684
|
|
|
672
685
|
@abstractmethod
|
|
@@ -832,6 +845,35 @@ class RunDBInterface(ABC):
|
|
|
832
845
|
def list_alert_templates(self):
|
|
833
846
|
pass
|
|
834
847
|
|
|
848
|
+
@abstractmethod
|
|
849
|
+
def list_alert_activations(
|
|
850
|
+
self,
|
|
851
|
+
project: Optional[str] = None,
|
|
852
|
+
name: Optional[str] = None,
|
|
853
|
+
since: Optional[datetime.datetime] = None,
|
|
854
|
+
until: Optional[datetime.datetime] = None,
|
|
855
|
+
entity: Optional[str] = None,
|
|
856
|
+
severity: Optional[
|
|
857
|
+
list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
|
|
858
|
+
] = None,
|
|
859
|
+
entity_kind: Optional[
|
|
860
|
+
Union[mlrun.common.schemas.alert.EventEntityKind, str]
|
|
861
|
+
] = None,
|
|
862
|
+
event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
|
|
863
|
+
):
|
|
864
|
+
pass
|
|
865
|
+
|
|
866
|
+
@abstractmethod
|
|
867
|
+
def paginated_list_alert_activations(
|
|
868
|
+
self,
|
|
869
|
+
*args,
|
|
870
|
+
page: Optional[int] = None,
|
|
871
|
+
page_size: Optional[int] = None,
|
|
872
|
+
page_token: Optional[str] = None,
|
|
873
|
+
**kwargs,
|
|
874
|
+
):
|
|
875
|
+
pass
|
|
876
|
+
|
|
835
877
|
@abstractmethod
|
|
836
878
|
def get_builder_status(
|
|
837
879
|
self,
|
mlrun/db/httpdb.py
CHANGED
|
@@ -22,18 +22,20 @@ import warnings
|
|
|
22
22
|
from copy import deepcopy
|
|
23
23
|
from datetime import datetime, timedelta
|
|
24
24
|
from os import path, remove
|
|
25
|
-
from typing import Optional, Union
|
|
25
|
+
from typing import Literal, Optional, Union
|
|
26
26
|
from urllib.parse import urlparse
|
|
27
27
|
|
|
28
|
-
import pydantic
|
|
28
|
+
import pydantic.v1
|
|
29
29
|
import requests
|
|
30
30
|
import semver
|
|
31
|
+
from pydantic import parse_obj_as
|
|
31
32
|
|
|
32
33
|
import mlrun
|
|
33
34
|
import mlrun.common.constants
|
|
34
35
|
import mlrun.common.formatters
|
|
35
36
|
import mlrun.common.runtimes
|
|
36
37
|
import mlrun.common.schemas
|
|
38
|
+
import mlrun.common.schemas.model_monitoring.model_endpoints as mm_endpoints
|
|
37
39
|
import mlrun.common.types
|
|
38
40
|
import mlrun.model_monitoring.model_endpoint
|
|
39
41
|
import mlrun.platforms
|
|
@@ -1392,6 +1394,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1392
1394
|
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
1393
1395
|
since: Optional[datetime] = None,
|
|
1394
1396
|
until: Optional[datetime] = None,
|
|
1397
|
+
kind: Optional[str] = None,
|
|
1398
|
+
format_: mlrun.common.formatters.FunctionFormat = mlrun.common.formatters.FunctionFormat.full,
|
|
1395
1399
|
):
|
|
1396
1400
|
"""Retrieve a list of functions, filtered by specific criteria.
|
|
1397
1401
|
|
|
@@ -1407,13 +1411,17 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1407
1411
|
the specified key-value pairs or key existence.
|
|
1408
1412
|
:param since: Return functions updated after this date (as datetime object).
|
|
1409
1413
|
:param until: Return functions updated before this date (as datetime object).
|
|
1414
|
+
:param kind: Return only functions of a specific kind.
|
|
1415
|
+
:param format_: The format in which to return the functions. Default is 'full'.
|
|
1410
1416
|
:returns: List of function objects (as dictionary).
|
|
1411
1417
|
"""
|
|
1412
1418
|
functions, _ = self._list_functions(
|
|
1413
1419
|
name=name,
|
|
1414
1420
|
project=project,
|
|
1415
1421
|
tag=tag,
|
|
1422
|
+
kind=kind,
|
|
1416
1423
|
labels=labels,
|
|
1424
|
+
format_=format_,
|
|
1417
1425
|
since=since,
|
|
1418
1426
|
until=until,
|
|
1419
1427
|
return_all=True,
|
|
@@ -3359,6 +3367,37 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3359
3367
|
params=params,
|
|
3360
3368
|
)
|
|
3361
3369
|
|
|
3370
|
+
def get_model_endpoint_monitoring_metrics(
|
|
3371
|
+
self,
|
|
3372
|
+
project: str,
|
|
3373
|
+
endpoint_id: str,
|
|
3374
|
+
type: Literal["results", "metrics", "all"] = "all",
|
|
3375
|
+
) -> list[mm_endpoints.ModelEndpointMonitoringMetric]:
|
|
3376
|
+
"""Get application metrics/results by endpoint id and project.
|
|
3377
|
+
|
|
3378
|
+
:param project: The name of the project.
|
|
3379
|
+
:param endpoint_id: The unique id of the model endpoint.
|
|
3380
|
+
:param type: The type of the metrics to return. "all" means "results" and "metrics".
|
|
3381
|
+
|
|
3382
|
+
:return: A list of the application metrics or/and results for this model endpoint.
|
|
3383
|
+
"""
|
|
3384
|
+
path = f"projects/{project}/model-endpoints/{endpoint_id}/metrics"
|
|
3385
|
+
params = {"type": type}
|
|
3386
|
+
error_message = (
|
|
3387
|
+
f"Failed to get model endpoint monitoring metrics,"
|
|
3388
|
+
f" endpoint_id: {endpoint_id}, project: {project}"
|
|
3389
|
+
)
|
|
3390
|
+
response = self.api_call(
|
|
3391
|
+
mlrun.common.types.HTTPMethod.GET,
|
|
3392
|
+
path,
|
|
3393
|
+
error_message,
|
|
3394
|
+
params=params,
|
|
3395
|
+
)
|
|
3396
|
+
monitoring_metrics = response.json()
|
|
3397
|
+
return parse_obj_as(
|
|
3398
|
+
list[mm_endpoints.ModelEndpointMonitoringMetric], monitoring_metrics
|
|
3399
|
+
)
|
|
3400
|
+
|
|
3362
3401
|
def create_user_secrets(
|
|
3363
3402
|
self,
|
|
3364
3403
|
user: str,
|
|
@@ -3536,6 +3575,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3536
3575
|
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3537
3576
|
:param top_level: if true will return only routers and endpoint that are NOT children of any router
|
|
3538
3577
|
:param uids: if passed will return a list `ModelEndpoint` object with uid in uids
|
|
3578
|
+
|
|
3579
|
+
:returns: Returns a list of `ModelEndpoint` objects.
|
|
3539
3580
|
"""
|
|
3540
3581
|
|
|
3541
3582
|
path = f"projects/{project}/model-endpoints"
|
|
@@ -4183,12 +4224,21 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4183
4224
|
"operations/migrations",
|
|
4184
4225
|
"Failed triggering migrations",
|
|
4185
4226
|
)
|
|
4186
|
-
|
|
4187
|
-
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
|
|
4191
|
-
|
|
4227
|
+
return self._wait_for_background_task_from_response(response)
|
|
4228
|
+
|
|
4229
|
+
def refresh_smtp_configuration(
|
|
4230
|
+
self,
|
|
4231
|
+
) -> Optional[mlrun.common.schemas.BackgroundTask]:
|
|
4232
|
+
"""Refresh smtp configuration and wait for the task to finish
|
|
4233
|
+
|
|
4234
|
+
:returns: :py:class:`~mlrun.common.schemas.BackgroundTask`.
|
|
4235
|
+
"""
|
|
4236
|
+
response = self.api_call(
|
|
4237
|
+
"POST",
|
|
4238
|
+
"operations/refresh-smtp-configuration",
|
|
4239
|
+
"Failed refreshing smtp configuration",
|
|
4240
|
+
)
|
|
4241
|
+
return self._wait_for_background_task_from_response(response)
|
|
4192
4242
|
|
|
4193
4243
|
def set_run_notifications(
|
|
4194
4244
|
self,
|
|
@@ -4625,6 +4675,112 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4625
4675
|
results.append(mlrun.common.schemas.AlertTemplate(**item))
|
|
4626
4676
|
return results
|
|
4627
4677
|
|
|
4678
|
+
def list_alert_activations(
|
|
4679
|
+
self,
|
|
4680
|
+
project: Optional[str] = None,
|
|
4681
|
+
name: Optional[str] = None,
|
|
4682
|
+
since: Optional[datetime] = None,
|
|
4683
|
+
until: Optional[datetime] = None,
|
|
4684
|
+
entity: Optional[str] = None,
|
|
4685
|
+
severity: Optional[
|
|
4686
|
+
list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
|
|
4687
|
+
] = None,
|
|
4688
|
+
entity_kind: Optional[
|
|
4689
|
+
Union[mlrun.common.schemas.alert.EventEntityKind, str]
|
|
4690
|
+
] = None,
|
|
4691
|
+
event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
|
|
4692
|
+
) -> list[mlrun.common.schemas.AlertActivation]:
|
|
4693
|
+
"""
|
|
4694
|
+
Retrieve a list of all alert activations.
|
|
4695
|
+
|
|
4696
|
+
:param project: The project name to filter by. If None, results are not filtered by project.
|
|
4697
|
+
:param name: The alert name to filter by. Supports exact matching or partial matching if prefixed with `~`.
|
|
4698
|
+
:param since: Filters for alert activations occurring after this timestamp.
|
|
4699
|
+
:param until: Filters for alert activations occurring before this timestamp.
|
|
4700
|
+
:param entity: The entity ID to filter by. Supports wildcard matching if prefixed with `~`.
|
|
4701
|
+
:param severity: A list of severity levels to filter by (e.g., ["high", "low"]).
|
|
4702
|
+
:param entity_kind: The kind of entity (e.g., "job", "endpoint") to filter by.
|
|
4703
|
+
:param event_kind: The kind of event (e.g., ""data-drift-detected"", "failed") to filter by.
|
|
4704
|
+
|
|
4705
|
+
:returns: A list of alert activations matching the provided filters.
|
|
4706
|
+
"""
|
|
4707
|
+
|
|
4708
|
+
alert_activations, _ = self._list_alert_activations(
|
|
4709
|
+
project=project,
|
|
4710
|
+
name=name,
|
|
4711
|
+
since=since,
|
|
4712
|
+
until=until,
|
|
4713
|
+
entity=entity,
|
|
4714
|
+
severity=severity,
|
|
4715
|
+
entity_kind=entity_kind,
|
|
4716
|
+
event_kind=event_kind,
|
|
4717
|
+
return_all=True,
|
|
4718
|
+
)
|
|
4719
|
+
return alert_activations
|
|
4720
|
+
|
|
4721
|
+
def paginated_list_alert_activations(
|
|
4722
|
+
self,
|
|
4723
|
+
*args,
|
|
4724
|
+
page: Optional[int] = None,
|
|
4725
|
+
page_size: Optional[int] = None,
|
|
4726
|
+
page_token: Optional[str] = None,
|
|
4727
|
+
**kwargs,
|
|
4728
|
+
) -> tuple[list, Optional[str]]:
|
|
4729
|
+
"""List alerts activations with support for pagination and various filtering options.
|
|
4730
|
+
|
|
4731
|
+
This method retrieves a paginated list of alert activations based on the specified filter parameters.
|
|
4732
|
+
Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
|
|
4733
|
+
will return a list of alert activations that match the filtering criteria provided.
|
|
4734
|
+
|
|
4735
|
+
For detailed information about the parameters, refer to the list_alert_activations method:
|
|
4736
|
+
See :py:func:`~list_alert_activations` for more details.
|
|
4737
|
+
|
|
4738
|
+
Examples::
|
|
4739
|
+
|
|
4740
|
+
# Fetch first page of alert activations with page size of 5
|
|
4741
|
+
alert_activations, token = db.paginated_list_alert_activations(
|
|
4742
|
+
project="my-project", page_size=5
|
|
4743
|
+
)
|
|
4744
|
+
# Fetch next page using the pagination token from the previous response
|
|
4745
|
+
alert_activations, token = db.paginated_list_alert_activations(
|
|
4746
|
+
project="my-project", page_token=token
|
|
4747
|
+
)
|
|
4748
|
+
# Fetch alert activations for a specific page (e.g., page 3)
|
|
4749
|
+
alert_activations, token = db.paginated_list_alert_activations(
|
|
4750
|
+
project="my-project", page=3, page_size=5
|
|
4751
|
+
)
|
|
4752
|
+
|
|
4753
|
+
# Automatically iterate over all pages without explicitly specifying the page number
|
|
4754
|
+
alert_activations = []
|
|
4755
|
+
token = None
|
|
4756
|
+
while True:
|
|
4757
|
+
page_alert_activations, token = db.paginated_list_alert_activations(
|
|
4758
|
+
project="my-project", page_token=token, page_size=5
|
|
4759
|
+
)
|
|
4760
|
+
alert_activations.extend(page_alert_activations)
|
|
4761
|
+
|
|
4762
|
+
# If token is None and page_alert_activations is empty, we've reached the end (no more activations).
|
|
4763
|
+
# If token is None and page_alert_activations is not empty, we've fetched the last page of activations.
|
|
4764
|
+
if not token:
|
|
4765
|
+
break
|
|
4766
|
+
print(f"Total alert activations retrieved: {len(alert_activations)}")
|
|
4767
|
+
|
|
4768
|
+
:param page: The page number to retrieve. If not provided, the next page will be retrieved.
|
|
4769
|
+
:param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
|
|
4770
|
+
:param page_token: A pagination token used to retrieve the next page of results. Should not be provided
|
|
4771
|
+
for the first request.
|
|
4772
|
+
|
|
4773
|
+
:returns: A tuple containing the list of alert activations and an optional `page_token` for pagination.
|
|
4774
|
+
"""
|
|
4775
|
+
return self._list_alert_activations(
|
|
4776
|
+
*args,
|
|
4777
|
+
page=page,
|
|
4778
|
+
page_size=page_size,
|
|
4779
|
+
page_token=page_token,
|
|
4780
|
+
return_all=False,
|
|
4781
|
+
**kwargs,
|
|
4782
|
+
)
|
|
4783
|
+
|
|
4628
4784
|
@staticmethod
|
|
4629
4785
|
def _parse_labels(
|
|
4630
4786
|
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]],
|
|
@@ -4641,7 +4797,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4641
4797
|
"""
|
|
4642
4798
|
try:
|
|
4643
4799
|
return mlrun.common.schemas.common.LabelsModel(labels=labels).labels
|
|
4644
|
-
except pydantic.error_wrappers.ValidationError as exc:
|
|
4800
|
+
except pydantic.v1.error_wrappers.ValidationError as exc:
|
|
4645
4801
|
raise mlrun.errors.MLRunValueError(
|
|
4646
4802
|
"Invalid labels format. Must be a dictionary of strings, a list of strings, "
|
|
4647
4803
|
"or a comma-separated string."
|
|
@@ -4719,7 +4875,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4719
4875
|
name: Optional[str] = None,
|
|
4720
4876
|
project: Optional[str] = None,
|
|
4721
4877
|
tag: Optional[str] = None,
|
|
4878
|
+
kind: Optional[str] = None,
|
|
4722
4879
|
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
4880
|
+
format_: Optional[str] = None,
|
|
4723
4881
|
since: Optional[datetime] = None,
|
|
4724
4882
|
until: Optional[datetime] = None,
|
|
4725
4883
|
page: Optional[int] = None,
|
|
@@ -4734,9 +4892,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4734
4892
|
params = {
|
|
4735
4893
|
"name": name,
|
|
4736
4894
|
"tag": tag,
|
|
4895
|
+
"kind": kind,
|
|
4737
4896
|
"label": labels,
|
|
4738
4897
|
"since": datetime_to_iso(since),
|
|
4739
4898
|
"until": datetime_to_iso(until),
|
|
4899
|
+
"format": format_,
|
|
4740
4900
|
"page": page,
|
|
4741
4901
|
"page-size": page_size,
|
|
4742
4902
|
"page-token": page_token,
|
|
@@ -4870,6 +5030,58 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4870
5030
|
paginated_responses, token = self.process_paginated_responses(responses, "runs")
|
|
4871
5031
|
return RunList(paginated_responses), token
|
|
4872
5032
|
|
|
5033
|
+
def _list_alert_activations(
|
|
5034
|
+
self,
|
|
5035
|
+
project: Optional[str] = None,
|
|
5036
|
+
name: Optional[str] = None,
|
|
5037
|
+
since: Optional[datetime] = None,
|
|
5038
|
+
until: Optional[datetime] = None,
|
|
5039
|
+
entity: Optional[str] = None,
|
|
5040
|
+
severity: Optional[
|
|
5041
|
+
list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
|
|
5042
|
+
] = None,
|
|
5043
|
+
entity_kind: Optional[
|
|
5044
|
+
Union[mlrun.common.schemas.alert.EventEntityKind, str]
|
|
5045
|
+
] = None,
|
|
5046
|
+
event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
|
|
5047
|
+
page: Optional[int] = None,
|
|
5048
|
+
page_size: Optional[int] = None,
|
|
5049
|
+
page_token: Optional[str] = None,
|
|
5050
|
+
return_all: bool = False,
|
|
5051
|
+
) -> tuple[list[mlrun.common.schemas.AlertActivation], Optional[str]]:
|
|
5052
|
+
project = project or config.default_project
|
|
5053
|
+
params = {
|
|
5054
|
+
"name": name,
|
|
5055
|
+
"since": datetime_to_iso(since),
|
|
5056
|
+
"until": datetime_to_iso(until),
|
|
5057
|
+
"entity": entity,
|
|
5058
|
+
"severity": severity,
|
|
5059
|
+
"entity-kind": entity_kind,
|
|
5060
|
+
"event-kind": event_kind,
|
|
5061
|
+
"page": page,
|
|
5062
|
+
"page-size": page_size,
|
|
5063
|
+
"page-token": page_token,
|
|
5064
|
+
}
|
|
5065
|
+
error = "list alert activations"
|
|
5066
|
+
path = f"projects/{project}/alert-activations"
|
|
5067
|
+
|
|
5068
|
+
# Fetch the responses, either one page or all based on `return_all`
|
|
5069
|
+
responses = self.paginated_api_call(
|
|
5070
|
+
"GET", path, error, params=params, return_all=return_all
|
|
5071
|
+
)
|
|
5072
|
+
paginated_responses, token = self.process_paginated_responses(
|
|
5073
|
+
responses, "activations"
|
|
5074
|
+
)
|
|
5075
|
+
return paginated_responses, token
|
|
5076
|
+
|
|
5077
|
+
def _wait_for_background_task_from_response(self, response):
|
|
5078
|
+
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
5079
|
+
background_task = mlrun.common.schemas.BackgroundTask(**response.json())
|
|
5080
|
+
return self._wait_for_background_task_to_reach_terminal_state(
|
|
5081
|
+
background_task.metadata.name
|
|
5082
|
+
)
|
|
5083
|
+
return None
|
|
5084
|
+
|
|
4873
5085
|
|
|
4874
5086
|
def _as_json(obj):
|
|
4875
5087
|
fn = getattr(obj, "to_json", None)
|
mlrun/db/nopdb.py
CHANGED
|
@@ -230,12 +230,14 @@ class NopDB(RunDBInterface):
|
|
|
230
230
|
|
|
231
231
|
def list_functions(
|
|
232
232
|
self,
|
|
233
|
-
name=None,
|
|
234
|
-
project=
|
|
235
|
-
tag=
|
|
233
|
+
name: Optional[str] = None,
|
|
234
|
+
project: Optional[str] = None,
|
|
235
|
+
tag: Optional[str] = None,
|
|
236
|
+
kind: Optional[str] = None,
|
|
236
237
|
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
format_: mlrun.common.formatters.FunctionFormat = mlrun.common.formatters.FunctionFormat.full,
|
|
239
|
+
since: Optional[datetime.datetime] = None,
|
|
240
|
+
until: Optional[datetime.datetime] = None,
|
|
239
241
|
):
|
|
240
242
|
return []
|
|
241
243
|
|
|
@@ -863,3 +865,30 @@ class NopDB(RunDBInterface):
|
|
|
863
865
|
|
|
864
866
|
def list_alert_templates(self):
|
|
865
867
|
pass
|
|
868
|
+
|
|
869
|
+
def list_alert_activations(
|
|
870
|
+
self,
|
|
871
|
+
project: Optional[str] = None,
|
|
872
|
+
name: Optional[str] = None,
|
|
873
|
+
since: Optional[datetime.datetime] = None,
|
|
874
|
+
until: Optional[datetime.datetime] = None,
|
|
875
|
+
entity: Optional[str] = None,
|
|
876
|
+
severity: Optional[
|
|
877
|
+
list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
|
|
878
|
+
] = None,
|
|
879
|
+
entity_kind: Optional[
|
|
880
|
+
Union[mlrun.common.schemas.alert.EventEntityKind, str]
|
|
881
|
+
] = None,
|
|
882
|
+
event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
|
|
883
|
+
):
|
|
884
|
+
pass
|
|
885
|
+
|
|
886
|
+
def paginated_list_alert_activations(
|
|
887
|
+
self,
|
|
888
|
+
*args,
|
|
889
|
+
page: Optional[int] = None,
|
|
890
|
+
page_size: Optional[int] = None,
|
|
891
|
+
page_token: Optional[str] = None,
|
|
892
|
+
**kwargs,
|
|
893
|
+
):
|
|
894
|
+
pass
|
mlrun/model.py
CHANGED
|
@@ -24,7 +24,7 @@ from datetime import datetime
|
|
|
24
24
|
from os import environ
|
|
25
25
|
from typing import Any, Optional, Union
|
|
26
26
|
|
|
27
|
-
import pydantic.error_wrappers
|
|
27
|
+
import pydantic.v1.error_wrappers
|
|
28
28
|
|
|
29
29
|
import mlrun
|
|
30
30
|
import mlrun.common.constants as mlrun_constants
|
|
@@ -739,7 +739,7 @@ class Notification(ModelObj):
|
|
|
739
739
|
def validate_notification(self):
|
|
740
740
|
try:
|
|
741
741
|
mlrun.common.schemas.notification.Notification(**self.to_dict())
|
|
742
|
-
except pydantic.error_wrappers.ValidationError as exc:
|
|
742
|
+
except pydantic.v1.error_wrappers.ValidationError as exc:
|
|
743
743
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
744
744
|
"Invalid notification object"
|
|
745
745
|
) from exc
|
|
@@ -17,8 +17,8 @@ import json
|
|
|
17
17
|
import re
|
|
18
18
|
from abc import ABC, abstractmethod
|
|
19
19
|
|
|
20
|
-
from pydantic import validator
|
|
21
|
-
from pydantic.dataclasses import dataclass
|
|
20
|
+
from pydantic.v1 import validator
|
|
21
|
+
from pydantic.v1.dataclasses import dataclass
|
|
22
22
|
|
|
23
23
|
import mlrun.common.helpers
|
|
24
24
|
import mlrun.common.model_monitoring.helpers
|
|
@@ -17,7 +17,7 @@ from abc import ABC, abstractmethod
|
|
|
17
17
|
from datetime import datetime
|
|
18
18
|
|
|
19
19
|
import pandas as pd
|
|
20
|
-
import pydantic
|
|
20
|
+
import pydantic.v1
|
|
21
21
|
|
|
22
22
|
import mlrun.common.schemas.model_monitoring as mm_schemas
|
|
23
23
|
import mlrun.model_monitoring.db.tsdb.helpers
|
|
@@ -427,7 +427,7 @@ class TSDBConnector(ABC):
|
|
|
427
427
|
), # pyright: ignore[reportArgumentType]
|
|
428
428
|
)
|
|
429
429
|
)
|
|
430
|
-
except pydantic.ValidationError:
|
|
430
|
+
except pydantic.v1.ValidationError:
|
|
431
431
|
logger.exception(
|
|
432
432
|
"Failed to convert data-frame into `ModelEndpointMonitoringResultValues`",
|
|
433
433
|
full_name=full_name,
|
|
@@ -82,9 +82,10 @@ class TDEngineSchema:
|
|
|
82
82
|
super_table: str,
|
|
83
83
|
columns: dict[str, _TDEngineColumn],
|
|
84
84
|
tags: dict[str, str],
|
|
85
|
+
project: str,
|
|
85
86
|
database: Optional[str] = None,
|
|
86
87
|
):
|
|
87
|
-
self.super_table = super_table
|
|
88
|
+
self.super_table = f"{super_table}_{project.replace('-', '_')}"
|
|
88
89
|
self.columns = columns
|
|
89
90
|
self.tags = tags
|
|
90
91
|
self.database = database or _MODEL_MONITORING_DATABASE
|
|
@@ -148,6 +149,9 @@ class TDEngineSchema:
|
|
|
148
149
|
) -> str:
|
|
149
150
|
return f"DROP TABLE if EXISTS {self.database}.{subtable};"
|
|
150
151
|
|
|
152
|
+
def drop_supertable_query(self) -> str:
|
|
153
|
+
return f"DROP STABLE if EXISTS {self.database}.{self.super_table};"
|
|
154
|
+
|
|
151
155
|
def _get_subtables_query(
|
|
152
156
|
self,
|
|
153
157
|
values: dict[str, Union[str, int, float, datetime.datetime]],
|
|
@@ -260,7 +264,7 @@ class TDEngineSchema:
|
|
|
260
264
|
|
|
261
265
|
@dataclass
|
|
262
266
|
class AppResultTable(TDEngineSchema):
|
|
263
|
-
def __init__(self, database: Optional[str] = None):
|
|
267
|
+
def __init__(self, project: str, database: Optional[str] = None):
|
|
264
268
|
super_table = mm_schemas.TDEngineSuperTables.APP_RESULTS
|
|
265
269
|
columns = {
|
|
266
270
|
mm_schemas.WriterEvent.END_INFER_TIME: _TDEngineColumn.TIMESTAMP,
|
|
@@ -270,18 +274,23 @@ class AppResultTable(TDEngineSchema):
|
|
|
270
274
|
mm_schemas.ResultData.RESULT_EXTRA_DATA: _TDEngineColumn.BINARY_1000,
|
|
271
275
|
}
|
|
272
276
|
tags = {
|
|
273
|
-
mm_schemas.EventFieldType.PROJECT: _TDEngineColumn.BINARY_64,
|
|
274
277
|
mm_schemas.WriterEvent.ENDPOINT_ID: _TDEngineColumn.BINARY_64,
|
|
275
278
|
mm_schemas.WriterEvent.APPLICATION_NAME: _TDEngineColumn.BINARY_64,
|
|
276
279
|
mm_schemas.ResultData.RESULT_NAME: _TDEngineColumn.BINARY_64,
|
|
277
280
|
mm_schemas.ResultData.RESULT_KIND: _TDEngineColumn.INT,
|
|
278
281
|
}
|
|
279
|
-
super().__init__(
|
|
282
|
+
super().__init__(
|
|
283
|
+
super_table=super_table,
|
|
284
|
+
columns=columns,
|
|
285
|
+
tags=tags,
|
|
286
|
+
database=database,
|
|
287
|
+
project=project,
|
|
288
|
+
)
|
|
280
289
|
|
|
281
290
|
|
|
282
291
|
@dataclass
|
|
283
292
|
class Metrics(TDEngineSchema):
|
|
284
|
-
def __init__(self, database: Optional[str] = None):
|
|
293
|
+
def __init__(self, project: str, database: Optional[str] = None):
|
|
285
294
|
super_table = mm_schemas.TDEngineSuperTables.METRICS
|
|
286
295
|
columns = {
|
|
287
296
|
mm_schemas.WriterEvent.END_INFER_TIME: _TDEngineColumn.TIMESTAMP,
|
|
@@ -289,17 +298,22 @@ class Metrics(TDEngineSchema):
|
|
|
289
298
|
mm_schemas.MetricData.METRIC_VALUE: _TDEngineColumn.FLOAT,
|
|
290
299
|
}
|
|
291
300
|
tags = {
|
|
292
|
-
mm_schemas.EventFieldType.PROJECT: _TDEngineColumn.BINARY_64,
|
|
293
301
|
mm_schemas.WriterEvent.ENDPOINT_ID: _TDEngineColumn.BINARY_64,
|
|
294
302
|
mm_schemas.WriterEvent.APPLICATION_NAME: _TDEngineColumn.BINARY_64,
|
|
295
303
|
mm_schemas.MetricData.METRIC_NAME: _TDEngineColumn.BINARY_64,
|
|
296
304
|
}
|
|
297
|
-
super().__init__(
|
|
305
|
+
super().__init__(
|
|
306
|
+
super_table=super_table,
|
|
307
|
+
columns=columns,
|
|
308
|
+
tags=tags,
|
|
309
|
+
database=database,
|
|
310
|
+
project=project,
|
|
311
|
+
)
|
|
298
312
|
|
|
299
313
|
|
|
300
314
|
@dataclass
|
|
301
315
|
class Predictions(TDEngineSchema):
|
|
302
|
-
def __init__(self, database: Optional[str] = None):
|
|
316
|
+
def __init__(self, project: str, database: Optional[str] = None):
|
|
303
317
|
super_table = mm_schemas.TDEngineSuperTables.PREDICTIONS
|
|
304
318
|
columns = {
|
|
305
319
|
mm_schemas.EventFieldType.TIME: _TDEngineColumn.TIMESTAMP,
|
|
@@ -307,23 +321,33 @@ class Predictions(TDEngineSchema):
|
|
|
307
321
|
mm_schemas.EventKeyMetrics.CUSTOM_METRICS: _TDEngineColumn.BINARY_1000,
|
|
308
322
|
}
|
|
309
323
|
tags = {
|
|
310
|
-
mm_schemas.EventFieldType.PROJECT: _TDEngineColumn.BINARY_64,
|
|
311
324
|
mm_schemas.WriterEvent.ENDPOINT_ID: _TDEngineColumn.BINARY_64,
|
|
312
325
|
}
|
|
313
|
-
super().__init__(
|
|
326
|
+
super().__init__(
|
|
327
|
+
super_table=super_table,
|
|
328
|
+
columns=columns,
|
|
329
|
+
tags=tags,
|
|
330
|
+
database=database,
|
|
331
|
+
project=project,
|
|
332
|
+
)
|
|
314
333
|
|
|
315
334
|
|
|
316
335
|
@dataclass
|
|
317
336
|
class Errors(TDEngineSchema):
|
|
318
|
-
def __init__(self, database: Optional[str] = None):
|
|
337
|
+
def __init__(self, project: str, database: Optional[str] = None):
|
|
319
338
|
super_table = mm_schemas.TDEngineSuperTables.ERRORS
|
|
320
339
|
columns = {
|
|
321
340
|
mm_schemas.EventFieldType.TIME: _TDEngineColumn.TIMESTAMP,
|
|
322
341
|
mm_schemas.EventFieldType.MODEL_ERROR: _TDEngineColumn.BINARY_1000,
|
|
323
342
|
}
|
|
324
343
|
tags = {
|
|
325
|
-
mm_schemas.EventFieldType.PROJECT: _TDEngineColumn.BINARY_64,
|
|
326
344
|
mm_schemas.WriterEvent.ENDPOINT_ID: _TDEngineColumn.BINARY_64,
|
|
327
345
|
mm_schemas.EventFieldType.ERROR_TYPE: _TDEngineColumn.BINARY_64,
|
|
328
346
|
}
|
|
329
|
-
super().__init__(
|
|
347
|
+
super().__init__(
|
|
348
|
+
super_table=super_table,
|
|
349
|
+
columns=columns,
|
|
350
|
+
tags=tags,
|
|
351
|
+
database=database,
|
|
352
|
+
project=project,
|
|
353
|
+
)
|