mlrun 1.7.1rc10__py3-none-any.whl → 1.8.0rc11__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 +23 -21
- mlrun/__main__.py +3 -3
- mlrun/alerts/alert.py +148 -14
- mlrun/artifacts/__init__.py +2 -3
- mlrun/artifacts/base.py +55 -12
- mlrun/artifacts/dataset.py +16 -16
- mlrun/artifacts/document.py +378 -0
- mlrun/artifacts/manager.py +26 -17
- mlrun/artifacts/model.py +66 -53
- mlrun/common/constants.py +8 -0
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/feature_set.py +1 -0
- mlrun/common/formatters/function.py +1 -0
- mlrun/{model_monitoring/db/stores/base/__init__.py → common/formatters/model_endpoint.py} +16 -1
- mlrun/common/formatters/pipeline.py +1 -2
- mlrun/common/formatters/project.py +9 -0
- mlrun/common/model_monitoring/__init__.py +0 -5
- mlrun/common/model_monitoring/helpers.py +1 -29
- mlrun/common/runtimes/constants.py +1 -2
- mlrun/common/schemas/__init__.py +6 -2
- mlrun/common/schemas/alert.py +111 -19
- mlrun/common/schemas/api_gateway.py +3 -3
- mlrun/common/schemas/artifact.py +11 -7
- mlrun/common/schemas/auth.py +6 -4
- mlrun/common/schemas/background_task.py +7 -7
- mlrun/common/schemas/client_spec.py +2 -3
- mlrun/common/schemas/clusterization_spec.py +2 -2
- mlrun/common/schemas/common.py +53 -3
- mlrun/common/schemas/constants.py +15 -0
- 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/__init__.py +2 -1
- mlrun/common/schemas/model_monitoring/constants.py +67 -14
- mlrun/common/schemas/model_monitoring/grafana.py +1 -1
- mlrun/common/schemas/model_monitoring/model_endpoints.py +92 -147
- mlrun/common/schemas/notification.py +24 -3
- mlrun/common/schemas/object.py +1 -1
- mlrun/common/schemas/pagination.py +4 -4
- mlrun/common/schemas/partition.py +137 -0
- mlrun/common/schemas/pipeline.py +2 -2
- mlrun/common/schemas/project.py +25 -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 +68 -10
- mlrun/data_types/__init__.py +0 -2
- mlrun/data_types/data_types.py +1 -0
- mlrun/data_types/infer.py +3 -1
- mlrun/data_types/spark.py +5 -3
- mlrun/data_types/to_pandas.py +11 -2
- mlrun/datastore/__init__.py +2 -2
- mlrun/datastore/alibaba_oss.py +4 -1
- mlrun/datastore/azure_blob.py +4 -1
- mlrun/datastore/base.py +12 -4
- mlrun/datastore/datastore.py +9 -3
- mlrun/datastore/datastore_profile.py +79 -20
- mlrun/datastore/dbfs_store.py +4 -1
- mlrun/datastore/filestore.py +4 -1
- mlrun/datastore/google_cloud_storage.py +4 -1
- mlrun/datastore/hdfs.py +4 -1
- mlrun/datastore/inmem.py +4 -1
- mlrun/datastore/redis.py +4 -1
- mlrun/datastore/s3.py +4 -1
- mlrun/datastore/sources.py +52 -51
- mlrun/datastore/store_resources.py +7 -4
- mlrun/datastore/targets.py +23 -22
- mlrun/datastore/utils.py +2 -2
- mlrun/datastore/v3io.py +4 -1
- mlrun/datastore/vectorstore.py +229 -0
- mlrun/datastore/wasbfs/fs.py +13 -12
- mlrun/db/base.py +213 -83
- mlrun/db/factory.py +0 -3
- mlrun/db/httpdb.py +1265 -387
- mlrun/db/nopdb.py +205 -74
- mlrun/errors.py +2 -2
- mlrun/execution.py +136 -50
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +41 -40
- mlrun/feature_store/common.py +9 -9
- mlrun/feature_store/feature_set.py +20 -18
- mlrun/feature_store/feature_vector.py +27 -24
- mlrun/feature_store/retrieval/base.py +14 -9
- mlrun/feature_store/retrieval/job.py +2 -1
- mlrun/feature_store/steps.py +2 -2
- mlrun/features.py +30 -13
- mlrun/frameworks/__init__.py +1 -2
- mlrun/frameworks/_common/__init__.py +1 -2
- mlrun/frameworks/_common/artifacts_library.py +2 -2
- mlrun/frameworks/_common/mlrun_interface.py +10 -6
- mlrun/frameworks/_common/model_handler.py +29 -27
- mlrun/frameworks/_common/producer.py +3 -1
- mlrun/frameworks/_dl_common/__init__.py +1 -2
- mlrun/frameworks/_dl_common/loggers/__init__.py +1 -2
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +4 -4
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +3 -3
- mlrun/frameworks/_ml_common/__init__.py +1 -2
- mlrun/frameworks/_ml_common/loggers/__init__.py +1 -2
- mlrun/frameworks/_ml_common/model_handler.py +21 -21
- mlrun/frameworks/_ml_common/plans/__init__.py +1 -2
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +3 -1
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
- mlrun/frameworks/auto_mlrun/__init__.py +1 -2
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +22 -15
- mlrun/frameworks/huggingface/__init__.py +1 -2
- mlrun/frameworks/huggingface/model_server.py +9 -9
- mlrun/frameworks/lgbm/__init__.py +47 -44
- mlrun/frameworks/lgbm/callbacks/__init__.py +1 -2
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -2
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -2
- mlrun/frameworks/lgbm/mlrun_interfaces/__init__.py +1 -2
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +5 -5
- mlrun/frameworks/lgbm/model_handler.py +15 -11
- mlrun/frameworks/lgbm/model_server.py +11 -7
- mlrun/frameworks/lgbm/utils.py +2 -2
- mlrun/frameworks/onnx/__init__.py +1 -2
- mlrun/frameworks/onnx/dataset.py +3 -3
- mlrun/frameworks/onnx/mlrun_interface.py +2 -2
- mlrun/frameworks/onnx/model_handler.py +7 -5
- mlrun/frameworks/onnx/model_server.py +8 -6
- mlrun/frameworks/parallel_coordinates.py +11 -11
- mlrun/frameworks/pytorch/__init__.py +22 -23
- mlrun/frameworks/pytorch/callbacks/__init__.py +1 -2
- mlrun/frameworks/pytorch/callbacks/callback.py +2 -1
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +15 -8
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +19 -12
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +22 -15
- mlrun/frameworks/pytorch/callbacks_handler.py +36 -30
- mlrun/frameworks/pytorch/mlrun_interface.py +17 -17
- mlrun/frameworks/pytorch/model_handler.py +21 -17
- mlrun/frameworks/pytorch/model_server.py +13 -9
- mlrun/frameworks/sklearn/__init__.py +19 -18
- mlrun/frameworks/sklearn/estimator.py +2 -2
- mlrun/frameworks/sklearn/metric.py +3 -3
- mlrun/frameworks/sklearn/metrics_library.py +8 -6
- mlrun/frameworks/sklearn/mlrun_interface.py +3 -2
- mlrun/frameworks/sklearn/model_handler.py +4 -3
- mlrun/frameworks/tf_keras/__init__.py +11 -12
- mlrun/frameworks/tf_keras/callbacks/__init__.py +1 -2
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +17 -14
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +15 -12
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +21 -18
- mlrun/frameworks/tf_keras/model_handler.py +17 -13
- mlrun/frameworks/tf_keras/model_server.py +12 -8
- mlrun/frameworks/xgboost/__init__.py +19 -18
- mlrun/frameworks/xgboost/model_handler.py +13 -9
- mlrun/launcher/base.py +3 -4
- mlrun/launcher/local.py +1 -1
- mlrun/launcher/remote.py +1 -1
- mlrun/lists.py +4 -3
- mlrun/model.py +117 -46
- mlrun/model_monitoring/__init__.py +4 -4
- mlrun/model_monitoring/api.py +72 -59
- mlrun/model_monitoring/applications/_application_steps.py +17 -17
- mlrun/model_monitoring/applications/base.py +165 -6
- mlrun/model_monitoring/applications/context.py +88 -37
- mlrun/model_monitoring/applications/evidently_base.py +0 -1
- mlrun/model_monitoring/applications/histogram_data_drift.py +43 -21
- mlrun/model_monitoring/applications/results.py +55 -3
- mlrun/model_monitoring/controller.py +207 -239
- mlrun/model_monitoring/db/__init__.py +0 -2
- mlrun/model_monitoring/db/_schedules.py +156 -0
- mlrun/model_monitoring/db/_stats.py +189 -0
- mlrun/model_monitoring/db/tsdb/base.py +78 -25
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +61 -6
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +33 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +255 -29
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +1 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +78 -17
- mlrun/model_monitoring/helpers.py +151 -49
- mlrun/model_monitoring/stream_processing.py +99 -283
- mlrun/model_monitoring/tracking_policy.py +10 -3
- mlrun/model_monitoring/writer.py +48 -36
- mlrun/package/__init__.py +3 -6
- mlrun/package/context_handler.py +1 -1
- mlrun/package/packager.py +12 -9
- mlrun/package/packagers/__init__.py +0 -2
- mlrun/package/packagers/default_packager.py +14 -11
- mlrun/package/packagers/numpy_packagers.py +16 -7
- mlrun/package/packagers/pandas_packagers.py +18 -18
- mlrun/package/packagers/python_standard_library_packagers.py +25 -11
- mlrun/package/packagers_manager.py +31 -14
- mlrun/package/utils/__init__.py +0 -3
- mlrun/package/utils/_pickler.py +6 -6
- mlrun/platforms/__init__.py +47 -16
- mlrun/platforms/iguazio.py +4 -1
- mlrun/projects/operations.py +27 -27
- mlrun/projects/pipelines.py +71 -36
- mlrun/projects/project.py +890 -220
- mlrun/run.py +53 -10
- mlrun/runtimes/__init__.py +1 -3
- mlrun/runtimes/base.py +15 -11
- mlrun/runtimes/daskjob.py +9 -9
- mlrun/runtimes/generators.py +2 -1
- mlrun/runtimes/kubejob.py +4 -5
- mlrun/runtimes/mounts.py +572 -0
- mlrun/runtimes/mpijob/__init__.py +0 -2
- mlrun/runtimes/mpijob/abstract.py +7 -6
- mlrun/runtimes/nuclio/api_gateway.py +7 -7
- mlrun/runtimes/nuclio/application/application.py +11 -11
- mlrun/runtimes/nuclio/function.py +19 -17
- mlrun/runtimes/nuclio/serving.py +18 -13
- mlrun/runtimes/pod.py +154 -45
- mlrun/runtimes/remotesparkjob.py +3 -2
- mlrun/runtimes/sparkjob/__init__.py +0 -2
- mlrun/runtimes/sparkjob/spark3job.py +21 -11
- mlrun/runtimes/utils.py +6 -5
- mlrun/serving/merger.py +6 -4
- mlrun/serving/remote.py +18 -17
- mlrun/serving/routers.py +185 -172
- mlrun/serving/server.py +7 -1
- mlrun/serving/states.py +97 -78
- mlrun/serving/utils.py +13 -2
- mlrun/serving/v1_serving.py +3 -2
- mlrun/serving/v2_serving.py +105 -72
- mlrun/track/__init__.py +1 -1
- mlrun/track/tracker.py +2 -2
- mlrun/track/trackers/mlflow_tracker.py +6 -5
- mlrun/utils/async_http.py +1 -1
- mlrun/utils/clones.py +1 -1
- mlrun/utils/helpers.py +63 -19
- mlrun/utils/logger.py +106 -4
- mlrun/utils/notifications/notification/__init__.py +22 -19
- mlrun/utils/notifications/notification/base.py +33 -14
- mlrun/utils/notifications/notification/console.py +6 -6
- mlrun/utils/notifications/notification/git.py +11 -11
- mlrun/utils/notifications/notification/ipython.py +10 -9
- mlrun/utils/notifications/notification/mail.py +176 -0
- mlrun/utils/notifications/notification/slack.py +6 -6
- mlrun/utils/notifications/notification/webhook.py +6 -6
- mlrun/utils/notifications/notification_pusher.py +86 -44
- mlrun/utils/regex.py +11 -2
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/METADATA +29 -24
- mlrun-1.8.0rc11.dist-info/RECORD +347 -0
- mlrun/model_monitoring/db/stores/__init__.py +0 -136
- mlrun/model_monitoring/db/stores/base/store.py +0 -213
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +0 -71
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +0 -190
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +0 -103
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +0 -40
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +0 -659
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +0 -13
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +0 -726
- mlrun/model_monitoring/model_endpoint.py +0 -118
- mlrun-1.7.1rc10.dist-info/RECORD +0 -351
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/LICENSE +0 -0
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/WHEEL +0 -0
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.1rc10.dist-info → mlrun-1.8.0rc11.dist-info}/top_level.txt +0 -0
mlrun/db/httpdb.py
CHANGED
|
@@ -22,19 +22,21 @@ 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.v1
|
|
28
29
|
import requests
|
|
29
30
|
import semver
|
|
30
|
-
from
|
|
31
|
+
from pydantic.v1 import parse_obj_as
|
|
31
32
|
|
|
32
33
|
import mlrun
|
|
34
|
+
import mlrun.common.constants
|
|
33
35
|
import mlrun.common.formatters
|
|
34
36
|
import mlrun.common.runtimes
|
|
35
37
|
import mlrun.common.schemas
|
|
38
|
+
import mlrun.common.schemas.model_monitoring.model_endpoints as mm_endpoints
|
|
36
39
|
import mlrun.common.types
|
|
37
|
-
import mlrun.model_monitoring.model_endpoint
|
|
38
40
|
import mlrun.platforms
|
|
39
41
|
import mlrun.projects
|
|
40
42
|
import mlrun.runtimes.nuclio.api_gateway
|
|
@@ -43,8 +45,10 @@ import mlrun.utils
|
|
|
43
45
|
from mlrun.alerts.alert import AlertConfig
|
|
44
46
|
from mlrun.db.auth_utils import OAuthClientIDTokenProvider, StaticTokenProvider
|
|
45
47
|
from mlrun.errors import MLRunInvalidArgumentError, err_to_str
|
|
48
|
+
from mlrun_pipelines.utils import compile_pipeline
|
|
46
49
|
|
|
47
50
|
from ..artifacts import Artifact
|
|
51
|
+
from ..common.schemas import AlertActivations
|
|
48
52
|
from ..config import config
|
|
49
53
|
from ..datastore.datastore_profile import DatastoreProfile2Json
|
|
50
54
|
from ..feature_store import FeatureSet, FeatureVector
|
|
@@ -169,7 +173,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
169
173
|
return f"{cls}({self.base_url!r})"
|
|
170
174
|
|
|
171
175
|
@staticmethod
|
|
172
|
-
def get_api_path_prefix(version: str = None) -> str:
|
|
176
|
+
def get_api_path_prefix(version: Optional[str] = None) -> str:
|
|
173
177
|
"""
|
|
174
178
|
:param version: API version to use, None (the default) will mean to use the default value from mlrun.config,
|
|
175
179
|
for un-versioned api set an empty string.
|
|
@@ -182,7 +186,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
182
186
|
)
|
|
183
187
|
return api_version_path
|
|
184
188
|
|
|
185
|
-
def get_base_api_url(self, path: str, version: str = None) -> str:
|
|
189
|
+
def get_base_api_url(self, path: str, version: Optional[str] = None) -> str:
|
|
186
190
|
path_prefix = self.get_api_path_prefix(version)
|
|
187
191
|
url = f"{self.base_url}/{path_prefix}/{path}"
|
|
188
192
|
return url
|
|
@@ -310,9 +314,26 @@ class HTTPRunDB(RunDBInterface):
|
|
|
310
314
|
headers=None,
|
|
311
315
|
timeout=45,
|
|
312
316
|
version=None,
|
|
317
|
+
return_all=False,
|
|
313
318
|
) -> typing.Generator[requests.Response, None, None]:
|
|
314
319
|
"""
|
|
315
|
-
Calls the
|
|
320
|
+
Calls the API with pagination and yields each page of the response.
|
|
321
|
+
|
|
322
|
+
Depending on the `return_all` parameter:
|
|
323
|
+
- If `return_all` is `True`, fetches and yields all pages of results.
|
|
324
|
+
- If `return_all` is False, only a single page of results is fetched and yielded.
|
|
325
|
+
|
|
326
|
+
:param method: The HTTP method (GET, POST, etc.).
|
|
327
|
+
:param path: The API endpoint path.
|
|
328
|
+
:param error: Error message used for debugging if the request fails.
|
|
329
|
+
:param params: The parameters to pass for the API request, including filters.
|
|
330
|
+
:param body: The body of the request.
|
|
331
|
+
:param json: The JSON payload for the request.
|
|
332
|
+
:param headers: Custom headers for the request.
|
|
333
|
+
:param timeout: Timeout for the request.
|
|
334
|
+
:param version: API version, optional.
|
|
335
|
+
:param return_all: If `True`, fetches all pages and returns them in one shot. If `False`, returns only
|
|
336
|
+
the requested page or the next page.
|
|
316
337
|
"""
|
|
317
338
|
|
|
318
339
|
def _api_call(_params):
|
|
@@ -328,38 +349,50 @@ class HTTPRunDB(RunDBInterface):
|
|
|
328
349
|
version=version,
|
|
329
350
|
)
|
|
330
351
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
if
|
|
337
|
-
|
|
338
|
-
|
|
352
|
+
page_params = deepcopy(params) or {}
|
|
353
|
+
|
|
354
|
+
if page_params.get("page-token") is None and page_params.get("page") is None:
|
|
355
|
+
page_params["page"] = 1
|
|
356
|
+
|
|
357
|
+
if page_params.get("page-size") is None:
|
|
358
|
+
page_params["page-size"] = config.httpdb.pagination.default_page_size
|
|
359
|
+
|
|
360
|
+
response = _api_call(page_params)
|
|
339
361
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
while page_token:
|
|
343
|
-
yield response
|
|
344
|
-
try:
|
|
345
|
-
response = _api_call(params_with_page_token)
|
|
346
|
-
except mlrun.errors.MLRunNotFoundError:
|
|
347
|
-
# pagination token expired
|
|
348
|
-
break
|
|
362
|
+
# Yield only a single page of results
|
|
363
|
+
yield response
|
|
349
364
|
|
|
365
|
+
if return_all:
|
|
350
366
|
page_token = response.json().get("pagination", {}).get("page-token", None)
|
|
351
367
|
|
|
368
|
+
while page_token:
|
|
369
|
+
try:
|
|
370
|
+
# Use the page token to get the next page.
|
|
371
|
+
# No need to supply any other parameters as the token informs the pagination cache
|
|
372
|
+
# which parameters to use.
|
|
373
|
+
response = _api_call({"page-token": page_token})
|
|
374
|
+
except mlrun.errors.MLRunNotFoundError:
|
|
375
|
+
# pagination token expired, we've reached the last page
|
|
376
|
+
break
|
|
377
|
+
|
|
378
|
+
yield response
|
|
379
|
+
page_token = (
|
|
380
|
+
response.json().get("pagination", {}).get("page-token", None)
|
|
381
|
+
)
|
|
382
|
+
|
|
352
383
|
@staticmethod
|
|
353
384
|
def process_paginated_responses(
|
|
354
385
|
responses: typing.Generator[requests.Response, None, None], key: str = "data"
|
|
355
|
-
) -> list[typing.Any]:
|
|
386
|
+
) -> tuple[list[typing.Any], Optional[str]]:
|
|
356
387
|
"""
|
|
357
388
|
Processes the paginated responses and returns the combined data
|
|
358
389
|
"""
|
|
359
390
|
data = []
|
|
391
|
+
page_token = None
|
|
360
392
|
for response in responses:
|
|
393
|
+
page_token = response.json().get("pagination", {}).get("page-token", None)
|
|
361
394
|
data.extend(response.json().get(key, []))
|
|
362
|
-
return data
|
|
395
|
+
return data, page_token
|
|
363
396
|
|
|
364
397
|
def _init_session(self, retry_on_post: bool = False):
|
|
365
398
|
return mlrun.utils.HTTPSessionWithRetry(
|
|
@@ -525,10 +558,6 @@ class HTTPRunDB(RunDBInterface):
|
|
|
525
558
|
server_cfg.get("external_platform_tracking")
|
|
526
559
|
or config.external_platform_tracking
|
|
527
560
|
)
|
|
528
|
-
config.model_endpoint_monitoring.endpoint_store_connection = (
|
|
529
|
-
server_cfg.get("model_endpoint_monitoring_endpoint_store_connection")
|
|
530
|
-
or config.model_endpoint_monitoring.endpoint_store_connection
|
|
531
|
-
)
|
|
532
561
|
config.model_endpoint_monitoring.tsdb_connection = (
|
|
533
562
|
server_cfg.get("model_monitoring_tsdb_connection")
|
|
534
563
|
or config.model_endpoint_monitoring.tsdb_connection
|
|
@@ -768,7 +797,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
768
797
|
name: Optional[str] = None,
|
|
769
798
|
uid: Optional[Union[str, list[str]]] = None,
|
|
770
799
|
project: Optional[str] = None,
|
|
771
|
-
labels: Optional[Union[str, list[str]]] = None,
|
|
800
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
772
801
|
state: Optional[
|
|
773
802
|
mlrun.common.runtimes.constants.RunStates
|
|
774
803
|
] = None, # Backward compatibility
|
|
@@ -807,9 +836,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
807
836
|
:param name: Name of the run to retrieve.
|
|
808
837
|
:param uid: Unique ID of the run, or a list of run UIDs.
|
|
809
838
|
:param project: Project that the runs belongs to.
|
|
810
|
-
:param labels:
|
|
811
|
-
|
|
812
|
-
|
|
839
|
+
:param labels: Filter runs by label key-value pairs or key existence. This can be provided as:
|
|
840
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
841
|
+
or `{"label": None}` to check for key existence.
|
|
842
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
843
|
+
or just `"label"` for key existence.
|
|
844
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
845
|
+
the specified key-value pairs or key existence.
|
|
813
846
|
:param state: Deprecated - List only runs whose state is specified (will be removed in 1.9.0)
|
|
814
847
|
:param states: List only runs whose state is one of the provided states.
|
|
815
848
|
:param sort: Whether to sort the result according to their start time. Otherwise, results will be
|
|
@@ -821,8 +854,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
821
854
|
:param last_update_time_from: Filter by run last update time in ``(last_update_time_from,
|
|
822
855
|
last_update_time_to)``.
|
|
823
856
|
:param last_update_time_to: Filter by run last update time in ``(last_update_time_from, last_update_time_to)``.
|
|
824
|
-
:param partition_by: Field to group results by.
|
|
825
|
-
|
|
857
|
+
:param partition_by: Field to group results by. When `partition_by` is specified, the `partition_sort_by`
|
|
858
|
+
parameter must be provided as well.
|
|
826
859
|
:param rows_per_partition: How many top rows (per sorting defined by `partition_sort_by` and `partition_order`)
|
|
827
860
|
to return per group. Default value is 1.
|
|
828
861
|
:param partition_sort_by: What field to sort the results by, within each partition defined by `partition_by`.
|
|
@@ -832,81 +865,95 @@ class HTTPRunDB(RunDBInterface):
|
|
|
832
865
|
limit.
|
|
833
866
|
:param with_notifications: Return runs with notifications, and join them to the response. Default is `False`.
|
|
834
867
|
"""
|
|
868
|
+
runs, _ = self._list_runs(
|
|
869
|
+
name=name,
|
|
870
|
+
uid=uid,
|
|
871
|
+
project=project,
|
|
872
|
+
labels=labels,
|
|
873
|
+
state=state,
|
|
874
|
+
states=states,
|
|
875
|
+
sort=sort,
|
|
876
|
+
last=last,
|
|
877
|
+
iter=iter,
|
|
878
|
+
start_time_from=start_time_from,
|
|
879
|
+
start_time_to=start_time_to,
|
|
880
|
+
last_update_time_from=last_update_time_from,
|
|
881
|
+
last_update_time_to=last_update_time_to,
|
|
882
|
+
partition_by=partition_by,
|
|
883
|
+
rows_per_partition=rows_per_partition,
|
|
884
|
+
partition_sort_by=partition_sort_by,
|
|
885
|
+
partition_order=partition_order,
|
|
886
|
+
max_partitions=max_partitions,
|
|
887
|
+
with_notifications=with_notifications,
|
|
888
|
+
return_all=True,
|
|
889
|
+
)
|
|
890
|
+
return runs
|
|
835
891
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
warnings.warn(
|
|
846
|
-
"'last' is deprecated and will be removed in 1.8.0.",
|
|
847
|
-
FutureWarning,
|
|
848
|
-
)
|
|
892
|
+
def paginated_list_runs(
|
|
893
|
+
self,
|
|
894
|
+
*args,
|
|
895
|
+
page: Optional[int] = None,
|
|
896
|
+
page_size: Optional[int] = None,
|
|
897
|
+
page_token: Optional[str] = None,
|
|
898
|
+
**kwargs,
|
|
899
|
+
) -> tuple[RunList, Optional[str]]:
|
|
900
|
+
"""List runs with support for pagination and various filtering options.
|
|
849
901
|
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
"'state' is deprecated and will be removed in 1.9.0. Use 'states' instead.",
|
|
854
|
-
FutureWarning,
|
|
855
|
-
)
|
|
902
|
+
This method retrieves a paginated list of runs based on the specified filter parameters.
|
|
903
|
+
Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
|
|
904
|
+
will return a list of runs that match the filtering criteria provided.
|
|
856
905
|
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
and not uid
|
|
860
|
-
and not labels
|
|
861
|
-
and not state
|
|
862
|
-
and not states
|
|
863
|
-
and not last
|
|
864
|
-
and not start_time_from
|
|
865
|
-
and not start_time_to
|
|
866
|
-
and not last_update_time_from
|
|
867
|
-
and not last_update_time_to
|
|
868
|
-
and not partition_by
|
|
869
|
-
and not partition_sort_by
|
|
870
|
-
and not iter
|
|
871
|
-
):
|
|
872
|
-
# default to last week on no filter
|
|
873
|
-
start_time_from = datetime.now() - timedelta(days=7)
|
|
874
|
-
partition_by = mlrun.common.schemas.RunPartitionByField.project_and_name
|
|
875
|
-
partition_sort_by = mlrun.common.schemas.SortField.updated
|
|
906
|
+
For detailed information about the parameters, refer to the list_runs method:
|
|
907
|
+
See :py:func:`~list_runs` for more details.
|
|
876
908
|
|
|
877
|
-
|
|
878
|
-
"name": name,
|
|
879
|
-
"uid": uid,
|
|
880
|
-
"label": labels or [],
|
|
881
|
-
"state": mlrun.utils.helpers.as_list(state)
|
|
882
|
-
if state is not None
|
|
883
|
-
else states or None,
|
|
884
|
-
"sort": bool2str(sort),
|
|
885
|
-
"iter": bool2str(iter),
|
|
886
|
-
"start_time_from": datetime_to_iso(start_time_from),
|
|
887
|
-
"start_time_to": datetime_to_iso(start_time_to),
|
|
888
|
-
"last_update_time_from": datetime_to_iso(last_update_time_from),
|
|
889
|
-
"last_update_time_to": datetime_to_iso(last_update_time_to),
|
|
890
|
-
"with-notifications": with_notifications,
|
|
891
|
-
}
|
|
909
|
+
Examples::
|
|
892
910
|
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
911
|
+
# Fetch first page of runs with page size of 5
|
|
912
|
+
runs, token = db.paginated_list_runs(project="my-project", page_size=5)
|
|
913
|
+
# Fetch next page using the pagination token from the previous response
|
|
914
|
+
runs, token = db.paginated_list_runs(project="my-project", page_token=token)
|
|
915
|
+
# Fetch runs for a specific page (e.g., page 3)
|
|
916
|
+
runs, token = db.paginated_list_runs(project="my-project", page=3, page_size=5)
|
|
917
|
+
|
|
918
|
+
# Automatically iterate over all pages without explicitly specifying the page number
|
|
919
|
+
runs = []
|
|
920
|
+
token = None
|
|
921
|
+
while True:
|
|
922
|
+
page_runs, token = db.paginated_list_runs(
|
|
923
|
+
project="my-project", page_token=token, page_size=5
|
|
902
924
|
)
|
|
903
|
-
|
|
904
|
-
error = "list runs"
|
|
905
|
-
_path = self._path_of("runs", project)
|
|
906
|
-
responses = self.paginated_api_call("GET", _path, error, params=params)
|
|
907
|
-
return RunList(self.process_paginated_responses(responses, "runs"))
|
|
925
|
+
runs.extend(page_runs)
|
|
908
926
|
|
|
909
|
-
|
|
927
|
+
# If token is None and page_runs is empty, we've reached the end (no more runs).
|
|
928
|
+
# If token is None and page_runs is not empty, we've fetched the last page of runs.
|
|
929
|
+
if not token:
|
|
930
|
+
break
|
|
931
|
+
print(f"Total runs retrieved: {len(runs)}")
|
|
932
|
+
|
|
933
|
+
:param page: The page number to retrieve. If not provided, the next page will be retrieved.
|
|
934
|
+
:param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
|
|
935
|
+
:param page_token: A pagination token used to retrieve the next page of results. Should not be provided
|
|
936
|
+
for the first request.
|
|
937
|
+
|
|
938
|
+
:returns: A tuple containing the list of runs and an optional `page_token` for pagination.
|
|
939
|
+
"""
|
|
940
|
+
return self._list_runs(
|
|
941
|
+
*args,
|
|
942
|
+
page=page,
|
|
943
|
+
page_size=page_size,
|
|
944
|
+
page_token=page_token,
|
|
945
|
+
return_all=False,
|
|
946
|
+
**kwargs,
|
|
947
|
+
)
|
|
948
|
+
|
|
949
|
+
def del_runs(
|
|
950
|
+
self,
|
|
951
|
+
name: Optional[str] = None,
|
|
952
|
+
project: Optional[str] = None,
|
|
953
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
954
|
+
state: Optional[mlrun.common.runtimes.constants.RunStates] = None,
|
|
955
|
+
days_ago: int = 0,
|
|
956
|
+
):
|
|
910
957
|
"""Delete a group of runs identified by the parameters of the function.
|
|
911
958
|
|
|
912
959
|
Example::
|
|
@@ -915,16 +962,23 @@ class HTTPRunDB(RunDBInterface):
|
|
|
915
962
|
|
|
916
963
|
:param name: Name of the task which the runs belong to.
|
|
917
964
|
:param project: Project to which the runs belong.
|
|
918
|
-
:param labels: Filter runs
|
|
965
|
+
:param labels: Filter runs by label key-value pairs or key existence. This can be provided as:
|
|
966
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
967
|
+
or `{"label": None}` to check for key existence.
|
|
968
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
969
|
+
or just `"label"` for key existence.
|
|
970
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
971
|
+
the specified key-value pairs or key existence.
|
|
919
972
|
:param state: Filter only runs which are in this state.
|
|
920
973
|
:param days_ago: Filter runs whose start time is newer than this parameter.
|
|
921
974
|
"""
|
|
922
975
|
|
|
923
976
|
project = project or config.default_project
|
|
977
|
+
labels = self._parse_labels(labels)
|
|
924
978
|
params = {
|
|
925
979
|
"name": name,
|
|
926
980
|
"project": project,
|
|
927
|
-
"label": labels
|
|
981
|
+
"label": labels,
|
|
928
982
|
"state": state,
|
|
929
983
|
"days_ago": str(days_ago),
|
|
930
984
|
}
|
|
@@ -942,7 +996,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
942
996
|
tag=None,
|
|
943
997
|
project="",
|
|
944
998
|
tree=None,
|
|
945
|
-
):
|
|
999
|
+
) -> dict[str, str]:
|
|
946
1000
|
"""Store an artifact in the DB.
|
|
947
1001
|
|
|
948
1002
|
:param key: Identifying key of the artifact.
|
|
@@ -954,6 +1008,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
954
1008
|
:param tag: Tag of the artifact.
|
|
955
1009
|
:param project: Project that the artifact belongs to.
|
|
956
1010
|
:param tree: The tree (producer id) which generated this artifact.
|
|
1011
|
+
:returns: The stored artifact dictionary.
|
|
957
1012
|
"""
|
|
958
1013
|
if uid:
|
|
959
1014
|
warnings.warn(
|
|
@@ -978,9 +1033,10 @@ class HTTPRunDB(RunDBInterface):
|
|
|
978
1033
|
params["tree"] = tree
|
|
979
1034
|
|
|
980
1035
|
body = _as_json(artifact)
|
|
981
|
-
self.api_call(
|
|
1036
|
+
response = self.api_call(
|
|
982
1037
|
"PUT", endpoint_path, error, body=body, params=params, version="v2"
|
|
983
1038
|
)
|
|
1039
|
+
return response.json()
|
|
984
1040
|
|
|
985
1041
|
def read_artifact(
|
|
986
1042
|
self,
|
|
@@ -1028,7 +1084,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1028
1084
|
deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
|
|
1029
1085
|
mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
|
|
1030
1086
|
),
|
|
1031
|
-
secrets: dict = None,
|
|
1087
|
+
secrets: Optional[dict] = None,
|
|
1032
1088
|
iter=None,
|
|
1033
1089
|
):
|
|
1034
1090
|
"""Delete an artifact.
|
|
@@ -1063,29 +1119,39 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1063
1119
|
|
|
1064
1120
|
def list_artifacts(
|
|
1065
1121
|
self,
|
|
1066
|
-
name=None,
|
|
1067
|
-
project=None,
|
|
1068
|
-
tag=None,
|
|
1069
|
-
labels: Optional[Union[dict[str, str], list[str]]] = None,
|
|
1122
|
+
name: Optional[str] = None,
|
|
1123
|
+
project: Optional[str] = None,
|
|
1124
|
+
tag: Optional[str] = None,
|
|
1125
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
1070
1126
|
since: Optional[datetime] = None,
|
|
1071
1127
|
until: Optional[datetime] = None,
|
|
1072
|
-
iter: int = None,
|
|
1128
|
+
iter: Optional[int] = None,
|
|
1073
1129
|
best_iteration: bool = False,
|
|
1074
|
-
kind: str = None,
|
|
1130
|
+
kind: Optional[str] = None,
|
|
1075
1131
|
category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
|
|
1076
|
-
tree: str = None,
|
|
1077
|
-
producer_uri: str = None,
|
|
1132
|
+
tree: Optional[str] = None,
|
|
1133
|
+
producer_uri: Optional[str] = None,
|
|
1078
1134
|
format_: Optional[
|
|
1079
1135
|
mlrun.common.formatters.ArtifactFormat
|
|
1080
1136
|
] = mlrun.common.formatters.ArtifactFormat.full,
|
|
1081
|
-
limit: int = None,
|
|
1137
|
+
limit: Optional[int] = None,
|
|
1138
|
+
partition_by: Optional[
|
|
1139
|
+
Union[mlrun.common.schemas.ArtifactPartitionByField, str]
|
|
1140
|
+
] = None,
|
|
1141
|
+
rows_per_partition: int = 1,
|
|
1142
|
+
partition_sort_by: Optional[
|
|
1143
|
+
Union[mlrun.common.schemas.SortField, str]
|
|
1144
|
+
] = mlrun.common.schemas.SortField.updated,
|
|
1145
|
+
partition_order: Union[
|
|
1146
|
+
mlrun.common.schemas.OrderType, str
|
|
1147
|
+
] = mlrun.common.schemas.OrderType.desc,
|
|
1082
1148
|
) -> ArtifactList:
|
|
1083
1149
|
"""List artifacts filtered by various parameters.
|
|
1084
1150
|
|
|
1085
1151
|
Examples::
|
|
1086
1152
|
|
|
1087
1153
|
# Show latest version of all artifacts in project
|
|
1088
|
-
latest_artifacts = db.list_artifacts(
|
|
1154
|
+
latest_artifacts = db.list_artifacts(tag="latest", project="iris")
|
|
1089
1155
|
# check different artifact versions for a specific artifact
|
|
1090
1156
|
result_versions = db.list_artifacts("results", tag="*", project="iris")
|
|
1091
1157
|
# Show artifacts with label filters - both uploaded and of binary type
|
|
@@ -1098,8 +1164,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1098
1164
|
``my_Name_1`` or ``surname``.
|
|
1099
1165
|
:param project: Project name.
|
|
1100
1166
|
:param tag: Return artifacts assigned this tag.
|
|
1101
|
-
:param labels:
|
|
1102
|
-
|
|
1167
|
+
:param labels: Filter artifacts by label key-value pairs or key existence. This can be provided as:
|
|
1168
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
1169
|
+
or `{"label": None}` to check for key existence.
|
|
1170
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
1171
|
+
or just `"label"` for key existence.
|
|
1172
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
1173
|
+
the specified key-value pairs or key existence.
|
|
1103
1174
|
:param since: Return artifacts updated after this date (as datetime object).
|
|
1104
1175
|
:param until: Return artifacts updated before this date (as datetime object).
|
|
1105
1176
|
:param iter: Return artifacts from a specific iteration (where ``iter=0`` means the root iteration). If
|
|
@@ -1115,38 +1186,110 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1115
1186
|
is a workflow id (artifact was created as part of a workflow).
|
|
1116
1187
|
:param format_: The format in which to return the artifacts. Default is 'full'.
|
|
1117
1188
|
:param limit: Maximum number of artifacts to return.
|
|
1189
|
+
:param partition_by: Field to group results by. When `partition_by` is specified, the `partition_sort_by`
|
|
1190
|
+
parameter must be provided as well.
|
|
1191
|
+
:param rows_per_partition: How many top rows (per sorting defined by `partition_sort_by` and `partition_order`)
|
|
1192
|
+
to return per group. Default value is 1.
|
|
1193
|
+
:param partition_sort_by: What field to sort the results by, within each partition defined by `partition_by`.
|
|
1194
|
+
Currently the only allowed values are `created` and `updated`.
|
|
1195
|
+
:param partition_order: Order of sorting within partitions - `asc` or `desc`. Default is `desc`.
|
|
1118
1196
|
"""
|
|
1119
1197
|
|
|
1120
|
-
|
|
1198
|
+
artifacts, _ = self._list_artifacts(
|
|
1199
|
+
name=name,
|
|
1200
|
+
project=project,
|
|
1201
|
+
tag=tag,
|
|
1202
|
+
labels=labels,
|
|
1203
|
+
since=since,
|
|
1204
|
+
until=until,
|
|
1205
|
+
iter=iter,
|
|
1206
|
+
best_iteration=best_iteration,
|
|
1207
|
+
kind=kind,
|
|
1208
|
+
category=category,
|
|
1209
|
+
tree=tree,
|
|
1210
|
+
producer_uri=producer_uri,
|
|
1211
|
+
format_=format_,
|
|
1212
|
+
limit=limit,
|
|
1213
|
+
partition_by=partition_by,
|
|
1214
|
+
rows_per_partition=rows_per_partition,
|
|
1215
|
+
partition_sort_by=partition_sort_by,
|
|
1216
|
+
partition_order=partition_order,
|
|
1217
|
+
return_all=True,
|
|
1218
|
+
)
|
|
1219
|
+
return artifacts
|
|
1121
1220
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1221
|
+
def paginated_list_artifacts(
|
|
1222
|
+
self,
|
|
1223
|
+
*args,
|
|
1224
|
+
page: Optional[int] = None,
|
|
1225
|
+
page_size: Optional[int] = None,
|
|
1226
|
+
page_token: Optional[str] = None,
|
|
1227
|
+
**kwargs,
|
|
1228
|
+
) -> tuple[ArtifactList, Optional[str]]:
|
|
1229
|
+
"""List artifacts with support for pagination and various filtering options.
|
|
1125
1230
|
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1231
|
+
This method retrieves a paginated list of artifacts based on the specified filter parameters.
|
|
1232
|
+
Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
|
|
1233
|
+
will return a list of artifacts that match the filtering criteria provided.
|
|
1234
|
+
|
|
1235
|
+
For detailed information about the parameters, refer to the list_artifacts method:
|
|
1236
|
+
See :py:func:`~list_artifacts` for more details.
|
|
1237
|
+
|
|
1238
|
+
Examples::
|
|
1239
|
+
|
|
1240
|
+
# Fetch first page of artifacts with page size of 5
|
|
1241
|
+
artifacts, token = db.paginated_list_artifacts(
|
|
1242
|
+
project="my-project", page_size=5
|
|
1243
|
+
)
|
|
1244
|
+
# Fetch next page using the pagination token from the previous response
|
|
1245
|
+
artifacts, token = db.paginated_list_artifacts(
|
|
1246
|
+
project="my-project", page_token=token
|
|
1247
|
+
)
|
|
1248
|
+
# Fetch artifacts for a specific page (e.g., page 3)
|
|
1249
|
+
artifacts, token = db.paginated_list_artifacts(
|
|
1250
|
+
project="my-project", page=3, page_size=5
|
|
1251
|
+
)
|
|
1252
|
+
|
|
1253
|
+
# Automatically iterate over all pages without explicitly specifying the page number
|
|
1254
|
+
artifacts = []
|
|
1255
|
+
token = None
|
|
1256
|
+
while True:
|
|
1257
|
+
page_artifacts, token = db.paginated_list_artifacts(
|
|
1258
|
+
project="my-project", page_token=token, page_size=5
|
|
1259
|
+
)
|
|
1260
|
+
artifacts.extend(page_artifacts)
|
|
1261
|
+
|
|
1262
|
+
# If token is None and page_artifacts is empty, we've reached the end (no more artifacts).
|
|
1263
|
+
# If token is None and page_artifacts is not empty, we've fetched the last page of artifacts.
|
|
1264
|
+
if not token:
|
|
1265
|
+
break
|
|
1266
|
+
print(f"Total artifacts retrieved: {len(artifacts)}")
|
|
1267
|
+
|
|
1268
|
+
:param page: The page number to retrieve. If not provided, the next page will be retrieved.
|
|
1269
|
+
:param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
|
|
1270
|
+
:param page_token: A pagination token used to retrieve the next page of results. Should not be provided
|
|
1271
|
+
for the first request.
|
|
1272
|
+
|
|
1273
|
+
:returns: A tuple containing the list of artifacts and an optional `page_token` for pagination.
|
|
1274
|
+
"""
|
|
1275
|
+
|
|
1276
|
+
return self._list_artifacts(
|
|
1277
|
+
*args,
|
|
1278
|
+
page=page,
|
|
1279
|
+
page_size=page_size,
|
|
1280
|
+
page_token=page_token,
|
|
1281
|
+
return_all=False,
|
|
1282
|
+
**kwargs,
|
|
1283
|
+
)
|
|
1147
1284
|
|
|
1148
1285
|
def del_artifacts(
|
|
1149
|
-
self,
|
|
1286
|
+
self,
|
|
1287
|
+
name: Optional[str] = None,
|
|
1288
|
+
project: Optional[str] = None,
|
|
1289
|
+
tag: Optional[str] = None,
|
|
1290
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
1291
|
+
days_ago=0,
|
|
1292
|
+
tree: Optional[str] = None,
|
|
1150
1293
|
):
|
|
1151
1294
|
"""Delete artifacts referenced by the parameters.
|
|
1152
1295
|
|
|
@@ -1154,15 +1297,24 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1154
1297
|
:py:func:`~list_artifacts` for more details.
|
|
1155
1298
|
:param project: Project that artifacts belong to.
|
|
1156
1299
|
:param tag: Choose artifacts who are assigned this tag.
|
|
1157
|
-
:param labels:
|
|
1300
|
+
:param labels: Filter artifacts by label key-value pairs or key existence. This can be provided as:
|
|
1301
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
1302
|
+
or `{"label": None}` to check for key existence.
|
|
1303
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
1304
|
+
or just `"label"` for key existence.
|
|
1305
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
1306
|
+
the specified key-value pairs or key existence.
|
|
1158
1307
|
:param days_ago: This parameter is deprecated and not used.
|
|
1308
|
+
:param tree: Delete artifacts filtered by tree.
|
|
1159
1309
|
"""
|
|
1160
1310
|
project = project or config.default_project
|
|
1311
|
+
labels = self._parse_labels(labels)
|
|
1312
|
+
|
|
1161
1313
|
params = {
|
|
1162
1314
|
"name": name,
|
|
1163
1315
|
"tag": tag,
|
|
1164
1316
|
"tree": tree,
|
|
1165
|
-
"label": labels
|
|
1317
|
+
"label": labels,
|
|
1166
1318
|
"days_ago": str(days_ago),
|
|
1167
1319
|
}
|
|
1168
1320
|
error = "del artifacts"
|
|
@@ -1254,30 +1406,110 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1254
1406
|
)
|
|
1255
1407
|
|
|
1256
1408
|
def list_functions(
|
|
1257
|
-
self,
|
|
1409
|
+
self,
|
|
1410
|
+
name: Optional[str] = None,
|
|
1411
|
+
project: Optional[str] = None,
|
|
1412
|
+
tag: Optional[str] = None,
|
|
1413
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
1414
|
+
since: Optional[datetime] = None,
|
|
1415
|
+
until: Optional[datetime] = None,
|
|
1416
|
+
kind: Optional[str] = None,
|
|
1417
|
+
format_: mlrun.common.formatters.FunctionFormat = mlrun.common.formatters.FunctionFormat.full,
|
|
1258
1418
|
):
|
|
1259
1419
|
"""Retrieve a list of functions, filtered by specific criteria.
|
|
1260
1420
|
|
|
1261
1421
|
:param name: Return only functions with a specific name.
|
|
1262
1422
|
:param project: Return functions belonging to this project. If not specified, the default project is used.
|
|
1263
1423
|
:param tag: Return function versions with specific tags. To return only tagged functions, set tag to ``"*"``.
|
|
1264
|
-
:param labels:
|
|
1424
|
+
:param labels: Filter functions by label key-value pairs or key existence. This can be provided as:
|
|
1425
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
1426
|
+
or `{"label": None}` to check for key existence.
|
|
1427
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
1428
|
+
or just `"label"` for key existence.
|
|
1429
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
1430
|
+
the specified key-value pairs or key existence.
|
|
1265
1431
|
:param since: Return functions updated after this date (as datetime object).
|
|
1266
1432
|
:param until: Return functions updated before this date (as datetime object).
|
|
1433
|
+
:param kind: Return only functions of a specific kind.
|
|
1434
|
+
:param format_: The format in which to return the functions. Default is 'full'.
|
|
1267
1435
|
:returns: List of function objects (as dictionary).
|
|
1268
1436
|
"""
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
return
|
|
1437
|
+
functions, _ = self._list_functions(
|
|
1438
|
+
name=name,
|
|
1439
|
+
project=project,
|
|
1440
|
+
tag=tag,
|
|
1441
|
+
kind=kind,
|
|
1442
|
+
labels=labels,
|
|
1443
|
+
format_=format_,
|
|
1444
|
+
since=since,
|
|
1445
|
+
until=until,
|
|
1446
|
+
return_all=True,
|
|
1447
|
+
)
|
|
1448
|
+
return functions
|
|
1449
|
+
|
|
1450
|
+
def paginated_list_functions(
|
|
1451
|
+
self,
|
|
1452
|
+
*args,
|
|
1453
|
+
page: Optional[int] = None,
|
|
1454
|
+
page_size: Optional[int] = None,
|
|
1455
|
+
page_token: Optional[str] = None,
|
|
1456
|
+
**kwargs,
|
|
1457
|
+
) -> tuple[list[dict], Optional[str]]:
|
|
1458
|
+
"""List functions with support for pagination and various filtering options.
|
|
1459
|
+
|
|
1460
|
+
This method retrieves a paginated list of functions based on the specified filter parameters.
|
|
1461
|
+
Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
|
|
1462
|
+
will return a list of functions that match the filtering criteria provided.
|
|
1463
|
+
|
|
1464
|
+
For detailed information about the parameters, refer to the list_functions method:
|
|
1465
|
+
See :py:func:`~list_functions` for more details.
|
|
1466
|
+
|
|
1467
|
+
Examples::
|
|
1468
|
+
|
|
1469
|
+
# Fetch first page of functions with page size of 5
|
|
1470
|
+
functions, token = db.paginated_list_functions(
|
|
1471
|
+
project="my-project", page_size=5
|
|
1472
|
+
)
|
|
1473
|
+
# Fetch next page using the pagination token from the previous response
|
|
1474
|
+
functions, token = db.paginated_list_functions(
|
|
1475
|
+
project="my-project", page_token=token
|
|
1476
|
+
)
|
|
1477
|
+
# Fetch functions for a specific page (e.g., page 3)
|
|
1478
|
+
functions, token = db.paginated_list_functions(
|
|
1479
|
+
project="my-project", page=3, page_size=5
|
|
1480
|
+
)
|
|
1481
|
+
|
|
1482
|
+
# Automatically iterate over all pages without explicitly specifying the page number
|
|
1483
|
+
functions = []
|
|
1484
|
+
token = None
|
|
1485
|
+
while True:
|
|
1486
|
+
page_functions, token = db.paginated_list_functions(
|
|
1487
|
+
project="my-project", page_token=token, page_size=5
|
|
1488
|
+
)
|
|
1489
|
+
functions.extend(page_functions)
|
|
1490
|
+
|
|
1491
|
+
# If token is None and page_functions is empty, we've reached the end (no more functions).
|
|
1492
|
+
# If token is None and page_functions is not empty, we've fetched the last page of functions.
|
|
1493
|
+
if not token:
|
|
1494
|
+
break
|
|
1495
|
+
print(f"Total functions retrieved: {len(functions)}")
|
|
1496
|
+
|
|
1497
|
+
:param page: The page number to retrieve. If not provided, the next page will be retrieved.
|
|
1498
|
+
:param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
|
|
1499
|
+
:param page_token: A pagination token used to retrieve the next page of results. Should not be provided
|
|
1500
|
+
for the first request.
|
|
1501
|
+
|
|
1502
|
+
:returns: A tuple containing the list of functions objects (as dictionary) and an optional
|
|
1503
|
+
`page_token` for pagination.
|
|
1504
|
+
"""
|
|
1505
|
+
return self._list_functions(
|
|
1506
|
+
*args,
|
|
1507
|
+
page=page,
|
|
1508
|
+
page_size=page_size,
|
|
1509
|
+
page_token=page_token,
|
|
1510
|
+
return_all=False,
|
|
1511
|
+
**kwargs,
|
|
1512
|
+
)
|
|
1281
1513
|
|
|
1282
1514
|
def list_runtime_resources(
|
|
1283
1515
|
self,
|
|
@@ -1352,7 +1584,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1352
1584
|
kind: Optional[str] = None,
|
|
1353
1585
|
object_id: Optional[str] = None,
|
|
1354
1586
|
force: bool = False,
|
|
1355
|
-
grace_period: int = None,
|
|
1587
|
+
grace_period: Optional[int] = None,
|
|
1356
1588
|
) -> mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput:
|
|
1357
1589
|
"""Delete all runtime resources which are in terminal state.
|
|
1358
1590
|
|
|
@@ -1464,9 +1696,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1464
1696
|
def list_schedules(
|
|
1465
1697
|
self,
|
|
1466
1698
|
project: str,
|
|
1467
|
-
name: str = None,
|
|
1699
|
+
name: Optional[str] = None,
|
|
1468
1700
|
kind: mlrun.common.schemas.ScheduleKinds = None,
|
|
1469
1701
|
include_last_run: bool = False,
|
|
1702
|
+
next_run_time_since: Optional[datetime] = None,
|
|
1703
|
+
next_run_time_until: Optional[datetime] = None,
|
|
1470
1704
|
) -> mlrun.common.schemas.SchedulesOutput:
|
|
1471
1705
|
"""Retrieve list of schedules of specific name or kind.
|
|
1472
1706
|
|
|
@@ -1475,10 +1709,18 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1475
1709
|
:param kind: Kind of schedule objects to retrieve, can be either ``job`` or ``pipeline``.
|
|
1476
1710
|
:param include_last_run: Whether to return for each schedule returned also the results of the last run of
|
|
1477
1711
|
that schedule.
|
|
1712
|
+
:param next_run_time_since: Return only schedules with next run time after this date.
|
|
1713
|
+
:param next_run_time_until: Return only schedules with next run time before this date.
|
|
1478
1714
|
"""
|
|
1479
1715
|
|
|
1480
1716
|
project = project or config.default_project
|
|
1481
|
-
params = {
|
|
1717
|
+
params = {
|
|
1718
|
+
"kind": kind,
|
|
1719
|
+
"name": name,
|
|
1720
|
+
"include_last_run": include_last_run,
|
|
1721
|
+
"next_run_time_since": datetime_to_iso(next_run_time_since),
|
|
1722
|
+
"next_run_time_until": datetime_to_iso(next_run_time_until),
|
|
1723
|
+
}
|
|
1482
1724
|
path = f"projects/{project}/schedules"
|
|
1483
1725
|
error_message = f"Failed listing schedules for {project} ? {kind} {name}"
|
|
1484
1726
|
resp = self.api_call("GET", path, error_message, params=params)
|
|
@@ -1636,6 +1878,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1636
1878
|
logs: bool = True,
|
|
1637
1879
|
last_log_timestamp: float = 0.0,
|
|
1638
1880
|
verbose: bool = False,
|
|
1881
|
+
events_offset: int = 0,
|
|
1639
1882
|
):
|
|
1640
1883
|
"""Retrieve the status of a build operation currently in progress.
|
|
1641
1884
|
|
|
@@ -1645,6 +1888,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1645
1888
|
:param last_log_timestamp: Last timestamp of logs that were already retrieved. Function will return only logs
|
|
1646
1889
|
later than this parameter.
|
|
1647
1890
|
:param verbose: Add verbose logs into the output.
|
|
1891
|
+
:param events_offset: Offset into the build events to retrieve events from.
|
|
1648
1892
|
|
|
1649
1893
|
:returns: The following parameters:
|
|
1650
1894
|
|
|
@@ -1661,6 +1905,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1661
1905
|
"tag": func.metadata.tag,
|
|
1662
1906
|
"logs": bool2str(logs),
|
|
1663
1907
|
"offset": str(offset),
|
|
1908
|
+
"events_offset": str(events_offset),
|
|
1664
1909
|
"last_log_timestamp": str(last_log_timestamp),
|
|
1665
1910
|
"verbose": bool2str(verbose),
|
|
1666
1911
|
}
|
|
@@ -1673,6 +1918,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1673
1918
|
logger.warning(f"failed resp, {resp.text}")
|
|
1674
1919
|
raise RunDBError("bad function build response")
|
|
1675
1920
|
|
|
1921
|
+
deploy_status_text_kind = mlrun.common.constants.DeployStatusTextKind.logs
|
|
1676
1922
|
if resp.headers:
|
|
1677
1923
|
func.status.state = resp.headers.get("x-mlrun-function-status", "")
|
|
1678
1924
|
last_log_timestamp = float(
|
|
@@ -1691,13 +1937,20 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1691
1937
|
if function_image:
|
|
1692
1938
|
func.spec.image = function_image
|
|
1693
1939
|
|
|
1940
|
+
deploy_status_text_kind = resp.headers.get(
|
|
1941
|
+
"deploy_status_text_kind",
|
|
1942
|
+
mlrun.common.constants.DeployStatusTextKind.logs,
|
|
1943
|
+
)
|
|
1944
|
+
|
|
1694
1945
|
text = ""
|
|
1695
1946
|
if resp.content:
|
|
1696
1947
|
text = resp.content.decode()
|
|
1697
|
-
return text, last_log_timestamp
|
|
1948
|
+
return text, last_log_timestamp, deploy_status_text_kind
|
|
1698
1949
|
|
|
1699
1950
|
def start_function(
|
|
1700
|
-
self,
|
|
1951
|
+
self,
|
|
1952
|
+
func_url: Optional[str] = None,
|
|
1953
|
+
function: "mlrun.runtimes.BaseRuntime" = None,
|
|
1701
1954
|
) -> mlrun.common.schemas.BackgroundTask:
|
|
1702
1955
|
"""Execute a function remotely, Used for ``dask`` functions.
|
|
1703
1956
|
|
|
@@ -1939,14 +2192,14 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1939
2192
|
def list_pipelines(
|
|
1940
2193
|
self,
|
|
1941
2194
|
project: str,
|
|
1942
|
-
namespace: str = None,
|
|
2195
|
+
namespace: Optional[str] = None,
|
|
1943
2196
|
sort_by: str = "",
|
|
1944
2197
|
page_token: str = "",
|
|
1945
2198
|
filter_: str = "",
|
|
1946
2199
|
format_: Union[
|
|
1947
2200
|
str, mlrun.common.formatters.PipelineFormat
|
|
1948
2201
|
] = mlrun.common.formatters.PipelineFormat.metadata_only,
|
|
1949
|
-
page_size: int = None,
|
|
2202
|
+
page_size: Optional[int] = None,
|
|
1950
2203
|
) -> mlrun.common.schemas.PipelinesOutput:
|
|
1951
2204
|
"""Retrieve a list of KFP pipelines. This function can be invoked to get all pipelines from all projects,
|
|
1952
2205
|
by specifying ``project=*``, in which case pagination can be used and the various sorting and pagination
|
|
@@ -1988,12 +2241,12 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1988
2241
|
def get_pipeline(
|
|
1989
2242
|
self,
|
|
1990
2243
|
run_id: str,
|
|
1991
|
-
namespace: str = None,
|
|
2244
|
+
namespace: Optional[str] = None,
|
|
1992
2245
|
timeout: int = 30,
|
|
1993
2246
|
format_: Union[
|
|
1994
2247
|
str, mlrun.common.formatters.PipelineFormat
|
|
1995
2248
|
] = mlrun.common.formatters.PipelineFormat.summary,
|
|
1996
|
-
project: str = None,
|
|
2249
|
+
project: Optional[str] = None,
|
|
1997
2250
|
):
|
|
1998
2251
|
"""Retrieve details of a specific pipeline using its run ID (as provided when the pipeline was executed)."""
|
|
1999
2252
|
|
|
@@ -2015,6 +2268,75 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2015
2268
|
|
|
2016
2269
|
return resp.json()
|
|
2017
2270
|
|
|
2271
|
+
def retry_pipeline(
|
|
2272
|
+
self,
|
|
2273
|
+
run_id: str,
|
|
2274
|
+
namespace: Optional[str] = None,
|
|
2275
|
+
timeout: int = 30,
|
|
2276
|
+
project: Optional[str] = None,
|
|
2277
|
+
):
|
|
2278
|
+
"""
|
|
2279
|
+
Retry a specific pipeline run using its run ID. This function sends an API request
|
|
2280
|
+
to retry a pipeline run. If a project is specified, the run must belong to that
|
|
2281
|
+
project; otherwise, all projects are queried.
|
|
2282
|
+
|
|
2283
|
+
:param run_id: The unique ID of the pipeline run to retry.
|
|
2284
|
+
:param namespace: Kubernetes namespace where the pipeline is running. Optional.
|
|
2285
|
+
:param timeout: Timeout (in seconds) for the API call. Defaults to 30 seconds.
|
|
2286
|
+
:param project: Name of the MLRun project associated with the pipeline. Can be
|
|
2287
|
+
``*`` to query across all projects. Optional.
|
|
2288
|
+
|
|
2289
|
+
:raises ValueError: Raised if the API response is not successful or contains an
|
|
2290
|
+
error.
|
|
2291
|
+
|
|
2292
|
+
:return: JSON response containing details of the retried pipeline run.
|
|
2293
|
+
"""
|
|
2294
|
+
|
|
2295
|
+
params = {}
|
|
2296
|
+
if namespace:
|
|
2297
|
+
params["namespace"] = namespace
|
|
2298
|
+
project_path = project if project else "*"
|
|
2299
|
+
|
|
2300
|
+
resp_text = ""
|
|
2301
|
+
resp_code = None
|
|
2302
|
+
try:
|
|
2303
|
+
resp = self.api_call(
|
|
2304
|
+
"POST",
|
|
2305
|
+
f"projects/{project_path}/pipelines/{run_id}/retry",
|
|
2306
|
+
params=params,
|
|
2307
|
+
timeout=timeout,
|
|
2308
|
+
)
|
|
2309
|
+
resp_code = resp.status_code
|
|
2310
|
+
resp_text = resp.text
|
|
2311
|
+
if not resp.ok:
|
|
2312
|
+
raise mlrun.errors.MLRunHTTPError(
|
|
2313
|
+
f"Failed to retry pipeline run '{run_id}'. "
|
|
2314
|
+
f"HTTP {resp_code}: {resp_text}"
|
|
2315
|
+
)
|
|
2316
|
+
except Exception as exc:
|
|
2317
|
+
logger.error(
|
|
2318
|
+
"Retry pipeline API call encountered an error.",
|
|
2319
|
+
run_id=run_id,
|
|
2320
|
+
project=project_path,
|
|
2321
|
+
namespace=namespace,
|
|
2322
|
+
response_code=resp_code,
|
|
2323
|
+
response_text=resp_text,
|
|
2324
|
+
error=str(exc),
|
|
2325
|
+
)
|
|
2326
|
+
if isinstance(exc, mlrun.errors.MLRunHTTPError):
|
|
2327
|
+
raise exc # Re-raise known HTTP errors
|
|
2328
|
+
raise mlrun.errors.MLRunRuntimeError(
|
|
2329
|
+
f"Unexpected error while retrying pipeline run '{run_id}'."
|
|
2330
|
+
) from exc
|
|
2331
|
+
|
|
2332
|
+
logger.info(
|
|
2333
|
+
"Successfully retried pipeline run",
|
|
2334
|
+
run_id=run_id,
|
|
2335
|
+
project=project_path,
|
|
2336
|
+
namespace=namespace,
|
|
2337
|
+
)
|
|
2338
|
+
return resp.json()
|
|
2339
|
+
|
|
2018
2340
|
@staticmethod
|
|
2019
2341
|
def _resolve_reference(tag, uid):
|
|
2020
2342
|
if uid and tag:
|
|
@@ -2061,7 +2383,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2061
2383
|
return resp.json()
|
|
2062
2384
|
|
|
2063
2385
|
def get_feature_set(
|
|
2064
|
-
self,
|
|
2386
|
+
self,
|
|
2387
|
+
name: str,
|
|
2388
|
+
project: str = "",
|
|
2389
|
+
tag: Optional[str] = None,
|
|
2390
|
+
uid: Optional[str] = None,
|
|
2065
2391
|
) -> FeatureSet:
|
|
2066
2392
|
"""Retrieve a ~mlrun.feature_store.FeatureSet` object. If both ``tag`` and ``uid`` are not specified, then
|
|
2067
2393
|
the object tagged ``latest`` will be retrieved.
|
|
@@ -2081,11 +2407,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2081
2407
|
|
|
2082
2408
|
def list_features(
|
|
2083
2409
|
self,
|
|
2084
|
-
project: str,
|
|
2085
|
-
name: str = None,
|
|
2086
|
-
tag: str = None,
|
|
2087
|
-
entities: list[str] = None,
|
|
2088
|
-
labels: list[str] = None,
|
|
2410
|
+
project: Optional[str] = None,
|
|
2411
|
+
name: Optional[str] = None,
|
|
2412
|
+
tag: Optional[str] = None,
|
|
2413
|
+
entities: Optional[list[str]] = None,
|
|
2414
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2089
2415
|
) -> list[dict]:
|
|
2090
2416
|
"""List feature-sets which contain specific features. This function may return multiple versions of the same
|
|
2091
2417
|
feature-set if a specific tag is not requested. Note that the various filters of this function actually
|
|
@@ -2096,18 +2422,25 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2096
2422
|
example, looking for ``feat`` will return features which are named ``MyFeature`` as well as ``defeat``.
|
|
2097
2423
|
:param tag: Return feature-sets which contain the features looked for, and are tagged with the specific tag.
|
|
2098
2424
|
:param entities: Return only feature-sets which contain an entity whose name is contained in this list.
|
|
2099
|
-
:param labels:
|
|
2425
|
+
:param labels: Filter feature-sets by label key-value pairs or key existence. This can be provided as:
|
|
2426
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
2427
|
+
or `{"label": None}` to check for key existence.
|
|
2428
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
2429
|
+
or just `"label"` for key existence.
|
|
2430
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
2431
|
+
the specified key-value pairs or key existence.
|
|
2100
2432
|
:returns: A list of mapping from feature to a digest of the feature-set, which contains the feature-set
|
|
2101
2433
|
meta-data. Multiple entries may be returned for any specific feature due to multiple tags or versions
|
|
2102
2434
|
of the feature-set.
|
|
2103
2435
|
"""
|
|
2104
2436
|
|
|
2105
2437
|
project = project or config.default_project
|
|
2438
|
+
labels = self._parse_labels(labels)
|
|
2106
2439
|
params = {
|
|
2107
2440
|
"name": name,
|
|
2108
2441
|
"tag": tag,
|
|
2109
2442
|
"entity": entities or [],
|
|
2110
|
-
"label": labels
|
|
2443
|
+
"label": labels,
|
|
2111
2444
|
}
|
|
2112
2445
|
|
|
2113
2446
|
path = f"projects/{project}/features"
|
|
@@ -2118,11 +2451,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2118
2451
|
|
|
2119
2452
|
def list_features_v2(
|
|
2120
2453
|
self,
|
|
2121
|
-
project: str,
|
|
2122
|
-
name: str = None,
|
|
2123
|
-
tag: str = None,
|
|
2124
|
-
entities: list[str] = None,
|
|
2125
|
-
labels: list[str] = None,
|
|
2454
|
+
project: Optional[str] = None,
|
|
2455
|
+
name: Optional[str] = None,
|
|
2456
|
+
tag: Optional[str] = None,
|
|
2457
|
+
entities: Optional[list[str]] = None,
|
|
2458
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2126
2459
|
) -> dict[str, list[dict]]:
|
|
2127
2460
|
"""List feature-sets which contain specific features. This function may return multiple versions of the same
|
|
2128
2461
|
feature-set if a specific tag is not requested. Note that the various filters of this function actually
|
|
@@ -2133,16 +2466,23 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2133
2466
|
example, looking for ``feat`` will return features which are named ``MyFeature`` as well as ``defeat``.
|
|
2134
2467
|
:param tag: Return feature-sets which contain the features looked for, and are tagged with the specific tag.
|
|
2135
2468
|
:param entities: Return only feature-sets which contain an entity whose name is contained in this list.
|
|
2136
|
-
:param labels:
|
|
2469
|
+
:param labels: Filter feature-sets by label key-value pairs or key existence. This can be provided as:
|
|
2470
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
2471
|
+
or `{"label": None}` to check for key existence.
|
|
2472
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
2473
|
+
or just `"label"` for key existence.
|
|
2474
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
2475
|
+
the specified key-value pairs or key existence.
|
|
2137
2476
|
:returns: A list of features, and a list of their corresponding feature sets.
|
|
2138
2477
|
"""
|
|
2139
2478
|
|
|
2140
2479
|
project = project or config.default_project
|
|
2480
|
+
labels = self._parse_labels(labels)
|
|
2141
2481
|
params = {
|
|
2142
2482
|
"name": name,
|
|
2143
2483
|
"tag": tag,
|
|
2144
2484
|
"entity": entities or [],
|
|
2145
|
-
"label": labels
|
|
2485
|
+
"label": labels,
|
|
2146
2486
|
}
|
|
2147
2487
|
|
|
2148
2488
|
path = f"projects/{project}/features"
|
|
@@ -2153,21 +2493,34 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2153
2493
|
|
|
2154
2494
|
def list_entities(
|
|
2155
2495
|
self,
|
|
2156
|
-
project: str,
|
|
2157
|
-
name: str = None,
|
|
2158
|
-
tag: str = None,
|
|
2159
|
-
labels: list[str] = None,
|
|
2496
|
+
project: Optional[str] = None,
|
|
2497
|
+
name: Optional[str] = None,
|
|
2498
|
+
tag: Optional[str] = None,
|
|
2499
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2160
2500
|
) -> list[dict]:
|
|
2161
2501
|
"""Retrieve a list of entities and their mapping to the containing feature-sets. This function is similar
|
|
2162
2502
|
to the :py:func:`~list_features` function, and uses the same logic. However, the entities are matched
|
|
2163
2503
|
against the name rather than the features.
|
|
2504
|
+
|
|
2505
|
+
:param project: The project containing the entities.
|
|
2506
|
+
:param name: The name of the entities to retrieve.
|
|
2507
|
+
:param tag: The tag of the specific entity version to retrieve.
|
|
2508
|
+
:param labels: Filter entities by label key-value pairs or key existence. This can be provided as:
|
|
2509
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
2510
|
+
or `{"label": None}` to check for key existence.
|
|
2511
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
2512
|
+
or just `"label"` for key existence.
|
|
2513
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
2514
|
+
the specified key-value pairs or key existence.
|
|
2515
|
+
:returns: A list of entities.
|
|
2164
2516
|
"""
|
|
2165
2517
|
|
|
2166
2518
|
project = project or config.default_project
|
|
2519
|
+
labels = self._parse_labels(labels)
|
|
2167
2520
|
params = {
|
|
2168
2521
|
"name": name,
|
|
2169
2522
|
"tag": tag,
|
|
2170
|
-
"label": labels
|
|
2523
|
+
"label": labels,
|
|
2171
2524
|
}
|
|
2172
2525
|
|
|
2173
2526
|
path = f"projects/{project}/entities"
|
|
@@ -2178,21 +2531,34 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2178
2531
|
|
|
2179
2532
|
def list_entities_v2(
|
|
2180
2533
|
self,
|
|
2181
|
-
project: str,
|
|
2182
|
-
name: str = None,
|
|
2183
|
-
tag: str = None,
|
|
2184
|
-
labels: list[str] = None,
|
|
2534
|
+
project: Optional[str] = None,
|
|
2535
|
+
name: Optional[str] = None,
|
|
2536
|
+
tag: Optional[str] = None,
|
|
2537
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2185
2538
|
) -> dict[str, list[dict]]:
|
|
2186
2539
|
"""Retrieve a list of entities and their mapping to the containing feature-sets. This function is similar
|
|
2187
2540
|
to the :py:func:`~list_features_v2` function, and uses the same logic. However, the entities are matched
|
|
2188
2541
|
against the name rather than the features.
|
|
2542
|
+
|
|
2543
|
+
:param project: The project containing the entities.
|
|
2544
|
+
:param name: The name of the entities to retrieve.
|
|
2545
|
+
:param tag: The tag of the specific entity version to retrieve.
|
|
2546
|
+
:param labels: Filter entities by label key-value pairs or key existence. This can be provided as:
|
|
2547
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
2548
|
+
or `{"label": None}` to check for key existence.
|
|
2549
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
2550
|
+
or just `"label"` for key existence.
|
|
2551
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
2552
|
+
the specified key-value pairs or key existence.
|
|
2553
|
+
:returns: A list of entities.
|
|
2189
2554
|
"""
|
|
2190
2555
|
|
|
2191
2556
|
project = project or config.default_project
|
|
2557
|
+
labels = self._parse_labels(labels)
|
|
2192
2558
|
params = {
|
|
2193
2559
|
"name": name,
|
|
2194
2560
|
"tag": tag,
|
|
2195
|
-
"label": labels
|
|
2561
|
+
"label": labels,
|
|
2196
2562
|
}
|
|
2197
2563
|
|
|
2198
2564
|
path = f"projects/{project}/entities"
|
|
@@ -2203,7 +2569,6 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2203
2569
|
|
|
2204
2570
|
@staticmethod
|
|
2205
2571
|
def _generate_partition_by_params(
|
|
2206
|
-
partition_by_cls,
|
|
2207
2572
|
partition_by,
|
|
2208
2573
|
rows_per_partition,
|
|
2209
2574
|
sort_by,
|
|
@@ -2222,13 +2587,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2222
2587
|
|
|
2223
2588
|
def list_feature_sets(
|
|
2224
2589
|
self,
|
|
2225
|
-
project: str =
|
|
2226
|
-
name: str = None,
|
|
2227
|
-
tag: str = None,
|
|
2228
|
-
state: str = None,
|
|
2229
|
-
entities: list[str] = None,
|
|
2230
|
-
features: list[str] = None,
|
|
2231
|
-
labels: list[str] = None,
|
|
2590
|
+
project: Optional[str] = None,
|
|
2591
|
+
name: Optional[str] = None,
|
|
2592
|
+
tag: Optional[str] = None,
|
|
2593
|
+
state: Optional[str] = None,
|
|
2594
|
+
entities: Optional[list[str]] = None,
|
|
2595
|
+
features: Optional[list[str]] = None,
|
|
2596
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2232
2597
|
partition_by: Union[
|
|
2233
2598
|
mlrun.common.schemas.FeatureStorePartitionByField, str
|
|
2234
2599
|
] = None,
|
|
@@ -2249,7 +2614,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2249
2614
|
:param state: Match feature-sets with a specific state.
|
|
2250
2615
|
:param entities: Match feature-sets which contain entities whose name is in this list.
|
|
2251
2616
|
:param features: Match feature-sets which contain features whose name is in this list.
|
|
2252
|
-
:param labels:
|
|
2617
|
+
:param labels: Filter feature-sets by label key-value pairs or key existence. This can be provided as:
|
|
2618
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
2619
|
+
or `{"label": None}` to check for key existence.
|
|
2620
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
2621
|
+
or just `"label"` for key existence.
|
|
2622
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
2623
|
+
the specified key-value pairs or key existence.
|
|
2253
2624
|
:param partition_by: Field to group results by. Only allowed value is `name`. When `partition_by` is specified,
|
|
2254
2625
|
the `partition_sort_by` parameter must be provided as well.
|
|
2255
2626
|
:param rows_per_partition: How many top rows (per sorting defined by `partition_sort_by` and `partition_order`)
|
|
@@ -2264,20 +2635,19 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2264
2635
|
"""
|
|
2265
2636
|
|
|
2266
2637
|
project = project or config.default_project
|
|
2267
|
-
|
|
2638
|
+
labels = self._parse_labels(labels)
|
|
2268
2639
|
params = {
|
|
2269
2640
|
"name": name,
|
|
2270
2641
|
"state": state,
|
|
2271
2642
|
"tag": tag,
|
|
2272
2643
|
"entity": entities or [],
|
|
2273
2644
|
"feature": features or [],
|
|
2274
|
-
"label": labels
|
|
2645
|
+
"label": labels,
|
|
2275
2646
|
"format": format_,
|
|
2276
2647
|
}
|
|
2277
2648
|
if partition_by:
|
|
2278
2649
|
params.update(
|
|
2279
2650
|
self._generate_partition_by_params(
|
|
2280
|
-
mlrun.common.schemas.FeatureStorePartitionByField,
|
|
2281
2651
|
partition_by,
|
|
2282
2652
|
rows_per_partition,
|
|
2283
2653
|
partition_sort_by,
|
|
@@ -2436,7 +2806,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2436
2806
|
return resp.json()
|
|
2437
2807
|
|
|
2438
2808
|
def get_feature_vector(
|
|
2439
|
-
self,
|
|
2809
|
+
self,
|
|
2810
|
+
name: str,
|
|
2811
|
+
project: str = "",
|
|
2812
|
+
tag: Optional[str] = None,
|
|
2813
|
+
uid: Optional[str] = None,
|
|
2440
2814
|
) -> FeatureVector:
|
|
2441
2815
|
"""Return a specific feature-vector referenced by its tag or uid. If none are provided, ``latest`` tag will
|
|
2442
2816
|
be used."""
|
|
@@ -2450,11 +2824,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2450
2824
|
|
|
2451
2825
|
def list_feature_vectors(
|
|
2452
2826
|
self,
|
|
2453
|
-
project: str =
|
|
2454
|
-
name: str = None,
|
|
2455
|
-
tag: str = None,
|
|
2456
|
-
state: str = None,
|
|
2457
|
-
labels: list[str] = None,
|
|
2827
|
+
project: Optional[str] = None,
|
|
2828
|
+
name: Optional[str] = None,
|
|
2829
|
+
tag: Optional[str] = None,
|
|
2830
|
+
state: Optional[str] = None,
|
|
2831
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2458
2832
|
partition_by: Union[
|
|
2459
2833
|
mlrun.common.schemas.FeatureStorePartitionByField, str
|
|
2460
2834
|
] = None,
|
|
@@ -2470,7 +2844,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2470
2844
|
:param name: Name of feature-vector to match. This is a like query, and is case-insensitive.
|
|
2471
2845
|
:param tag: Match feature-vectors with specific tag.
|
|
2472
2846
|
:param state: Match feature-vectors with a specific state.
|
|
2473
|
-
:param labels:
|
|
2847
|
+
:param labels: Filter feature-vectors by label key-value pairs or key existence. This can be provided as:
|
|
2848
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
2849
|
+
or `{"label": None}` to check for key existence.
|
|
2850
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
2851
|
+
or just `"label"` for key existence.
|
|
2852
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
2853
|
+
the specified key-value pairs or key existence.
|
|
2474
2854
|
:param partition_by: Field to group results by. Only allowed value is `name`. When `partition_by` is specified,
|
|
2475
2855
|
the `partition_sort_by` parameter must be provided as well.
|
|
2476
2856
|
:param rows_per_partition: How many top rows (per sorting defined by `partition_sort_by` and `partition_order`)
|
|
@@ -2482,17 +2862,16 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2482
2862
|
"""
|
|
2483
2863
|
|
|
2484
2864
|
project = project or config.default_project
|
|
2485
|
-
|
|
2865
|
+
labels = self._parse_labels(labels)
|
|
2486
2866
|
params = {
|
|
2487
2867
|
"name": name,
|
|
2488
2868
|
"state": state,
|
|
2489
2869
|
"tag": tag,
|
|
2490
|
-
"label": labels
|
|
2870
|
+
"label": labels,
|
|
2491
2871
|
}
|
|
2492
2872
|
if partition_by:
|
|
2493
2873
|
params.update(
|
|
2494
2874
|
self._generate_partition_by_params(
|
|
2495
|
-
mlrun.common.schemas.FeatureStorePartitionByField,
|
|
2496
2875
|
partition_by,
|
|
2497
2876
|
rows_per_partition,
|
|
2498
2877
|
partition_sort_by,
|
|
@@ -2699,11 +3078,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2699
3078
|
|
|
2700
3079
|
def list_projects(
|
|
2701
3080
|
self,
|
|
2702
|
-
owner: str = None,
|
|
3081
|
+
owner: Optional[str] = None,
|
|
2703
3082
|
format_: Union[
|
|
2704
3083
|
str, mlrun.common.formatters.ProjectFormat
|
|
2705
3084
|
] = mlrun.common.formatters.ProjectFormat.name_only,
|
|
2706
|
-
labels: list[str] = None,
|
|
3085
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
2707
3086
|
state: Union[str, mlrun.common.schemas.ProjectState] = None,
|
|
2708
3087
|
) -> list[Union[mlrun.projects.MlrunProject, str]]:
|
|
2709
3088
|
"""Return a list of the existing projects, potentially filtered by specific criteria.
|
|
@@ -2715,15 +3094,22 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2715
3094
|
- ``minimal`` - Return minimal project objects (minimization happens in the BE).
|
|
2716
3095
|
- ``full`` - Return full project objects.
|
|
2717
3096
|
|
|
2718
|
-
:param labels: Filter by
|
|
3097
|
+
:param labels: Filter projects by label key-value pairs or key existence. This can be provided as:
|
|
3098
|
+
- A dictionary in the format `{"label": "value"}` to match specific label key-value pairs,
|
|
3099
|
+
or `{"label": None}` to check for key existence.
|
|
3100
|
+
- A list of strings formatted as `"label=value"` to match specific label key-value pairs,
|
|
3101
|
+
or just `"label"` for key existence.
|
|
3102
|
+
- A comma-separated string formatted as `"label1=value1,label2"` to match entities with
|
|
3103
|
+
the specified key-value pairs or key existence.
|
|
2719
3104
|
:param state: Filter by project's state. Can be either ``online`` or ``archived``.
|
|
2720
3105
|
"""
|
|
3106
|
+
labels = self._parse_labels(labels)
|
|
2721
3107
|
|
|
2722
3108
|
params = {
|
|
2723
3109
|
"owner": owner,
|
|
2724
3110
|
"state": state,
|
|
2725
3111
|
"format": format_,
|
|
2726
|
-
"label": labels
|
|
3112
|
+
"label": labels,
|
|
2727
3113
|
}
|
|
2728
3114
|
|
|
2729
3115
|
error_message = f"Failed listing projects, query: {params}"
|
|
@@ -2739,7 +3125,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2739
3125
|
for project_dict in response.json()["projects"]
|
|
2740
3126
|
]
|
|
2741
3127
|
|
|
2742
|
-
def get_project(self, name: str) -> mlrun.
|
|
3128
|
+
def get_project(self, name: str) -> "mlrun.MlrunProject":
|
|
2743
3129
|
"""Get details for a specific project."""
|
|
2744
3130
|
|
|
2745
3131
|
if not name:
|
|
@@ -2748,7 +3134,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2748
3134
|
path = f"projects/{name}"
|
|
2749
3135
|
error_message = f"Failed retrieving project {name}"
|
|
2750
3136
|
response = self.api_call("GET", path, error_message)
|
|
2751
|
-
return mlrun.
|
|
3137
|
+
return mlrun.MlrunProject.from_dict(response.json())
|
|
2752
3138
|
|
|
2753
3139
|
def delete_project(
|
|
2754
3140
|
self,
|
|
@@ -2919,7 +3305,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2919
3305
|
provider: Union[
|
|
2920
3306
|
str, mlrun.common.schemas.SecretProviderName
|
|
2921
3307
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2922
|
-
secrets: dict = None,
|
|
3308
|
+
secrets: Optional[dict] = None,
|
|
2923
3309
|
):
|
|
2924
3310
|
"""Create project-context secrets using either ``vault`` or ``kubernetes`` provider.
|
|
2925
3311
|
When using with Vault, this will create needed Vault structures for storing secrets in project-context, and
|
|
@@ -2963,11 +3349,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2963
3349
|
def list_project_secrets(
|
|
2964
3350
|
self,
|
|
2965
3351
|
project: str,
|
|
2966
|
-
token: str = None,
|
|
3352
|
+
token: Optional[str] = None,
|
|
2967
3353
|
provider: Union[
|
|
2968
3354
|
str, mlrun.common.schemas.SecretProviderName
|
|
2969
3355
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2970
|
-
secrets: list[str] = None,
|
|
3356
|
+
secrets: Optional[list[str]] = None,
|
|
2971
3357
|
) -> mlrun.common.schemas.SecretsData:
|
|
2972
3358
|
"""Retrieve project-context secrets from Vault.
|
|
2973
3359
|
|
|
@@ -3010,7 +3396,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3010
3396
|
provider: Union[
|
|
3011
3397
|
str, mlrun.common.schemas.SecretProviderName
|
|
3012
3398
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
3013
|
-
token: str = None,
|
|
3399
|
+
token: Optional[str] = None,
|
|
3014
3400
|
) -> mlrun.common.schemas.SecretKeysData:
|
|
3015
3401
|
"""Retrieve project-context secret keys from Vault or Kubernetes.
|
|
3016
3402
|
|
|
@@ -3056,7 +3442,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3056
3442
|
provider: Union[
|
|
3057
3443
|
str, mlrun.common.schemas.SecretProviderName
|
|
3058
3444
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
3059
|
-
secrets: list[str] = None,
|
|
3445
|
+
secrets: Optional[list[str]] = None,
|
|
3060
3446
|
):
|
|
3061
3447
|
"""Delete project-context secrets from Kubernetes.
|
|
3062
3448
|
|
|
@@ -3076,13 +3462,44 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3076
3462
|
params=params,
|
|
3077
3463
|
)
|
|
3078
3464
|
|
|
3465
|
+
def get_model_endpoint_monitoring_metrics(
|
|
3466
|
+
self,
|
|
3467
|
+
project: str,
|
|
3468
|
+
endpoint_id: str,
|
|
3469
|
+
type: Literal["results", "metrics", "all"] = "all",
|
|
3470
|
+
) -> list[mm_endpoints.ModelEndpointMonitoringMetric]:
|
|
3471
|
+
"""Get application metrics/results by endpoint id and project.
|
|
3472
|
+
|
|
3473
|
+
:param project: The name of the project.
|
|
3474
|
+
:param endpoint_id: The unique id of the model endpoint.
|
|
3475
|
+
:param type: The type of the metrics to return. "all" means "results" and "metrics".
|
|
3476
|
+
|
|
3477
|
+
:return: A list of the application metrics or/and results for this model endpoint.
|
|
3478
|
+
"""
|
|
3479
|
+
path = f"projects/{project}/model-endpoints/{endpoint_id}/metrics"
|
|
3480
|
+
params = {"type": type}
|
|
3481
|
+
error_message = (
|
|
3482
|
+
f"Failed to get model endpoint monitoring metrics,"
|
|
3483
|
+
f" endpoint_id: {endpoint_id}, project: {project}"
|
|
3484
|
+
)
|
|
3485
|
+
response = self.api_call(
|
|
3486
|
+
mlrun.common.types.HTTPMethod.GET,
|
|
3487
|
+
path,
|
|
3488
|
+
error_message,
|
|
3489
|
+
params=params,
|
|
3490
|
+
)
|
|
3491
|
+
monitoring_metrics = response.json()
|
|
3492
|
+
return parse_obj_as(
|
|
3493
|
+
list[mm_endpoints.ModelEndpointMonitoringMetric], monitoring_metrics
|
|
3494
|
+
)
|
|
3495
|
+
|
|
3079
3496
|
def create_user_secrets(
|
|
3080
3497
|
self,
|
|
3081
3498
|
user: str,
|
|
3082
3499
|
provider: Union[
|
|
3083
3500
|
str, mlrun.common.schemas.SecretProviderName
|
|
3084
3501
|
] = mlrun.common.schemas.SecretProviderName.vault,
|
|
3085
|
-
secrets: dict = None,
|
|
3502
|
+
secrets: Optional[dict] = None,
|
|
3086
3503
|
):
|
|
3087
3504
|
"""Create user-context secret in Vault. Please refer to :py:func:`create_project_secrets` for more details
|
|
3088
3505
|
and status of this functionality.
|
|
@@ -3164,212 +3581,205 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3164
3581
|
|
|
3165
3582
|
def create_model_endpoint(
|
|
3166
3583
|
self,
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
model_endpoint: Union[
|
|
3170
|
-
mlrun.model_monitoring.model_endpoint.ModelEndpoint, dict
|
|
3171
|
-
],
|
|
3172
|
-
):
|
|
3584
|
+
model_endpoint: mlrun.common.schemas.ModelEndpoint,
|
|
3585
|
+
) -> mlrun.common.schemas.ModelEndpoint:
|
|
3173
3586
|
"""
|
|
3174
3587
|
Creates a DB record with the given model_endpoint record.
|
|
3175
3588
|
|
|
3176
|
-
:param project: The name of the project.
|
|
3177
|
-
:param endpoint_id: The id of the endpoint.
|
|
3178
3589
|
:param model_endpoint: An object representing the model endpoint.
|
|
3179
|
-
"""
|
|
3180
3590
|
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
):
|
|
3184
|
-
model_endpoint = model_endpoint.to_dict()
|
|
3591
|
+
:return: The created model endpoint object.
|
|
3592
|
+
"""
|
|
3185
3593
|
|
|
3186
|
-
path = f"projects/{project}/model-endpoints
|
|
3187
|
-
self.api_call(
|
|
3188
|
-
method=
|
|
3594
|
+
path = f"projects/{model_endpoint.metadata.project}/model-endpoints"
|
|
3595
|
+
response = self.api_call(
|
|
3596
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3189
3597
|
path=path,
|
|
3190
|
-
body=
|
|
3598
|
+
body=model_endpoint.json(),
|
|
3191
3599
|
)
|
|
3600
|
+
return mlrun.common.schemas.ModelEndpoint(**response.json())
|
|
3192
3601
|
|
|
3193
3602
|
def delete_model_endpoint(
|
|
3194
3603
|
self,
|
|
3604
|
+
name: str,
|
|
3195
3605
|
project: str,
|
|
3196
|
-
|
|
3606
|
+
function_name: Optional[str] = None,
|
|
3607
|
+
function_tag: Optional[str] = None,
|
|
3608
|
+
endpoint_id: Optional[str] = None,
|
|
3197
3609
|
):
|
|
3198
3610
|
"""
|
|
3199
3611
|
Deletes the DB record of a given model endpoint, project and endpoint_id are used for lookup
|
|
3200
3612
|
|
|
3613
|
+
:param name: The name of the model endpoint
|
|
3201
3614
|
:param project: The name of the project
|
|
3615
|
+
:param function_name: The name of the function
|
|
3616
|
+
:param function_tag: The tag of the function
|
|
3202
3617
|
:param endpoint_id: The id of the endpoint
|
|
3203
3618
|
"""
|
|
3204
|
-
|
|
3205
|
-
|
|
3619
|
+
self._check_model_endpoint_representation(
|
|
3620
|
+
function_name, function_tag, endpoint_id
|
|
3621
|
+
)
|
|
3622
|
+
path = f"projects/{project}/model-endpoints/{name}"
|
|
3206
3623
|
self.api_call(
|
|
3207
|
-
method=
|
|
3624
|
+
method=mlrun.common.types.HTTPMethod.DELETE,
|
|
3208
3625
|
path=path,
|
|
3626
|
+
params={
|
|
3627
|
+
"function_name": function_name,
|
|
3628
|
+
"function_tag": function_tag,
|
|
3629
|
+
"endpoint_id": endpoint_id,
|
|
3630
|
+
},
|
|
3209
3631
|
)
|
|
3210
3632
|
|
|
3211
3633
|
def list_model_endpoints(
|
|
3212
3634
|
self,
|
|
3213
3635
|
project: str,
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3636
|
+
name: Optional[str] = None,
|
|
3637
|
+
function_name: Optional[str] = None,
|
|
3638
|
+
function_tag: Optional[str] = None,
|
|
3639
|
+
model_name: Optional[str] = None,
|
|
3640
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
3641
|
+
start: Optional[datetime] = None,
|
|
3642
|
+
end: Optional[datetime] = None,
|
|
3643
|
+
tsdb_metrics: bool = True,
|
|
3220
3644
|
top_level: bool = False,
|
|
3221
3645
|
uids: Optional[list[str]] = None,
|
|
3222
|
-
|
|
3646
|
+
latest_only: bool = False,
|
|
3647
|
+
) -> mlrun.common.schemas.ModelEndpointList:
|
|
3648
|
+
"""
|
|
3649
|
+
List model endpoints with optional filtering by name, function name, model name, labels, and time range.
|
|
3650
|
+
|
|
3651
|
+
:param project: The name of the project
|
|
3652
|
+
:param name: The name of the model endpoint
|
|
3653
|
+
:param function_name: The name of the function
|
|
3654
|
+
:param function_tag: The tag of the function
|
|
3655
|
+
:param model_name: The name of the model
|
|
3656
|
+
:param labels: A list of labels to filter by. (see mlrun.common.schemas.LabelsModel)
|
|
3657
|
+
:param start: The start time to filter by.Corresponding to the `created` field.
|
|
3658
|
+
:param end: The end time to filter by. Corresponding to the `created` field.
|
|
3659
|
+
:param tsdb_metrics: Whether to include metrics from the time series DB.
|
|
3660
|
+
:param top_level: Whether to return only top level model endpoints.
|
|
3661
|
+
:param uids: A list of unique ids to filter by.
|
|
3662
|
+
:param latest_only: Whether to return only the latest model endpoint version.
|
|
3663
|
+
:return: A list of model endpoints.
|
|
3223
3664
|
"""
|
|
3224
|
-
Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
|
|
3225
|
-
model endpoint. This functions supports filtering by the following parameters:
|
|
3226
|
-
1) model
|
|
3227
|
-
2) function
|
|
3228
|
-
3) labels
|
|
3229
|
-
4) top level
|
|
3230
|
-
5) uids
|
|
3231
|
-
By default, when no filters are applied, all available endpoints for the given project will be listed.
|
|
3232
|
-
|
|
3233
|
-
In addition, this functions provides a facade for listing endpoint related metrics. This facade is time-based
|
|
3234
|
-
and depends on the 'start' and 'end' parameters. By default, when the metrics parameter is None, no metrics are
|
|
3235
|
-
added to the output of this function.
|
|
3236
|
-
|
|
3237
|
-
:param project: The name of the project
|
|
3238
|
-
:param model: The name of the model to filter by
|
|
3239
|
-
:param function: The name of the function to filter by
|
|
3240
|
-
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a
|
|
3241
|
-
label (i.e. list("key=value")) or by looking for the existence of a given key (i.e. "key")
|
|
3242
|
-
:param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
|
|
3243
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time, a
|
|
3244
|
-
Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
|
|
3245
|
-
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3246
|
-
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time, a
|
|
3247
|
-
Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
|
|
3248
|
-
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3249
|
-
:param top_level: if true will return only routers and endpoint that are NOT children of any router
|
|
3250
|
-
:param uids: if passed will return a list `ModelEndpoint` object with uid in uids
|
|
3251
|
-
"""
|
|
3252
|
-
|
|
3253
3665
|
path = f"projects/{project}/model-endpoints"
|
|
3254
|
-
|
|
3255
|
-
if labels and isinstance(labels, dict):
|
|
3256
|
-
labels = [f"{key}={value}" for key, value in labels.items()]
|
|
3666
|
+
labels = self._parse_labels(labels)
|
|
3257
3667
|
|
|
3258
3668
|
response = self.api_call(
|
|
3259
|
-
method=
|
|
3669
|
+
method=mlrun.common.types.HTTPMethod.GET,
|
|
3260
3670
|
path=path,
|
|
3261
3671
|
params={
|
|
3262
|
-
"
|
|
3263
|
-
"
|
|
3264
|
-
"
|
|
3265
|
-
"
|
|
3266
|
-
"
|
|
3267
|
-
"
|
|
3672
|
+
"name": name,
|
|
3673
|
+
"model_name": model_name,
|
|
3674
|
+
"function_name": function_name,
|
|
3675
|
+
"function_tag": function_tag,
|
|
3676
|
+
"label": labels,
|
|
3677
|
+
"start": datetime_to_iso(start),
|
|
3678
|
+
"end": datetime_to_iso(end),
|
|
3679
|
+
"tsdb_metrics": tsdb_metrics,
|
|
3268
3680
|
"top-level": top_level,
|
|
3269
3681
|
"uid": uids,
|
|
3682
|
+
"latest_only": latest_only,
|
|
3270
3683
|
},
|
|
3271
3684
|
)
|
|
3272
3685
|
|
|
3273
|
-
|
|
3274
|
-
model_endpoints = response.json()["endpoints"]
|
|
3275
|
-
if model_endpoints:
|
|
3276
|
-
return [
|
|
3277
|
-
mlrun.model_monitoring.model_endpoint.ModelEndpoint.from_dict(obj)
|
|
3278
|
-
for obj in model_endpoints
|
|
3279
|
-
]
|
|
3280
|
-
return []
|
|
3686
|
+
return mlrun.common.schemas.ModelEndpointList(**response.json())
|
|
3281
3687
|
|
|
3282
3688
|
def get_model_endpoint(
|
|
3283
3689
|
self,
|
|
3690
|
+
name: str,
|
|
3284
3691
|
project: str,
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3692
|
+
function_name: Optional[str] = None,
|
|
3693
|
+
function_tag: Optional[str] = None,
|
|
3694
|
+
endpoint_id: Optional[str] = None,
|
|
3695
|
+
tsdb_metrics: bool = True,
|
|
3289
3696
|
feature_analysis: bool = False,
|
|
3290
|
-
) -> mlrun.
|
|
3697
|
+
) -> mlrun.common.schemas.ModelEndpoint:
|
|
3291
3698
|
"""
|
|
3292
3699
|
Returns a single `ModelEndpoint` object with additional metrics and feature related data.
|
|
3293
3700
|
|
|
3701
|
+
:param name: The name of the model endpoint
|
|
3294
3702
|
:param project: The name of the project
|
|
3295
|
-
:param
|
|
3296
|
-
:param
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
appeared under model_endpoint.spec.metrics.
|
|
3309
|
-
:param feature_analysis: When True, the base feature statistics and current feature statistics will
|
|
3310
|
-
be added to the output of the resulting object.
|
|
3311
|
-
|
|
3312
|
-
:returns: A `ModelEndpoint` object.
|
|
3313
|
-
"""
|
|
3314
|
-
|
|
3315
|
-
path = f"projects/{project}/model-endpoints/{endpoint_id}"
|
|
3703
|
+
:param function_name: The name of the function
|
|
3704
|
+
:param function_tag: The tag of the function
|
|
3705
|
+
:param endpoint_id: The id of the endpoint
|
|
3706
|
+
:param tsdb_metrics: Whether to include metrics from the time series DB.
|
|
3707
|
+
:param feature_analysis: Whether to include feature analysis data (feature_stats,
|
|
3708
|
+
current_stats & drift_measures).
|
|
3709
|
+
|
|
3710
|
+
:return: A `ModelEndpoint` object.
|
|
3711
|
+
"""
|
|
3712
|
+
self._check_model_endpoint_representation(
|
|
3713
|
+
function_name, function_tag, endpoint_id
|
|
3714
|
+
)
|
|
3715
|
+
path = f"projects/{project}/model-endpoints/{name}"
|
|
3316
3716
|
response = self.api_call(
|
|
3317
|
-
method=
|
|
3717
|
+
method=mlrun.common.types.HTTPMethod.GET,
|
|
3318
3718
|
path=path,
|
|
3319
3719
|
params={
|
|
3320
|
-
"
|
|
3321
|
-
"
|
|
3322
|
-
"
|
|
3720
|
+
"function_name": function_name,
|
|
3721
|
+
"function_tag": function_tag,
|
|
3722
|
+
"endpoint_id": endpoint_id,
|
|
3723
|
+
"tsdb_metrics": tsdb_metrics,
|
|
3323
3724
|
"feature_analysis": feature_analysis,
|
|
3324
3725
|
},
|
|
3325
3726
|
)
|
|
3326
3727
|
|
|
3327
|
-
return mlrun.
|
|
3328
|
-
response.json()
|
|
3329
|
-
)
|
|
3728
|
+
return mlrun.common.schemas.ModelEndpoint(**response.json())
|
|
3330
3729
|
|
|
3331
3730
|
def patch_model_endpoint(
|
|
3332
3731
|
self,
|
|
3732
|
+
name: str,
|
|
3333
3733
|
project: str,
|
|
3334
|
-
endpoint_id: str,
|
|
3335
3734
|
attributes: dict,
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
:param project: The name of the project.
|
|
3341
|
-
:param endpoint_id: The id of the endpoint.
|
|
3342
|
-
:param attributes: Dictionary of attributes that will be used for update the model endpoint. The keys
|
|
3343
|
-
of this dictionary should exist in the target table. Note that the values should be from type string or from
|
|
3344
|
-
a valid numerical type such as int or float. More details about the model endpoint available attributes can
|
|
3345
|
-
be found under :py:class:`~mlrun.common.schemas.ModelEndpoint`.
|
|
3346
|
-
|
|
3347
|
-
Example::
|
|
3348
|
-
|
|
3349
|
-
# Generate current stats for two features
|
|
3350
|
-
current_stats = {'tvd_sum': 2.2,
|
|
3351
|
-
'tvd_mean': 0.5,
|
|
3352
|
-
'hellinger_sum': 3.6,
|
|
3353
|
-
'hellinger_mean': 0.9,
|
|
3354
|
-
'kld_sum': 24.2,
|
|
3355
|
-
'kld_mean': 6.0,
|
|
3356
|
-
'f1': {'tvd': 0.5, 'hellinger': 1.0, 'kld': 6.4},
|
|
3357
|
-
'f2': {'tvd': 0.5, 'hellinger': 1.0, 'kld': 6.5}}
|
|
3358
|
-
|
|
3359
|
-
# Create attributes dictionary according to the required format
|
|
3360
|
-
attributes = {`current_stats`: json.dumps(current_stats),
|
|
3361
|
-
`drift_status`: "DRIFT_DETECTED"}
|
|
3362
|
-
|
|
3735
|
+
function_name: Optional[str] = None,
|
|
3736
|
+
function_tag: Optional[str] = None,
|
|
3737
|
+
endpoint_id: Optional[str] = None,
|
|
3738
|
+
) -> mlrun.common.schemas.ModelEndpoint:
|
|
3363
3739
|
"""
|
|
3740
|
+
Updates a model endpoint with the given attributes.
|
|
3364
3741
|
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3742
|
+
:param name: The name of the model endpoint
|
|
3743
|
+
:param project: The name of the project
|
|
3744
|
+
:param attributes: The attributes to update
|
|
3745
|
+
:param function_name: The name of the function
|
|
3746
|
+
:param function_tag: The tag of the function
|
|
3747
|
+
:param endpoint_id: The id of the endpoint
|
|
3748
|
+
:return: The updated `ModelEndpoint` object.
|
|
3749
|
+
"""
|
|
3750
|
+
attributes_keys = list(attributes.keys())
|
|
3751
|
+
attributes["name"] = name
|
|
3752
|
+
attributes["project"] = project
|
|
3753
|
+
attributes["function_name"] = function_name or None
|
|
3754
|
+
attributes["function_tag"] = function_tag or None
|
|
3755
|
+
attributes["uid"] = endpoint_id or None
|
|
3756
|
+
model_endpoint = mlrun.common.schemas.ModelEndpoint.from_flat_dict(attributes)
|
|
3757
|
+
path = f"projects/{project}/model-endpoints"
|
|
3758
|
+
logger.info(
|
|
3759
|
+
"Patching model endpoint",
|
|
3760
|
+
attributes_keys=attributes_keys,
|
|
3761
|
+
model_endpoint=model_endpoint,
|
|
3762
|
+
)
|
|
3763
|
+
response = self.api_call(
|
|
3764
|
+
method=mlrun.common.types.HTTPMethod.PATCH,
|
|
3369
3765
|
path=path,
|
|
3370
|
-
params=
|
|
3766
|
+
params={
|
|
3767
|
+
"attribute-key": attributes_keys,
|
|
3768
|
+
},
|
|
3769
|
+
body=model_endpoint.json(),
|
|
3371
3770
|
)
|
|
3372
3771
|
|
|
3772
|
+
return mlrun.common.schemas.ModelEndpoint(**response.json())
|
|
3773
|
+
|
|
3774
|
+
@staticmethod
|
|
3775
|
+
def _check_model_endpoint_representation(
|
|
3776
|
+
function_name: str, function_tag: str, uid: str
|
|
3777
|
+
):
|
|
3778
|
+
if not uid and not (function_name and function_tag):
|
|
3779
|
+
raise MLRunInvalidArgumentError(
|
|
3780
|
+
"Either endpoint_uid or function_name and function_tag must be provided"
|
|
3781
|
+
)
|
|
3782
|
+
|
|
3373
3783
|
def update_model_monitoring_controller(
|
|
3374
3784
|
self,
|
|
3375
3785
|
project: str,
|
|
@@ -3441,7 +3851,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3441
3851
|
delete_stream_function: bool = False,
|
|
3442
3852
|
delete_histogram_data_drift_app: bool = True,
|
|
3443
3853
|
delete_user_applications: bool = False,
|
|
3444
|
-
user_application_list: list[str] = None,
|
|
3854
|
+
user_application_list: Optional[list[str]] = None,
|
|
3445
3855
|
) -> bool:
|
|
3446
3856
|
"""
|
|
3447
3857
|
Disable model monitoring application controller, writer, stream, histogram data drift application
|
|
@@ -3714,8 +4124,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3714
4124
|
def get_hub_catalog(
|
|
3715
4125
|
self,
|
|
3716
4126
|
source_name: str,
|
|
3717
|
-
version: str = None,
|
|
3718
|
-
tag: str = None,
|
|
4127
|
+
version: Optional[str] = None,
|
|
4128
|
+
tag: Optional[str] = None,
|
|
3719
4129
|
force_refresh: bool = False,
|
|
3720
4130
|
):
|
|
3721
4131
|
"""
|
|
@@ -3745,7 +4155,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3745
4155
|
self,
|
|
3746
4156
|
source_name: str,
|
|
3747
4157
|
item_name: str,
|
|
3748
|
-
version: str = None,
|
|
4158
|
+
version: Optional[str] = None,
|
|
3749
4159
|
tag: str = "latest",
|
|
3750
4160
|
force_refresh: bool = False,
|
|
3751
4161
|
):
|
|
@@ -3775,7 +4185,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3775
4185
|
source_name: str,
|
|
3776
4186
|
item_name: str,
|
|
3777
4187
|
asset_name: str,
|
|
3778
|
-
version: str = None,
|
|
4188
|
+
version: Optional[str] = None,
|
|
3779
4189
|
tag: str = "latest",
|
|
3780
4190
|
):
|
|
3781
4191
|
"""
|
|
@@ -3897,18 +4307,27 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3897
4307
|
"operations/migrations",
|
|
3898
4308
|
"Failed triggering migrations",
|
|
3899
4309
|
)
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
4310
|
+
return self._wait_for_background_task_from_response(response)
|
|
4311
|
+
|
|
4312
|
+
def refresh_smtp_configuration(
|
|
4313
|
+
self,
|
|
4314
|
+
) -> Optional[mlrun.common.schemas.BackgroundTask]:
|
|
4315
|
+
"""Refresh smtp configuration and wait for the task to finish
|
|
4316
|
+
|
|
4317
|
+
:returns: :py:class:`~mlrun.common.schemas.BackgroundTask`.
|
|
4318
|
+
"""
|
|
4319
|
+
response = self.api_call(
|
|
4320
|
+
"POST",
|
|
4321
|
+
"operations/refresh-smtp-configuration",
|
|
4322
|
+
"Failed refreshing smtp configuration",
|
|
4323
|
+
)
|
|
4324
|
+
return self._wait_for_background_task_from_response(response)
|
|
3906
4325
|
|
|
3907
4326
|
def set_run_notifications(
|
|
3908
4327
|
self,
|
|
3909
4328
|
project: str,
|
|
3910
4329
|
run_uid: str,
|
|
3911
|
-
notifications: list[mlrun.model.Notification] = None,
|
|
4330
|
+
notifications: Optional[list[mlrun.model.Notification]] = None,
|
|
3912
4331
|
):
|
|
3913
4332
|
"""
|
|
3914
4333
|
Set notifications on a run. This will override any existing notifications on the run.
|
|
@@ -3934,7 +4353,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3934
4353
|
self,
|
|
3935
4354
|
project: str,
|
|
3936
4355
|
schedule_name: str,
|
|
3937
|
-
notifications: list[mlrun.model.Notification] = None,
|
|
4356
|
+
notifications: Optional[list[mlrun.model.Notification]] = None,
|
|
3938
4357
|
):
|
|
3939
4358
|
"""
|
|
3940
4359
|
Set notifications on a schedule. This will override any existing notifications on the schedule.
|
|
@@ -3960,7 +4379,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3960
4379
|
self,
|
|
3961
4380
|
notification_objects: list[mlrun.model.Notification],
|
|
3962
4381
|
run_uid: str,
|
|
3963
|
-
project: str = None,
|
|
4382
|
+
project: Optional[str] = None,
|
|
3964
4383
|
mask_params: bool = True,
|
|
3965
4384
|
):
|
|
3966
4385
|
"""
|
|
@@ -3994,7 +4413,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3994
4413
|
source: Optional[str] = None,
|
|
3995
4414
|
run_name: Optional[str] = None,
|
|
3996
4415
|
namespace: Optional[str] = None,
|
|
3997
|
-
notifications: list[mlrun.model.Notification] = None,
|
|
4416
|
+
notifications: Optional[list[mlrun.model.Notification]] = None,
|
|
3998
4417
|
) -> mlrun.common.schemas.WorkflowResponse:
|
|
3999
4418
|
"""
|
|
4000
4419
|
Submitting workflow for a remote execution.
|
|
@@ -4216,6 +4635,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4216
4635
|
alert_name: str,
|
|
4217
4636
|
alert_data: Union[dict, AlertConfig],
|
|
4218
4637
|
project="",
|
|
4638
|
+
force_reset: bool = False,
|
|
4219
4639
|
) -> AlertConfig:
|
|
4220
4640
|
"""
|
|
4221
4641
|
Create/modify an alert.
|
|
@@ -4223,6 +4643,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4223
4643
|
:param alert_name: The name of the alert.
|
|
4224
4644
|
:param alert_data: The data of the alert.
|
|
4225
4645
|
:param project: The project that the alert belongs to.
|
|
4646
|
+
:param force_reset: If True and the alert already exists, the alert would be reset.
|
|
4226
4647
|
:returns: The created/modified alert.
|
|
4227
4648
|
"""
|
|
4228
4649
|
if not alert_data:
|
|
@@ -4247,7 +4668,10 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4247
4668
|
|
|
4248
4669
|
alert_data = alert_instance.to_dict()
|
|
4249
4670
|
body = _as_json(alert_data)
|
|
4250
|
-
|
|
4671
|
+
params = {"force_reset": bool2str(force_reset)} if force_reset else {}
|
|
4672
|
+
response = self.api_call(
|
|
4673
|
+
"PUT", endpoint_path, error_message, params=params, body=body
|
|
4674
|
+
)
|
|
4251
4675
|
return AlertConfig.from_dict(response.json())
|
|
4252
4676
|
|
|
4253
4677
|
def get_alert_config(self, alert_name: str, project="") -> AlertConfig:
|
|
@@ -4334,6 +4758,460 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4334
4758
|
results.append(mlrun.common.schemas.AlertTemplate(**item))
|
|
4335
4759
|
return results
|
|
4336
4760
|
|
|
4761
|
+
def list_alert_activations(
|
|
4762
|
+
self,
|
|
4763
|
+
project: Optional[str] = None,
|
|
4764
|
+
name: Optional[str] = None,
|
|
4765
|
+
since: Optional[datetime] = None,
|
|
4766
|
+
until: Optional[datetime] = None,
|
|
4767
|
+
entity: Optional[str] = None,
|
|
4768
|
+
severity: Optional[
|
|
4769
|
+
list[Union[mlrun.common.schemas.alert.AlertSeverity, str]]
|
|
4770
|
+
] = None,
|
|
4771
|
+
entity_kind: Optional[
|
|
4772
|
+
Union[mlrun.common.schemas.alert.EventEntityKind, str]
|
|
4773
|
+
] = None,
|
|
4774
|
+
event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
|
|
4775
|
+
) -> mlrun.common.schemas.AlertActivations:
|
|
4776
|
+
"""
|
|
4777
|
+
Retrieve a list of all alert activations.
|
|
4778
|
+
|
|
4779
|
+
:param project: The project name to filter by. If None, results are not filtered by project.
|
|
4780
|
+
:param name: The alert name to filter by. Supports exact matching or partial matching if prefixed with `~`.
|
|
4781
|
+
:param since: Filters for alert activations occurring after this timestamp.
|
|
4782
|
+
:param until: Filters for alert activations occurring before this timestamp.
|
|
4783
|
+
:param entity: The entity ID to filter by. Supports wildcard matching if prefixed with `~`.
|
|
4784
|
+
:param severity: A list of severity levels to filter by (e.g., ["high", "low"]).
|
|
4785
|
+
:param entity_kind: The kind of entity (e.g., "job", "endpoint") to filter by.
|
|
4786
|
+
:param event_kind: The kind of event (e.g., ""data-drift-detected"", "failed") to filter by.
|
|
4787
|
+
|
|
4788
|
+
:returns: A list of alert activations matching the provided filters.
|
|
4789
|
+
"""
|
|
4790
|
+
|
|
4791
|
+
alert_activations, _ = self._list_alert_activations(
|
|
4792
|
+
project=project,
|
|
4793
|
+
name=name,
|
|
4794
|
+
since=since,
|
|
4795
|
+
until=until,
|
|
4796
|
+
entity=entity,
|
|
4797
|
+
severity=severity,
|
|
4798
|
+
entity_kind=entity_kind,
|
|
4799
|
+
event_kind=event_kind,
|
|
4800
|
+
return_all=True,
|
|
4801
|
+
)
|
|
4802
|
+
return alert_activations
|
|
4803
|
+
|
|
4804
|
+
def paginated_list_alert_activations(
|
|
4805
|
+
self,
|
|
4806
|
+
*args,
|
|
4807
|
+
page: Optional[int] = None,
|
|
4808
|
+
page_size: Optional[int] = None,
|
|
4809
|
+
page_token: Optional[str] = None,
|
|
4810
|
+
**kwargs,
|
|
4811
|
+
) -> tuple[AlertActivations, Optional[str]]:
|
|
4812
|
+
"""List alerts activations with support for pagination and various filtering options.
|
|
4813
|
+
|
|
4814
|
+
This method retrieves a paginated list of alert activations based on the specified filter parameters.
|
|
4815
|
+
Pagination is controlled using the `page`, `page_size`, and `page_token` parameters. The method
|
|
4816
|
+
will return a list of alert activations that match the filtering criteria provided.
|
|
4817
|
+
|
|
4818
|
+
For detailed information about the parameters, refer to the list_alert_activations method:
|
|
4819
|
+
See :py:func:`~list_alert_activations` for more details.
|
|
4820
|
+
|
|
4821
|
+
Examples::
|
|
4822
|
+
|
|
4823
|
+
# Fetch first page of alert activations with page size of 5
|
|
4824
|
+
alert_activations, token = db.paginated_list_alert_activations(
|
|
4825
|
+
project="my-project", page_size=5
|
|
4826
|
+
)
|
|
4827
|
+
# Fetch next page using the pagination token from the previous response
|
|
4828
|
+
alert_activations, token = db.paginated_list_alert_activations(
|
|
4829
|
+
project="my-project", page_token=token
|
|
4830
|
+
)
|
|
4831
|
+
# Fetch alert activations for a specific page (e.g., page 3)
|
|
4832
|
+
alert_activations, token = db.paginated_list_alert_activations(
|
|
4833
|
+
project="my-project", page=3, page_size=5
|
|
4834
|
+
)
|
|
4835
|
+
|
|
4836
|
+
# Automatically iterate over all pages without explicitly specifying the page number
|
|
4837
|
+
alert_activations = []
|
|
4838
|
+
token = None
|
|
4839
|
+
while True:
|
|
4840
|
+
page_alert_activations, token = db.paginated_list_alert_activations(
|
|
4841
|
+
project="my-project", page_token=token, page_size=5
|
|
4842
|
+
)
|
|
4843
|
+
alert_activations.extend(page_alert_activations)
|
|
4844
|
+
|
|
4845
|
+
# If token is None and page_alert_activations is empty, we've reached the end (no more activations).
|
|
4846
|
+
# If token is None and page_alert_activations is not empty, we've fetched the last page of activations.
|
|
4847
|
+
if not token:
|
|
4848
|
+
break
|
|
4849
|
+
print(f"Total alert activations retrieved: {len(alert_activations)}")
|
|
4850
|
+
|
|
4851
|
+
:param page: The page number to retrieve. If not provided, the next page will be retrieved.
|
|
4852
|
+
:param page_size: The number of items per page to retrieve. Up to `page_size` responses are expected.
|
|
4853
|
+
:param page_token: A pagination token used to retrieve the next page of results. Should not be provided
|
|
4854
|
+
for the first request.
|
|
4855
|
+
|
|
4856
|
+
:returns: A tuple containing the list of alert activations and an optional `page_token` for pagination.
|
|
4857
|
+
"""
|
|
4858
|
+
return self._list_alert_activations(
|
|
4859
|
+
*args,
|
|
4860
|
+
page=page,
|
|
4861
|
+
page_size=page_size,
|
|
4862
|
+
page_token=page_token,
|
|
4863
|
+
return_all=False,
|
|
4864
|
+
**kwargs,
|
|
4865
|
+
)
|
|
4866
|
+
|
|
4867
|
+
def get_project_summary(
|
|
4868
|
+
self, project: Optional[str] = None
|
|
4869
|
+
) -> mlrun.common.schemas.ProjectSummary:
|
|
4870
|
+
"""
|
|
4871
|
+
Retrieve the summary of a project.
|
|
4872
|
+
|
|
4873
|
+
:param project: Project name for which the summary belongs.
|
|
4874
|
+
:returns: A summary of the project.
|
|
4875
|
+
"""
|
|
4876
|
+
project = project or config.default_project
|
|
4877
|
+
|
|
4878
|
+
endpoint_path = f"project-summaries/{project}"
|
|
4879
|
+
error_message = f"Failed retrieving project summary for {project}"
|
|
4880
|
+
response = self.api_call("GET", endpoint_path, error_message)
|
|
4881
|
+
return mlrun.common.schemas.ProjectSummary(**response.json())
|
|
4882
|
+
|
|
4883
|
+
@staticmethod
|
|
4884
|
+
def _parse_labels(
|
|
4885
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]],
|
|
4886
|
+
):
|
|
4887
|
+
"""
|
|
4888
|
+
Parse labels to support providing a dictionary from the SDK,
|
|
4889
|
+
which may not be directly supported in the endpoints.
|
|
4890
|
+
|
|
4891
|
+
:param labels: The labels to parse, which can be a dictionary, a list of strings,
|
|
4892
|
+
or a comma-separated string. This function converts them into a list
|
|
4893
|
+
of labels in the format 'key=value' or 'key'.
|
|
4894
|
+
:return: A list of parsed labels in the format 'key=value' or 'key'.
|
|
4895
|
+
:raises MLRunValueError: If the labels format is invalid.
|
|
4896
|
+
"""
|
|
4897
|
+
try:
|
|
4898
|
+
return mlrun.common.schemas.common.LabelsModel(labels=labels).labels
|
|
4899
|
+
except pydantic.v1.error_wrappers.ValidationError as exc:
|
|
4900
|
+
raise mlrun.errors.MLRunValueError(
|
|
4901
|
+
"Invalid labels format. Must be a dictionary of strings, a list of strings, "
|
|
4902
|
+
"or a comma-separated string."
|
|
4903
|
+
) from exc
|
|
4904
|
+
|
|
4905
|
+
def _list_artifacts(
|
|
4906
|
+
self,
|
|
4907
|
+
name: Optional[str] = None,
|
|
4908
|
+
project: Optional[str] = None,
|
|
4909
|
+
tag: Optional[str] = None,
|
|
4910
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
4911
|
+
since: Optional[datetime] = None,
|
|
4912
|
+
until: Optional[datetime] = None,
|
|
4913
|
+
iter: Optional[int] = None,
|
|
4914
|
+
best_iteration: bool = False,
|
|
4915
|
+
kind: Optional[str] = None,
|
|
4916
|
+
category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
|
|
4917
|
+
tree: Optional[str] = None,
|
|
4918
|
+
producer_uri: Optional[str] = None,
|
|
4919
|
+
format_: Optional[
|
|
4920
|
+
mlrun.common.formatters.ArtifactFormat
|
|
4921
|
+
] = mlrun.common.formatters.ArtifactFormat.full,
|
|
4922
|
+
limit: Optional[int] = None,
|
|
4923
|
+
partition_by: Optional[
|
|
4924
|
+
Union[mlrun.common.schemas.ArtifactPartitionByField, str]
|
|
4925
|
+
] = None,
|
|
4926
|
+
rows_per_partition: int = 1,
|
|
4927
|
+
partition_sort_by: Optional[
|
|
4928
|
+
Union[mlrun.common.schemas.SortField, str]
|
|
4929
|
+
] = mlrun.common.schemas.SortField.updated,
|
|
4930
|
+
partition_order: Union[
|
|
4931
|
+
mlrun.common.schemas.OrderType, str
|
|
4932
|
+
] = mlrun.common.schemas.OrderType.desc,
|
|
4933
|
+
page: Optional[int] = None,
|
|
4934
|
+
page_size: Optional[int] = None,
|
|
4935
|
+
page_token: Optional[str] = None,
|
|
4936
|
+
return_all: bool = False,
|
|
4937
|
+
) -> tuple[ArtifactList, Optional[str]]:
|
|
4938
|
+
"""Handles list artifacts, both paginated and not."""
|
|
4939
|
+
|
|
4940
|
+
project = project or config.default_project
|
|
4941
|
+
labels = self._parse_labels(labels)
|
|
4942
|
+
|
|
4943
|
+
params = {
|
|
4944
|
+
"name": name,
|
|
4945
|
+
"tag": tag,
|
|
4946
|
+
"label": labels,
|
|
4947
|
+
"iter": iter,
|
|
4948
|
+
"best-iteration": best_iteration,
|
|
4949
|
+
"kind": kind,
|
|
4950
|
+
"category": category,
|
|
4951
|
+
"tree": tree,
|
|
4952
|
+
"format": format_,
|
|
4953
|
+
"producer_uri": producer_uri,
|
|
4954
|
+
"since": datetime_to_iso(since),
|
|
4955
|
+
"until": datetime_to_iso(until),
|
|
4956
|
+
"limit": limit,
|
|
4957
|
+
"page": page,
|
|
4958
|
+
"page-size": page_size,
|
|
4959
|
+
"page-token": page_token,
|
|
4960
|
+
}
|
|
4961
|
+
|
|
4962
|
+
if partition_by:
|
|
4963
|
+
params.update(
|
|
4964
|
+
self._generate_partition_by_params(
|
|
4965
|
+
partition_by,
|
|
4966
|
+
rows_per_partition,
|
|
4967
|
+
partition_sort_by,
|
|
4968
|
+
partition_order,
|
|
4969
|
+
)
|
|
4970
|
+
)
|
|
4971
|
+
error = "list artifacts"
|
|
4972
|
+
endpoint_path = f"projects/{project}/artifacts"
|
|
4973
|
+
|
|
4974
|
+
# Fetch the responses, either one page or all based on `return_all`
|
|
4975
|
+
responses = self.paginated_api_call(
|
|
4976
|
+
"GET",
|
|
4977
|
+
endpoint_path,
|
|
4978
|
+
error,
|
|
4979
|
+
params=params,
|
|
4980
|
+
version="v2",
|
|
4981
|
+
return_all=return_all,
|
|
4982
|
+
)
|
|
4983
|
+
paginated_responses, token = self.process_paginated_responses(
|
|
4984
|
+
responses, "artifacts"
|
|
4985
|
+
)
|
|
4986
|
+
|
|
4987
|
+
values = ArtifactList(paginated_responses)
|
|
4988
|
+
values.tag = tag
|
|
4989
|
+
return values, token
|
|
4990
|
+
|
|
4991
|
+
def _list_functions(
|
|
4992
|
+
self,
|
|
4993
|
+
name: Optional[str] = None,
|
|
4994
|
+
project: Optional[str] = None,
|
|
4995
|
+
tag: Optional[str] = None,
|
|
4996
|
+
kind: Optional[str] = None,
|
|
4997
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
4998
|
+
format_: Optional[str] = None,
|
|
4999
|
+
since: Optional[datetime] = None,
|
|
5000
|
+
until: Optional[datetime] = None,
|
|
5001
|
+
page: Optional[int] = None,
|
|
5002
|
+
page_size: Optional[int] = None,
|
|
5003
|
+
page_token: Optional[str] = None,
|
|
5004
|
+
return_all: bool = False,
|
|
5005
|
+
) -> tuple[list, Optional[str]]:
|
|
5006
|
+
"""Handles list functions, both paginated and not."""
|
|
5007
|
+
|
|
5008
|
+
project = project or config.default_project
|
|
5009
|
+
labels = self._parse_labels(labels)
|
|
5010
|
+
params = {
|
|
5011
|
+
"name": name,
|
|
5012
|
+
"tag": tag,
|
|
5013
|
+
"kind": kind,
|
|
5014
|
+
"label": labels,
|
|
5015
|
+
"since": datetime_to_iso(since),
|
|
5016
|
+
"until": datetime_to_iso(until),
|
|
5017
|
+
"format": format_,
|
|
5018
|
+
"page": page,
|
|
5019
|
+
"page-size": page_size,
|
|
5020
|
+
"page-token": page_token,
|
|
5021
|
+
}
|
|
5022
|
+
error = "list functions"
|
|
5023
|
+
path = f"projects/{project}/functions"
|
|
5024
|
+
|
|
5025
|
+
# Fetch the responses, either one page or all based on `return_all`
|
|
5026
|
+
responses = self.paginated_api_call(
|
|
5027
|
+
"GET", path, error, params=params, return_all=return_all
|
|
5028
|
+
)
|
|
5029
|
+
paginated_responses, token = self.process_paginated_responses(
|
|
5030
|
+
responses, "funcs"
|
|
5031
|
+
)
|
|
5032
|
+
return paginated_responses, token
|
|
5033
|
+
|
|
5034
|
+
def _list_runs(
|
|
5035
|
+
self,
|
|
5036
|
+
name: Optional[str] = None,
|
|
5037
|
+
uid: Optional[Union[str, list[str]]] = None,
|
|
5038
|
+
project: Optional[str] = None,
|
|
5039
|
+
labels: Optional[Union[str, dict[str, Optional[str]], list[str]]] = None,
|
|
5040
|
+
state: Optional[
|
|
5041
|
+
mlrun.common.runtimes.constants.RunStates
|
|
5042
|
+
] = None, # Backward compatibility
|
|
5043
|
+
states: typing.Optional[list[mlrun.common.runtimes.constants.RunStates]] = None,
|
|
5044
|
+
sort: bool = True,
|
|
5045
|
+
last: int = 0,
|
|
5046
|
+
iter: bool = False,
|
|
5047
|
+
start_time_from: Optional[datetime] = None,
|
|
5048
|
+
start_time_to: Optional[datetime] = None,
|
|
5049
|
+
last_update_time_from: Optional[datetime] = None,
|
|
5050
|
+
last_update_time_to: Optional[datetime] = None,
|
|
5051
|
+
partition_by: Optional[
|
|
5052
|
+
Union[mlrun.common.schemas.RunPartitionByField, str]
|
|
5053
|
+
] = None,
|
|
5054
|
+
rows_per_partition: int = 1,
|
|
5055
|
+
partition_sort_by: Optional[Union[mlrun.common.schemas.SortField, str]] = None,
|
|
5056
|
+
partition_order: Union[
|
|
5057
|
+
mlrun.common.schemas.OrderType, str
|
|
5058
|
+
] = mlrun.common.schemas.OrderType.desc,
|
|
5059
|
+
max_partitions: int = 0,
|
|
5060
|
+
with_notifications: bool = False,
|
|
5061
|
+
page: Optional[int] = None,
|
|
5062
|
+
page_size: Optional[int] = None,
|
|
5063
|
+
page_token: Optional[str] = None,
|
|
5064
|
+
return_all: bool = False,
|
|
5065
|
+
) -> tuple[RunList, Optional[str]]:
|
|
5066
|
+
"""Handles list runs, both paginated and not."""
|
|
5067
|
+
|
|
5068
|
+
project = project or config.default_project
|
|
5069
|
+
if with_notifications:
|
|
5070
|
+
logger.warning(
|
|
5071
|
+
"Local run notifications are not persisted in the DB, therefore local runs will not be returned when "
|
|
5072
|
+
"using the `with_notifications` flag."
|
|
5073
|
+
)
|
|
5074
|
+
|
|
5075
|
+
if last:
|
|
5076
|
+
# TODO: Remove this in 1.8.0
|
|
5077
|
+
warnings.warn(
|
|
5078
|
+
"'last' is deprecated and will be removed in 1.8.0.",
|
|
5079
|
+
FutureWarning,
|
|
5080
|
+
)
|
|
5081
|
+
|
|
5082
|
+
if state:
|
|
5083
|
+
# TODO: Remove this in 1.9.0
|
|
5084
|
+
warnings.warn(
|
|
5085
|
+
"'state' is deprecated and will be removed in 1.9.0. Use 'states' instead.",
|
|
5086
|
+
FutureWarning,
|
|
5087
|
+
)
|
|
5088
|
+
|
|
5089
|
+
labels = self._parse_labels(labels)
|
|
5090
|
+
|
|
5091
|
+
if (
|
|
5092
|
+
not name
|
|
5093
|
+
and not uid
|
|
5094
|
+
and not labels
|
|
5095
|
+
and not state
|
|
5096
|
+
and not states
|
|
5097
|
+
and not last
|
|
5098
|
+
and not start_time_from
|
|
5099
|
+
and not start_time_to
|
|
5100
|
+
and not last_update_time_from
|
|
5101
|
+
and not last_update_time_to
|
|
5102
|
+
and not partition_by
|
|
5103
|
+
and not partition_sort_by
|
|
5104
|
+
and not iter
|
|
5105
|
+
):
|
|
5106
|
+
# default to last week on no filter
|
|
5107
|
+
start_time_from = datetime.now() - timedelta(days=7)
|
|
5108
|
+
partition_by = mlrun.common.schemas.RunPartitionByField.project_and_name
|
|
5109
|
+
partition_sort_by = mlrun.common.schemas.SortField.updated
|
|
5110
|
+
|
|
5111
|
+
params = {
|
|
5112
|
+
"name": name,
|
|
5113
|
+
"uid": uid,
|
|
5114
|
+
"label": labels,
|
|
5115
|
+
"state": (
|
|
5116
|
+
mlrun.utils.helpers.as_list(state)
|
|
5117
|
+
if state is not None
|
|
5118
|
+
else states or None
|
|
5119
|
+
),
|
|
5120
|
+
"sort": bool2str(sort),
|
|
5121
|
+
"iter": bool2str(iter),
|
|
5122
|
+
"start_time_from": datetime_to_iso(start_time_from),
|
|
5123
|
+
"start_time_to": datetime_to_iso(start_time_to),
|
|
5124
|
+
"last_update_time_from": datetime_to_iso(last_update_time_from),
|
|
5125
|
+
"last_update_time_to": datetime_to_iso(last_update_time_to),
|
|
5126
|
+
"with-notifications": with_notifications,
|
|
5127
|
+
"page": page,
|
|
5128
|
+
"page-size": page_size,
|
|
5129
|
+
"page-token": page_token,
|
|
5130
|
+
}
|
|
5131
|
+
|
|
5132
|
+
if partition_by:
|
|
5133
|
+
params.update(
|
|
5134
|
+
self._generate_partition_by_params(
|
|
5135
|
+
partition_by,
|
|
5136
|
+
rows_per_partition,
|
|
5137
|
+
partition_sort_by,
|
|
5138
|
+
partition_order,
|
|
5139
|
+
max_partitions,
|
|
5140
|
+
)
|
|
5141
|
+
)
|
|
5142
|
+
error = "list runs"
|
|
5143
|
+
_path = self._path_of("runs", project)
|
|
5144
|
+
|
|
5145
|
+
# Fetch the responses, either one page or all based on `return_all`
|
|
5146
|
+
responses = self.paginated_api_call(
|
|
5147
|
+
"GET", _path, error, params=params, return_all=return_all
|
|
5148
|
+
)
|
|
5149
|
+
paginated_responses, token = self.process_paginated_responses(responses, "runs")
|
|
5150
|
+
return RunList(paginated_responses), token
|
|
5151
|
+
|
|
5152
|
+
def _list_alert_activations(
|
|
5153
|
+
self,
|
|
5154
|
+
project: Optional[str] = None,
|
|
5155
|
+
name: Optional[str] = None,
|
|
5156
|
+
since: Optional[datetime] = None,
|
|
5157
|
+
until: Optional[datetime] = None,
|
|
5158
|
+
entity: Optional[str] = None,
|
|
5159
|
+
severity: Optional[
|
|
5160
|
+
Union[
|
|
5161
|
+
mlrun.common.schemas.alert.AlertSeverity,
|
|
5162
|
+
str,
|
|
5163
|
+
list[Union[mlrun.common.schemas.alert.AlertSeverity, str]],
|
|
5164
|
+
]
|
|
5165
|
+
] = None,
|
|
5166
|
+
entity_kind: Optional[
|
|
5167
|
+
Union[mlrun.common.schemas.alert.EventEntityKind, str]
|
|
5168
|
+
] = None,
|
|
5169
|
+
event_kind: Optional[Union[mlrun.common.schemas.alert.EventKind, str]] = None,
|
|
5170
|
+
page: Optional[int] = None,
|
|
5171
|
+
page_size: Optional[int] = None,
|
|
5172
|
+
page_token: Optional[str] = None,
|
|
5173
|
+
return_all: bool = False,
|
|
5174
|
+
) -> tuple[mlrun.common.schemas.AlertActivations, Optional[str]]:
|
|
5175
|
+
project = project or config.default_project
|
|
5176
|
+
params = {
|
|
5177
|
+
"name": name,
|
|
5178
|
+
"since": datetime_to_iso(since),
|
|
5179
|
+
"until": datetime_to_iso(until),
|
|
5180
|
+
"entity": entity,
|
|
5181
|
+
"severity": mlrun.utils.helpers.as_list(severity) if severity else None,
|
|
5182
|
+
"entity-kind": entity_kind,
|
|
5183
|
+
"event-kind": event_kind,
|
|
5184
|
+
"page": page,
|
|
5185
|
+
"page-size": page_size,
|
|
5186
|
+
"page-token": page_token,
|
|
5187
|
+
}
|
|
5188
|
+
error = "list alert activations"
|
|
5189
|
+
path = f"projects/{project}/alert-activations"
|
|
5190
|
+
|
|
5191
|
+
# Fetch the responses, either one page or all based on `return_all`
|
|
5192
|
+
responses = self.paginated_api_call(
|
|
5193
|
+
"GET", path, error, params=params, return_all=return_all
|
|
5194
|
+
)
|
|
5195
|
+
paginated_responses, token = self.process_paginated_responses(
|
|
5196
|
+
responses, "activations"
|
|
5197
|
+
)
|
|
5198
|
+
paginated_results = mlrun.common.schemas.AlertActivations(
|
|
5199
|
+
activations=[
|
|
5200
|
+
mlrun.common.schemas.AlertActivation(**item)
|
|
5201
|
+
for item in paginated_responses
|
|
5202
|
+
]
|
|
5203
|
+
)
|
|
5204
|
+
|
|
5205
|
+
return paginated_results, token
|
|
5206
|
+
|
|
5207
|
+
def _wait_for_background_task_from_response(self, response):
|
|
5208
|
+
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
5209
|
+
background_task = mlrun.common.schemas.BackgroundTask(**response.json())
|
|
5210
|
+
return self._wait_for_background_task_to_reach_terminal_state(
|
|
5211
|
+
background_task.metadata.name
|
|
5212
|
+
)
|
|
5213
|
+
return None
|
|
5214
|
+
|
|
4337
5215
|
|
|
4338
5216
|
def _as_json(obj):
|
|
4339
5217
|
fn = getattr(obj, "to_json", None)
|