mlrun 1.6.4rc7__py3-none-any.whl → 1.7.0__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 +11 -1
- mlrun/__main__.py +40 -122
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +248 -0
- mlrun/api/schemas/__init__.py +5 -4
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +47 -257
- mlrun/artifacts/dataset.py +11 -192
- mlrun/artifacts/manager.py +79 -47
- mlrun/artifacts/model.py +31 -159
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +74 -1
- mlrun/common/db/sql_session.py +5 -5
- mlrun/common/formatters/__init__.py +21 -0
- mlrun/common/formatters/artifact.py +45 -0
- mlrun/common/formatters/base.py +113 -0
- mlrun/common/formatters/feature_set.py +33 -0
- mlrun/common/formatters/function.py +46 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/common/formatters/run.py +29 -0
- mlrun/common/helpers.py +12 -3
- mlrun/common/model_monitoring/helpers.py +9 -5
- mlrun/{runtimes → common/runtimes}/constants.py +37 -9
- mlrun/common/schemas/__init__.py +31 -5
- mlrun/common/schemas/alert.py +202 -0
- mlrun/common/schemas/api_gateway.py +196 -0
- mlrun/common/schemas/artifact.py +25 -4
- mlrun/common/schemas/auth.py +16 -5
- mlrun/common/schemas/background_task.py +1 -1
- mlrun/common/schemas/client_spec.py +4 -2
- mlrun/common/schemas/common.py +7 -4
- mlrun/common/schemas/constants.py +3 -0
- mlrun/common/schemas/feature_store.py +74 -44
- mlrun/common/schemas/frontend_spec.py +15 -7
- mlrun/common/schemas/function.py +12 -1
- mlrun/common/schemas/hub.py +11 -18
- mlrun/common/schemas/memory_reports.py +2 -2
- mlrun/common/schemas/model_monitoring/__init__.py +20 -4
- mlrun/common/schemas/model_monitoring/constants.py +123 -42
- mlrun/common/schemas/model_monitoring/grafana.py +13 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +101 -54
- mlrun/common/schemas/notification.py +71 -14
- mlrun/common/schemas/object.py +2 -2
- mlrun/{model_monitoring/controller_handler.py → common/schemas/pagination.py} +9 -12
- mlrun/common/schemas/pipeline.py +8 -1
- mlrun/common/schemas/project.py +69 -18
- mlrun/common/schemas/runs.py +7 -1
- mlrun/common/schemas/runtime_resource.py +8 -12
- mlrun/common/schemas/schedule.py +4 -4
- mlrun/common/schemas/tag.py +1 -2
- mlrun/common/schemas/workflow.py +12 -4
- mlrun/common/types.py +14 -1
- mlrun/config.py +154 -69
- mlrun/data_types/data_types.py +6 -1
- mlrun/data_types/spark.py +2 -2
- mlrun/data_types/to_pandas.py +67 -37
- mlrun/datastore/__init__.py +6 -8
- mlrun/datastore/alibaba_oss.py +131 -0
- mlrun/datastore/azure_blob.py +143 -42
- mlrun/datastore/base.py +102 -58
- mlrun/datastore/datastore.py +34 -13
- mlrun/datastore/datastore_profile.py +146 -20
- mlrun/datastore/dbfs_store.py +3 -7
- mlrun/datastore/filestore.py +1 -4
- mlrun/datastore/google_cloud_storage.py +97 -33
- mlrun/datastore/hdfs.py +56 -0
- mlrun/datastore/inmem.py +6 -3
- mlrun/datastore/redis.py +7 -2
- mlrun/datastore/s3.py +34 -12
- mlrun/datastore/snowflake_utils.py +45 -0
- mlrun/datastore/sources.py +303 -111
- mlrun/datastore/spark_utils.py +31 -2
- mlrun/datastore/store_resources.py +9 -7
- mlrun/datastore/storeytargets.py +151 -0
- mlrun/datastore/targets.py +453 -176
- mlrun/datastore/utils.py +72 -58
- mlrun/datastore/v3io.py +6 -1
- mlrun/db/base.py +274 -41
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +893 -225
- mlrun/db/nopdb.py +291 -33
- mlrun/errors.py +36 -6
- mlrun/execution.py +115 -42
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +65 -73
- mlrun/feature_store/common.py +7 -12
- mlrun/feature_store/feature_set.py +76 -55
- mlrun/feature_store/feature_vector.py +39 -31
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +16 -11
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +13 -4
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +24 -32
- mlrun/feature_store/steps.py +45 -34
- mlrun/features.py +11 -21
- mlrun/frameworks/_common/artifacts_library.py +9 -9
- mlrun/frameworks/_common/mlrun_interface.py +5 -5
- mlrun/frameworks/_common/model_handler.py +48 -48
- mlrun/frameworks/_common/plan.py +5 -6
- mlrun/frameworks/_common/producer.py +3 -4
- mlrun/frameworks/_common/utils.py +5 -5
- mlrun/frameworks/_dl_common/loggers/logger.py +6 -7
- mlrun/frameworks/_dl_common/loggers/mlrun_logger.py +9 -9
- mlrun/frameworks/_dl_common/loggers/tensorboard_logger.py +23 -47
- mlrun/frameworks/_ml_common/artifacts_library.py +1 -2
- mlrun/frameworks/_ml_common/loggers/logger.py +3 -4
- mlrun/frameworks/_ml_common/loggers/mlrun_logger.py +4 -5
- mlrun/frameworks/_ml_common/model_handler.py +24 -24
- mlrun/frameworks/_ml_common/pkl_model_server.py +2 -2
- mlrun/frameworks/_ml_common/plan.py +2 -2
- mlrun/frameworks/_ml_common/plans/calibration_curve_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/confusion_matrix_plan.py +2 -3
- mlrun/frameworks/_ml_common/plans/dataset_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/feature_importance_plan.py +3 -3
- mlrun/frameworks/_ml_common/plans/roc_curve_plan.py +4 -4
- mlrun/frameworks/_ml_common/utils.py +4 -4
- mlrun/frameworks/auto_mlrun/auto_mlrun.py +9 -9
- mlrun/frameworks/huggingface/model_server.py +4 -4
- mlrun/frameworks/lgbm/__init__.py +33 -33
- mlrun/frameworks/lgbm/callbacks/callback.py +2 -4
- mlrun/frameworks/lgbm/callbacks/logging_callback.py +4 -5
- mlrun/frameworks/lgbm/callbacks/mlrun_logging_callback.py +4 -5
- mlrun/frameworks/lgbm/mlrun_interfaces/booster_mlrun_interface.py +1 -3
- mlrun/frameworks/lgbm/mlrun_interfaces/mlrun_interface.py +6 -6
- mlrun/frameworks/lgbm/model_handler.py +10 -10
- mlrun/frameworks/lgbm/model_server.py +6 -6
- mlrun/frameworks/lgbm/utils.py +5 -5
- mlrun/frameworks/onnx/dataset.py +8 -8
- mlrun/frameworks/onnx/mlrun_interface.py +3 -3
- mlrun/frameworks/onnx/model_handler.py +6 -6
- mlrun/frameworks/onnx/model_server.py +7 -7
- mlrun/frameworks/parallel_coordinates.py +6 -6
- mlrun/frameworks/pytorch/__init__.py +18 -18
- mlrun/frameworks/pytorch/callbacks/callback.py +4 -5
- mlrun/frameworks/pytorch/callbacks/logging_callback.py +17 -17
- mlrun/frameworks/pytorch/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/pytorch/callbacks/tensorboard_logging_callback.py +23 -29
- mlrun/frameworks/pytorch/callbacks_handler.py +38 -38
- mlrun/frameworks/pytorch/mlrun_interface.py +20 -20
- mlrun/frameworks/pytorch/model_handler.py +17 -17
- mlrun/frameworks/pytorch/model_server.py +7 -7
- mlrun/frameworks/sklearn/__init__.py +13 -13
- mlrun/frameworks/sklearn/estimator.py +4 -4
- mlrun/frameworks/sklearn/metrics_library.py +14 -14
- mlrun/frameworks/sklearn/mlrun_interface.py +16 -9
- mlrun/frameworks/sklearn/model_handler.py +2 -2
- mlrun/frameworks/tf_keras/__init__.py +10 -7
- mlrun/frameworks/tf_keras/callbacks/logging_callback.py +15 -15
- mlrun/frameworks/tf_keras/callbacks/mlrun_logging_callback.py +11 -11
- mlrun/frameworks/tf_keras/callbacks/tensorboard_logging_callback.py +19 -23
- mlrun/frameworks/tf_keras/mlrun_interface.py +9 -11
- mlrun/frameworks/tf_keras/model_handler.py +14 -14
- mlrun/frameworks/tf_keras/model_server.py +6 -6
- mlrun/frameworks/xgboost/__init__.py +13 -13
- mlrun/frameworks/xgboost/model_handler.py +6 -6
- mlrun/k8s_utils.py +61 -17
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +16 -15
- mlrun/launcher/client.py +13 -11
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +23 -13
- mlrun/launcher/remote.py +17 -10
- mlrun/lists.py +7 -6
- mlrun/model.py +478 -103
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +163 -371
- mlrun/{runtimes/mpijob/v1alpha1.py → model_monitoring/applications/__init__.py} +9 -15
- mlrun/model_monitoring/applications/_application_steps.py +188 -0
- mlrun/model_monitoring/applications/base.py +108 -0
- mlrun/model_monitoring/applications/context.py +341 -0
- mlrun/model_monitoring/{evidently_application.py → applications/evidently_base.py} +27 -22
- mlrun/model_monitoring/applications/histogram_data_drift.py +354 -0
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +131 -278
- mlrun/model_monitoring/db/__init__.py +18 -0
- mlrun/model_monitoring/db/stores/__init__.py +136 -0
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/db/stores/base/store.py +213 -0
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +190 -0
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +103 -0
- mlrun/model_monitoring/{stores/models/mysql.py → db/stores/sqldb/models/sqlite.py} +19 -13
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +659 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +726 -0
- mlrun/model_monitoring/db/tsdb/__init__.py +105 -0
- mlrun/model_monitoring/db/tsdb/base.py +448 -0
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +279 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +42 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +507 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +158 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +849 -0
- mlrun/model_monitoring/features_drift_table.py +134 -106
- mlrun/model_monitoring/helpers.py +199 -55
- mlrun/model_monitoring/metrics/__init__.py +13 -0
- mlrun/model_monitoring/metrics/histogram_distance.py +127 -0
- mlrun/model_monitoring/model_endpoint.py +3 -2
- mlrun/model_monitoring/stream_processing.py +131 -398
- mlrun/model_monitoring/tracking_policy.py +9 -2
- mlrun/model_monitoring/writer.py +161 -125
- mlrun/package/__init__.py +6 -6
- mlrun/package/context_handler.py +5 -5
- mlrun/package/packager.py +7 -7
- mlrun/package/packagers/default_packager.py +8 -8
- mlrun/package/packagers/numpy_packagers.py +15 -15
- mlrun/package/packagers/pandas_packagers.py +5 -5
- mlrun/package/packagers/python_standard_library_packagers.py +10 -10
- mlrun/package/packagers_manager.py +19 -23
- mlrun/package/utils/_formatter.py +6 -6
- mlrun/package/utils/_pickler.py +2 -2
- mlrun/package/utils/_supported_format.py +4 -4
- mlrun/package/utils/log_hint_utils.py +2 -2
- mlrun/package/utils/type_hint_utils.py +4 -9
- mlrun/platforms/__init__.py +11 -10
- mlrun/platforms/iguazio.py +24 -203
- mlrun/projects/operations.py +52 -25
- mlrun/projects/pipelines.py +191 -197
- mlrun/projects/project.py +1227 -400
- mlrun/render.py +16 -19
- mlrun/run.py +209 -184
- mlrun/runtimes/__init__.py +83 -15
- mlrun/runtimes/base.py +51 -35
- mlrun/runtimes/daskjob.py +17 -10
- mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +8 -7
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +1 -29
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/kubejob.py +34 -128
- mlrun/runtimes/local.py +40 -11
- mlrun/runtimes/mpijob/__init__.py +0 -20
- mlrun/runtimes/mpijob/abstract.py +9 -10
- mlrun/runtimes/mpijob/v1.py +1 -1
- mlrun/{model_monitoring/stores/models/sqlite.py → runtimes/nuclio/__init__.py} +7 -9
- mlrun/runtimes/nuclio/api_gateway.py +769 -0
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +758 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/{function.py → nuclio/function.py} +200 -83
- mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
- mlrun/runtimes/{serving.py → nuclio/serving.py} +65 -68
- mlrun/runtimes/pod.py +281 -101
- mlrun/runtimes/remotesparkjob.py +12 -9
- mlrun/runtimes/sparkjob/spark3job.py +67 -51
- mlrun/runtimes/utils.py +41 -75
- mlrun/secrets.py +9 -5
- mlrun/serving/__init__.py +8 -1
- mlrun/serving/remote.py +2 -7
- mlrun/serving/routers.py +85 -69
- mlrun/serving/server.py +69 -44
- mlrun/serving/states.py +209 -36
- mlrun/serving/utils.py +22 -14
- mlrun/serving/v1_serving.py +6 -7
- mlrun/serving/v2_serving.py +129 -54
- mlrun/track/tracker.py +2 -1
- mlrun/track/tracker_manager.py +3 -3
- mlrun/track/trackers/mlflow_tracker.py +6 -2
- mlrun/utils/async_http.py +6 -8
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +1 -2
- mlrun/utils/condition_evaluator.py +3 -3
- mlrun/utils/db.py +21 -3
- mlrun/utils/helpers.py +405 -225
- mlrun/utils/http.py +3 -6
- mlrun/utils/logger.py +112 -16
- mlrun/utils/notifications/notification/__init__.py +17 -13
- mlrun/utils/notifications/notification/base.py +50 -2
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +24 -1
- mlrun/utils/notifications/notification/ipython.py +3 -1
- mlrun/utils/notifications/notification/slack.py +96 -21
- mlrun/utils/notifications/notification/webhook.py +59 -2
- mlrun/utils/notifications/notification_pusher.py +149 -30
- mlrun/utils/regex.py +9 -0
- mlrun/utils/retryer.py +208 -0
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +4 -6
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +2 -6
- mlrun-1.7.0.dist-info/METADATA +378 -0
- mlrun-1.7.0.dist-info/RECORD +351 -0
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/WHEEL +1 -1
- mlrun/feature_store/retrieval/conversion.py +0 -273
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/application.py +0 -310
- mlrun/model_monitoring/batch.py +0 -1095
- mlrun/model_monitoring/prometheus.py +0 -219
- mlrun/model_monitoring/stores/__init__.py +0 -111
- mlrun/model_monitoring/stores/kv_model_endpoint_store.py +0 -576
- mlrun/model_monitoring/stores/model_endpoint_store.py +0 -147
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/models/base.py +0 -84
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
- mlrun/platforms/other.py +0 -306
- mlrun-1.6.4rc7.dist-info/METADATA +0 -272
- mlrun-1.6.4rc7.dist-info/RECORD +0 -314
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/LICENSE +0 -0
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/entry_points.txt +0 -0
- {mlrun-1.6.4rc7.dist-info → mlrun-1.7.0.dist-info}/top_level.txt +0 -0
mlrun/db/httpdb.py
CHANGED
|
@@ -11,28 +11,36 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
+
|
|
14
15
|
import enum
|
|
15
16
|
import http
|
|
16
17
|
import re
|
|
17
|
-
import tempfile
|
|
18
18
|
import time
|
|
19
19
|
import traceback
|
|
20
20
|
import typing
|
|
21
21
|
import warnings
|
|
22
|
+
from copy import deepcopy
|
|
22
23
|
from datetime import datetime, timedelta
|
|
23
24
|
from os import path, remove
|
|
24
|
-
from typing import
|
|
25
|
+
from typing import Optional, Union
|
|
25
26
|
from urllib.parse import urlparse
|
|
26
27
|
|
|
27
|
-
import kfp
|
|
28
28
|
import requests
|
|
29
29
|
import semver
|
|
30
|
+
from mlrun_pipelines.utils import compile_pipeline
|
|
30
31
|
|
|
31
32
|
import mlrun
|
|
33
|
+
import mlrun.common.formatters
|
|
34
|
+
import mlrun.common.runtimes
|
|
32
35
|
import mlrun.common.schemas
|
|
36
|
+
import mlrun.common.types
|
|
33
37
|
import mlrun.model_monitoring.model_endpoint
|
|
34
38
|
import mlrun.platforms
|
|
35
39
|
import mlrun.projects
|
|
40
|
+
import mlrun.runtimes.nuclio.api_gateway
|
|
41
|
+
import mlrun.runtimes.nuclio.function
|
|
42
|
+
import mlrun.utils
|
|
43
|
+
from mlrun.alerts.alert import AlertConfig
|
|
36
44
|
from mlrun.db.auth_utils import OAuthClientIDTokenProvider, StaticTokenProvider
|
|
37
45
|
from mlrun.errors import MLRunInvalidArgumentError, err_to_str
|
|
38
46
|
|
|
@@ -46,7 +54,6 @@ from ..utils import (
|
|
|
46
54
|
datetime_to_iso,
|
|
47
55
|
dict_to_json,
|
|
48
56
|
logger,
|
|
49
|
-
new_pipe_metadata,
|
|
50
57
|
normalize_name,
|
|
51
58
|
version,
|
|
52
59
|
)
|
|
@@ -191,7 +198,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
191
198
|
headers=None,
|
|
192
199
|
timeout=45,
|
|
193
200
|
version=None,
|
|
194
|
-
):
|
|
201
|
+
) -> requests.Response:
|
|
195
202
|
"""Perform a direct REST API call on the :py:mod:`mlrun` API server.
|
|
196
203
|
|
|
197
204
|
Caution:
|
|
@@ -209,7 +216,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
209
216
|
:param version: API version to use, None (the default) will mean to use the default value from config,
|
|
210
217
|
for un-versioned api set an empty string.
|
|
211
218
|
|
|
212
|
-
:
|
|
219
|
+
:returns: `requests.Response` HTTP response object
|
|
213
220
|
"""
|
|
214
221
|
url = self.get_base_api_url(path, version)
|
|
215
222
|
kw = {
|
|
@@ -292,6 +299,68 @@ class HTTPRunDB(RunDBInterface):
|
|
|
292
299
|
|
|
293
300
|
return response
|
|
294
301
|
|
|
302
|
+
def paginated_api_call(
|
|
303
|
+
self,
|
|
304
|
+
method,
|
|
305
|
+
path,
|
|
306
|
+
error=None,
|
|
307
|
+
params=None,
|
|
308
|
+
body=None,
|
|
309
|
+
json=None,
|
|
310
|
+
headers=None,
|
|
311
|
+
timeout=45,
|
|
312
|
+
version=None,
|
|
313
|
+
) -> typing.Generator[requests.Response, None, None]:
|
|
314
|
+
"""
|
|
315
|
+
Calls the api with pagination, yielding each page of the response
|
|
316
|
+
"""
|
|
317
|
+
|
|
318
|
+
def _api_call(_params):
|
|
319
|
+
return self.api_call(
|
|
320
|
+
method=method,
|
|
321
|
+
path=path,
|
|
322
|
+
error=error,
|
|
323
|
+
params=_params,
|
|
324
|
+
body=body,
|
|
325
|
+
json=json,
|
|
326
|
+
headers=headers,
|
|
327
|
+
timeout=timeout,
|
|
328
|
+
version=version,
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
first_page_params = deepcopy(params) or {}
|
|
332
|
+
first_page_params["page"] = 1
|
|
333
|
+
first_page_params["page-size"] = config.httpdb.pagination.default_page_size
|
|
334
|
+
response = _api_call(first_page_params)
|
|
335
|
+
page_token = response.json().get("pagination", {}).get("page-token")
|
|
336
|
+
if not page_token:
|
|
337
|
+
yield response
|
|
338
|
+
return
|
|
339
|
+
|
|
340
|
+
params_with_page_token = deepcopy(params) or {}
|
|
341
|
+
params_with_page_token["page-token"] = page_token
|
|
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
|
|
349
|
+
|
|
350
|
+
page_token = response.json().get("pagination", {}).get("page-token", None)
|
|
351
|
+
|
|
352
|
+
@staticmethod
|
|
353
|
+
def process_paginated_responses(
|
|
354
|
+
responses: typing.Generator[requests.Response, None, None], key: str = "data"
|
|
355
|
+
) -> list[typing.Any]:
|
|
356
|
+
"""
|
|
357
|
+
Processes the paginated responses and returns the combined data
|
|
358
|
+
"""
|
|
359
|
+
data = []
|
|
360
|
+
for response in responses:
|
|
361
|
+
data.extend(response.json().get(key, []))
|
|
362
|
+
return data
|
|
363
|
+
|
|
295
364
|
def _init_session(self, retry_on_post: bool = False):
|
|
296
365
|
return mlrun.utils.HTTPSessionWithRetry(
|
|
297
366
|
retry_on_exception=config.httpdb.retry_api_call_on_exception
|
|
@@ -324,7 +393,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
324
393
|
|
|
325
394
|
For example::
|
|
326
395
|
|
|
327
|
-
config.dbpath = config.dbpath or
|
|
396
|
+
config.dbpath = config.dbpath or "http://mlrun-api:8080"
|
|
328
397
|
db = get_run_db().connect()
|
|
329
398
|
"""
|
|
330
399
|
# hack to allow unit tests to instantiate HTTPRunDB without a real server behind
|
|
@@ -456,14 +525,18 @@ class HTTPRunDB(RunDBInterface):
|
|
|
456
525
|
server_cfg.get("external_platform_tracking")
|
|
457
526
|
or config.external_platform_tracking
|
|
458
527
|
)
|
|
459
|
-
config.model_endpoint_monitoring.store_type = (
|
|
460
|
-
server_cfg.get("model_endpoint_monitoring_store_type")
|
|
461
|
-
or config.model_endpoint_monitoring.store_type
|
|
462
|
-
)
|
|
463
528
|
config.model_endpoint_monitoring.endpoint_store_connection = (
|
|
464
529
|
server_cfg.get("model_endpoint_monitoring_endpoint_store_connection")
|
|
465
530
|
or config.model_endpoint_monitoring.endpoint_store_connection
|
|
466
531
|
)
|
|
532
|
+
config.model_endpoint_monitoring.tsdb_connection = (
|
|
533
|
+
server_cfg.get("model_monitoring_tsdb_connection")
|
|
534
|
+
or config.model_endpoint_monitoring.tsdb_connection
|
|
535
|
+
)
|
|
536
|
+
config.model_endpoint_monitoring.stream_connection = (
|
|
537
|
+
server_cfg.get("stream_connection")
|
|
538
|
+
or config.model_endpoint_monitoring.stream_connection
|
|
539
|
+
)
|
|
467
540
|
config.packagers = server_cfg.get("packagers") or config.packagers
|
|
468
541
|
server_data_prefixes = server_cfg.get("feature_store_data_prefixes") or {}
|
|
469
542
|
for prefix in ["default", "nosql", "redisnosql"]:
|
|
@@ -472,6 +545,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
472
545
|
setattr(
|
|
473
546
|
config.feature_store.data_prefixes, prefix, server_prefix_value
|
|
474
547
|
)
|
|
548
|
+
config.feature_store.default_targets = (
|
|
549
|
+
server_cfg.get("feature_store_default_targets")
|
|
550
|
+
or config.feature_store.default_targets
|
|
551
|
+
)
|
|
552
|
+
config.alerts.mode = server_cfg.get("alerts_mode") or config.alerts.mode
|
|
475
553
|
|
|
476
554
|
except Exception as exc:
|
|
477
555
|
logger.warning(
|
|
@@ -518,7 +596,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
518
596
|
if offset < 0:
|
|
519
597
|
raise MLRunInvalidArgumentError("Offset cannot be negative")
|
|
520
598
|
if size is None:
|
|
521
|
-
size = int(
|
|
599
|
+
size = int(mlrun.mlconf.httpdb.logs.pull_logs_default_size_limit)
|
|
522
600
|
elif size == -1:
|
|
523
601
|
logger.warning(
|
|
524
602
|
"Retrieving all logs. This may be inefficient and can result in a large log."
|
|
@@ -564,33 +642,35 @@ class HTTPRunDB(RunDBInterface):
|
|
|
564
642
|
|
|
565
643
|
state, text = self.get_log(uid, project, offset=offset)
|
|
566
644
|
if text:
|
|
567
|
-
print(text.decode(errors=
|
|
645
|
+
print(text.decode(errors=mlrun.mlconf.httpdb.logs.decode.errors))
|
|
568
646
|
nil_resp = 0
|
|
569
647
|
while True:
|
|
570
648
|
offset += len(text)
|
|
571
649
|
# if we get 3 nil responses in a row, increase the sleep time to 10 seconds
|
|
572
650
|
# TODO: refactor this to use a conditional backoff mechanism
|
|
573
651
|
if nil_resp < 3:
|
|
574
|
-
time.sleep(int(
|
|
652
|
+
time.sleep(int(mlrun.mlconf.httpdb.logs.pull_logs_default_interval))
|
|
575
653
|
else:
|
|
576
654
|
time.sleep(
|
|
577
|
-
int(
|
|
655
|
+
int(
|
|
656
|
+
mlrun.mlconf.httpdb.logs.pull_logs_backoff_no_logs_default_interval
|
|
657
|
+
)
|
|
578
658
|
)
|
|
579
659
|
state, text = self.get_log(uid, project, offset=offset)
|
|
580
660
|
if text:
|
|
581
661
|
nil_resp = 0
|
|
582
662
|
print(
|
|
583
|
-
text.decode(errors=
|
|
663
|
+
text.decode(errors=mlrun.mlconf.httpdb.logs.decode.errors),
|
|
584
664
|
end="",
|
|
585
665
|
)
|
|
586
666
|
else:
|
|
587
667
|
nil_resp += 1
|
|
588
668
|
|
|
589
669
|
if watch and state in [
|
|
590
|
-
mlrun.runtimes.constants.RunStates.pending,
|
|
591
|
-
mlrun.runtimes.constants.RunStates.running,
|
|
592
|
-
mlrun.runtimes.constants.RunStates.created,
|
|
593
|
-
mlrun.runtimes.constants.RunStates.aborting,
|
|
670
|
+
mlrun.common.runtimes.constants.RunStates.pending,
|
|
671
|
+
mlrun.common.runtimes.constants.RunStates.running,
|
|
672
|
+
mlrun.common.runtimes.constants.RunStates.created,
|
|
673
|
+
mlrun.common.runtimes.constants.RunStates.aborting,
|
|
594
674
|
]:
|
|
595
675
|
continue
|
|
596
676
|
else:
|
|
@@ -651,7 +731,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
651
731
|
uid,
|
|
652
732
|
project="",
|
|
653
733
|
iter=0,
|
|
654
|
-
format_: mlrun.common.
|
|
734
|
+
format_: mlrun.common.formatters.RunFormat = mlrun.common.formatters.RunFormat.full,
|
|
655
735
|
):
|
|
656
736
|
"""Read the details of a stored run from the DB.
|
|
657
737
|
|
|
@@ -686,10 +766,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
686
766
|
def list_runs(
|
|
687
767
|
self,
|
|
688
768
|
name: Optional[str] = None,
|
|
689
|
-
uid: Optional[Union[str,
|
|
769
|
+
uid: Optional[Union[str, list[str]]] = None,
|
|
690
770
|
project: Optional[str] = None,
|
|
691
|
-
labels: Optional[Union[str,
|
|
692
|
-
state: Optional[
|
|
771
|
+
labels: Optional[Union[str, list[str]]] = None,
|
|
772
|
+
state: Optional[
|
|
773
|
+
mlrun.common.runtimes.constants.RunStates
|
|
774
|
+
] = None, # Backward compatibility
|
|
775
|
+
states: typing.Optional[list[mlrun.common.runtimes.constants.RunStates]] = None,
|
|
693
776
|
sort: bool = True,
|
|
694
777
|
last: int = 0,
|
|
695
778
|
iter: bool = False,
|
|
@@ -714,9 +797,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
714
797
|
|
|
715
798
|
Example::
|
|
716
799
|
|
|
717
|
-
runs = db.list_runs(
|
|
800
|
+
runs = db.list_runs(
|
|
801
|
+
name="download", project="iris", labels=["owner=admin", "kind=job"]
|
|
802
|
+
)
|
|
718
803
|
# If running in Jupyter, can use the .show() function to display the results
|
|
719
|
-
db.list_runs(name=
|
|
804
|
+
db.list_runs(name="", project=project_name).show()
|
|
720
805
|
|
|
721
806
|
|
|
722
807
|
:param name: Name of the run to retrieve.
|
|
@@ -725,7 +810,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
725
810
|
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value
|
|
726
811
|
of a label (i.e. list("key=value")) or by looking for the existence of a given
|
|
727
812
|
key (i.e. "key").
|
|
728
|
-
:param state: List only runs whose state is specified.
|
|
813
|
+
:param state: Deprecated - List only runs whose state is specified (will be removed in 1.9.0)
|
|
814
|
+
:param states: List only runs whose state is one of the provided states.
|
|
729
815
|
:param sort: Whether to sort the result according to their start time. Otherwise, results will be
|
|
730
816
|
returned by their internal order in the DB (order will not be guaranteed).
|
|
731
817
|
:param last: Deprecated - currently not used (will be removed in 1.8.0).
|
|
@@ -761,11 +847,19 @@ class HTTPRunDB(RunDBInterface):
|
|
|
761
847
|
FutureWarning,
|
|
762
848
|
)
|
|
763
849
|
|
|
850
|
+
if state:
|
|
851
|
+
# TODO: Remove this in 1.9.0
|
|
852
|
+
warnings.warn(
|
|
853
|
+
"'state' is deprecated and will be removed in 1.9.0. Use 'states' instead.",
|
|
854
|
+
FutureWarning,
|
|
855
|
+
)
|
|
856
|
+
|
|
764
857
|
if (
|
|
765
858
|
not name
|
|
766
859
|
and not uid
|
|
767
860
|
and not labels
|
|
768
861
|
and not state
|
|
862
|
+
and not states
|
|
769
863
|
and not last
|
|
770
864
|
and not start_time_from
|
|
771
865
|
and not start_time_to
|
|
@@ -777,14 +871,16 @@ class HTTPRunDB(RunDBInterface):
|
|
|
777
871
|
):
|
|
778
872
|
# default to last week on no filter
|
|
779
873
|
start_time_from = datetime.now() - timedelta(days=7)
|
|
780
|
-
partition_by = mlrun.common.schemas.RunPartitionByField.
|
|
874
|
+
partition_by = mlrun.common.schemas.RunPartitionByField.project_and_name
|
|
781
875
|
partition_sort_by = mlrun.common.schemas.SortField.updated
|
|
782
876
|
|
|
783
877
|
params = {
|
|
784
878
|
"name": name,
|
|
785
879
|
"uid": uid,
|
|
786
880
|
"label": labels or [],
|
|
787
|
-
"state": state
|
|
881
|
+
"state": mlrun.utils.helpers.as_list(state)
|
|
882
|
+
if state is not None
|
|
883
|
+
else states or None,
|
|
788
884
|
"sort": bool2str(sort),
|
|
789
885
|
"iter": bool2str(iter),
|
|
790
886
|
"start_time_from": datetime_to_iso(start_time_from),
|
|
@@ -807,15 +903,15 @@ class HTTPRunDB(RunDBInterface):
|
|
|
807
903
|
)
|
|
808
904
|
error = "list runs"
|
|
809
905
|
_path = self._path_of("runs", project)
|
|
810
|
-
|
|
811
|
-
return RunList(
|
|
906
|
+
responses = self.paginated_api_call("GET", _path, error, params=params)
|
|
907
|
+
return RunList(self.process_paginated_responses(responses, "runs"))
|
|
812
908
|
|
|
813
909
|
def del_runs(self, name=None, project=None, labels=None, state=None, days_ago=0):
|
|
814
910
|
"""Delete a group of runs identified by the parameters of the function.
|
|
815
911
|
|
|
816
912
|
Example::
|
|
817
913
|
|
|
818
|
-
db.del_runs(state=
|
|
914
|
+
db.del_runs(state="completed")
|
|
819
915
|
|
|
820
916
|
:param name: Name of the task which the runs belong to.
|
|
821
917
|
:param project: Project to which the runs belong.
|
|
@@ -868,7 +964,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
868
964
|
|
|
869
965
|
# we do this because previously the 'uid' name was used for the 'tree' parameter
|
|
870
966
|
tree = tree or uid
|
|
871
|
-
|
|
967
|
+
project = project or mlrun.mlconf.default_project
|
|
872
968
|
endpoint_path = f"projects/{project}/artifacts/{key}"
|
|
873
969
|
|
|
874
970
|
error = f"store artifact {project}/{key}"
|
|
@@ -894,6 +990,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
894
990
|
project="",
|
|
895
991
|
tree=None,
|
|
896
992
|
uid=None,
|
|
993
|
+
format_: mlrun.common.formatters.ArtifactFormat = mlrun.common.formatters.ArtifactFormat.full,
|
|
897
994
|
):
|
|
898
995
|
"""Read an artifact, identified by its key, tag, tree and iteration.
|
|
899
996
|
|
|
@@ -903,25 +1000,37 @@ class HTTPRunDB(RunDBInterface):
|
|
|
903
1000
|
:param project: Project that the artifact belongs to.
|
|
904
1001
|
:param tree: The tree which generated this artifact.
|
|
905
1002
|
:param uid: A unique ID for this specific version of the artifact (the uid that was generated in the backend)
|
|
1003
|
+
:param format_: The format in which to return the artifact. Default is 'full'.
|
|
906
1004
|
"""
|
|
907
1005
|
|
|
908
|
-
project = project or
|
|
1006
|
+
project = project or mlrun.mlconf.default_project
|
|
909
1007
|
tag = tag or "latest"
|
|
910
1008
|
endpoint_path = f"projects/{project}/artifacts/{key}"
|
|
911
1009
|
error = f"read artifact {project}/{key}"
|
|
912
|
-
# explicitly set artifacts format to 'full' since old servers may default to 'legacy'
|
|
913
1010
|
params = {
|
|
914
|
-
"format":
|
|
1011
|
+
"format": format_,
|
|
915
1012
|
"tag": tag,
|
|
916
1013
|
"tree": tree,
|
|
917
|
-
"uid": uid,
|
|
1014
|
+
"object-uid": uid,
|
|
918
1015
|
}
|
|
919
|
-
if iter:
|
|
1016
|
+
if iter is not None:
|
|
920
1017
|
params["iter"] = str(iter)
|
|
921
1018
|
resp = self.api_call("GET", endpoint_path, error, params=params, version="v2")
|
|
922
1019
|
return resp.json()
|
|
923
1020
|
|
|
924
|
-
def del_artifact(
|
|
1021
|
+
def del_artifact(
|
|
1022
|
+
self,
|
|
1023
|
+
key,
|
|
1024
|
+
tag=None,
|
|
1025
|
+
project="",
|
|
1026
|
+
tree=None,
|
|
1027
|
+
uid=None,
|
|
1028
|
+
deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
|
|
1029
|
+
mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
|
|
1030
|
+
),
|
|
1031
|
+
secrets: dict = None,
|
|
1032
|
+
iter=None,
|
|
1033
|
+
):
|
|
925
1034
|
"""Delete an artifact.
|
|
926
1035
|
|
|
927
1036
|
:param key: Identifying key of the artifact.
|
|
@@ -929,32 +1038,44 @@ class HTTPRunDB(RunDBInterface):
|
|
|
929
1038
|
:param project: Project that the artifact belongs to.
|
|
930
1039
|
:param tree: The tree which generated this artifact.
|
|
931
1040
|
:param uid: A unique ID for this specific version of the artifact (the uid that was generated in the backend)
|
|
1041
|
+
:param deletion_strategy: The artifact deletion strategy types.
|
|
1042
|
+
:param secrets: Credentials needed to access the artifact data.
|
|
932
1043
|
"""
|
|
933
|
-
|
|
1044
|
+
project = project or mlrun.mlconf.default_project
|
|
934
1045
|
endpoint_path = f"projects/{project}/artifacts/{key}"
|
|
935
1046
|
params = {
|
|
936
1047
|
"key": key,
|
|
937
1048
|
"tag": tag,
|
|
938
1049
|
"tree": tree,
|
|
939
|
-
"uid": uid,
|
|
1050
|
+
"object-uid": uid,
|
|
1051
|
+
"iter": iter,
|
|
1052
|
+
"deletion_strategy": deletion_strategy,
|
|
940
1053
|
}
|
|
941
1054
|
error = f"del artifact {project}/{key}"
|
|
942
|
-
self.api_call(
|
|
1055
|
+
self.api_call(
|
|
1056
|
+
"DELETE",
|
|
1057
|
+
endpoint_path,
|
|
1058
|
+
error,
|
|
1059
|
+
params=params,
|
|
1060
|
+
version="v2",
|
|
1061
|
+
body=dict_to_json(secrets),
|
|
1062
|
+
)
|
|
943
1063
|
|
|
944
1064
|
def list_artifacts(
|
|
945
1065
|
self,
|
|
946
1066
|
name=None,
|
|
947
1067
|
project=None,
|
|
948
1068
|
tag=None,
|
|
949
|
-
labels: Optional[Union[
|
|
950
|
-
since=None,
|
|
951
|
-
until=None,
|
|
1069
|
+
labels: Optional[Union[dict[str, str], list[str]]] = None,
|
|
1070
|
+
since: Optional[datetime] = None,
|
|
1071
|
+
until: Optional[datetime] = None,
|
|
952
1072
|
iter: int = None,
|
|
953
1073
|
best_iteration: bool = False,
|
|
954
1074
|
kind: str = None,
|
|
955
1075
|
category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
|
|
956
1076
|
tree: str = None,
|
|
957
1077
|
producer_uri: str = None,
|
|
1078
|
+
format_: mlrun.common.formatters.ArtifactFormat = mlrun.common.formatters.ArtifactFormat.full,
|
|
958
1079
|
limit: int = None,
|
|
959
1080
|
) -> ArtifactList:
|
|
960
1081
|
"""List artifacts filtered by various parameters.
|
|
@@ -962,11 +1083,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
962
1083
|
Examples::
|
|
963
1084
|
|
|
964
1085
|
# Show latest version of all artifacts in project
|
|
965
|
-
latest_artifacts = db.list_artifacts(
|
|
1086
|
+
latest_artifacts = db.list_artifacts("", tag="latest", project="iris")
|
|
966
1087
|
# check different artifact versions for a specific artifact
|
|
967
|
-
result_versions = db.list_artifacts(
|
|
1088
|
+
result_versions = db.list_artifacts("results", tag="*", project="iris")
|
|
968
1089
|
# Show artifacts with label filters - both uploaded and of binary type
|
|
969
|
-
result_labels = db.list_artifacts(
|
|
1090
|
+
result_labels = db.list_artifacts(
|
|
1091
|
+
"results", tag="*", project="iris", labels=["uploaded", "type=binary"]
|
|
1092
|
+
)
|
|
970
1093
|
|
|
971
1094
|
:param name: Name of artifacts to retrieve. Name with '~' prefix is used as a like query, and is not
|
|
972
1095
|
case-sensitive. This means that querying for ``~name`` may return artifacts named
|
|
@@ -975,8 +1098,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
975
1098
|
:param tag: Return artifacts assigned this tag.
|
|
976
1099
|
:param labels: Return artifacts that have these labels. Labels can either be a dictionary {"label": "value"} or
|
|
977
1100
|
a list of "label=value" (match label key and value) or "label" (match just label key) strings.
|
|
978
|
-
:param since:
|
|
979
|
-
:param until:
|
|
1101
|
+
:param since: Return artifacts updated after this date (as datetime object).
|
|
1102
|
+
:param until: Return artifacts updated before this date (as datetime object).
|
|
980
1103
|
:param iter: Return artifacts from a specific iteration (where ``iter=0`` means the root iteration). If
|
|
981
1104
|
``None`` (default) return artifacts from all iterations.
|
|
982
1105
|
:param best_iteration: Returns the artifact which belongs to the best iteration of a given run, in the case of
|
|
@@ -988,6 +1111,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
988
1111
|
:param producer_uri: Return artifacts produced by the requested producer URI. Producer URI usually
|
|
989
1112
|
points to a run and is used to filter artifacts by the run that produced them when the artifact producer id
|
|
990
1113
|
is a workflow id (artifact was created as part of a workflow).
|
|
1114
|
+
:param format_: The format in which to return the artifacts. Default is 'full'.
|
|
991
1115
|
:param limit: Maximum number of artifacts to return.
|
|
992
1116
|
"""
|
|
993
1117
|
|
|
@@ -1006,9 +1130,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1006
1130
|
"kind": kind,
|
|
1007
1131
|
"category": category,
|
|
1008
1132
|
"tree": tree,
|
|
1009
|
-
"format":
|
|
1133
|
+
"format": format_,
|
|
1010
1134
|
"producer_uri": producer_uri,
|
|
1011
1135
|
"limit": limit,
|
|
1136
|
+
"since": datetime_to_iso(since),
|
|
1137
|
+
"until": datetime_to_iso(until),
|
|
1012
1138
|
}
|
|
1013
1139
|
error = "list artifacts"
|
|
1014
1140
|
endpoint_path = f"projects/{project}/artifacts"
|
|
@@ -1045,7 +1171,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1045
1171
|
self,
|
|
1046
1172
|
project=None,
|
|
1047
1173
|
category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
|
|
1048
|
-
) ->
|
|
1174
|
+
) -> list[str]:
|
|
1049
1175
|
"""Return a list of all the tags assigned to artifacts in the scope of the given project."""
|
|
1050
1176
|
|
|
1051
1177
|
project = project or config.default_project
|
|
@@ -1098,15 +1224,44 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1098
1224
|
project = project or config.default_project
|
|
1099
1225
|
path = f"projects/{project}/functions/{name}"
|
|
1100
1226
|
error_message = f"Failed deleting function {project}/{name}"
|
|
1101
|
-
self.api_call("DELETE", path, error_message)
|
|
1227
|
+
response = self.api_call("DELETE", path, error_message, version="v2")
|
|
1228
|
+
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
1229
|
+
logger.info(
|
|
1230
|
+
"Function is being deleted", project_name=project, function_name=name
|
|
1231
|
+
)
|
|
1232
|
+
background_task = mlrun.common.schemas.BackgroundTask(**response.json())
|
|
1233
|
+
background_task = self._wait_for_background_task_to_reach_terminal_state(
|
|
1234
|
+
background_task.metadata.name, project=project
|
|
1235
|
+
)
|
|
1236
|
+
if (
|
|
1237
|
+
background_task.status.state
|
|
1238
|
+
== mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
1239
|
+
):
|
|
1240
|
+
logger.info(
|
|
1241
|
+
"Function deleted", project_name=project, function_name=name
|
|
1242
|
+
)
|
|
1243
|
+
elif (
|
|
1244
|
+
background_task.status.state
|
|
1245
|
+
== mlrun.common.schemas.BackgroundTaskState.failed
|
|
1246
|
+
):
|
|
1247
|
+
logger.info(
|
|
1248
|
+
"Function deletion failed",
|
|
1249
|
+
reason=background_task.status.error,
|
|
1250
|
+
project_name=project,
|
|
1251
|
+
function_name=name,
|
|
1252
|
+
)
|
|
1102
1253
|
|
|
1103
|
-
def list_functions(
|
|
1254
|
+
def list_functions(
|
|
1255
|
+
self, name=None, project=None, tag=None, labels=None, since=None, until=None
|
|
1256
|
+
):
|
|
1104
1257
|
"""Retrieve a list of functions, filtered by specific criteria.
|
|
1105
1258
|
|
|
1106
1259
|
:param name: Return only functions with a specific name.
|
|
1107
1260
|
:param project: Return functions belonging to this project. If not specified, the default project is used.
|
|
1108
|
-
:param tag: Return function versions with specific tags.
|
|
1261
|
+
:param tag: Return function versions with specific tags. To return only tagged functions, set tag to ``"*"``.
|
|
1109
1262
|
:param labels: Return functions that have specific labels assigned to them.
|
|
1263
|
+
:param since: Return functions updated after this date (as datetime object).
|
|
1264
|
+
:param until: Return functions updated before this date (as datetime object).
|
|
1110
1265
|
:returns: List of function objects (as dictionary).
|
|
1111
1266
|
"""
|
|
1112
1267
|
project = project or config.default_project
|
|
@@ -1114,11 +1269,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1114
1269
|
"name": name,
|
|
1115
1270
|
"tag": tag,
|
|
1116
1271
|
"label": labels or [],
|
|
1272
|
+
"since": datetime_to_iso(since),
|
|
1273
|
+
"until": datetime_to_iso(until),
|
|
1117
1274
|
}
|
|
1118
1275
|
error = "list functions"
|
|
1119
1276
|
path = f"projects/{project}/functions"
|
|
1120
|
-
|
|
1121
|
-
return
|
|
1277
|
+
responses = self.paginated_api_call("GET", path, error, params=params)
|
|
1278
|
+
return self.process_paginated_responses(responses, "funcs")
|
|
1122
1279
|
|
|
1123
1280
|
def list_runtime_resources(
|
|
1124
1281
|
self,
|
|
@@ -1208,25 +1365,19 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1208
1365
|
period didn't pass.
|
|
1209
1366
|
:param grace_period: Grace period given to the runtime resource before they are actually removed, counted from
|
|
1210
1367
|
the moment they moved to terminal state
|
|
1211
|
-
(defaults to mlrun.
|
|
1368
|
+
(defaults to mlrun.mlconf.runtime_resources_deletion_grace_period).
|
|
1212
1369
|
|
|
1213
1370
|
:returns: :py:class:`~mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput` listing the runtime resources
|
|
1214
1371
|
that were removed.
|
|
1215
1372
|
"""
|
|
1216
|
-
if grace_period is None:
|
|
1217
|
-
grace_period = config.runtime_resources_deletion_grace_period
|
|
1218
|
-
logger.info(
|
|
1219
|
-
"Using default grace period for runtime resources deletion",
|
|
1220
|
-
grace_period=grace_period,
|
|
1221
|
-
)
|
|
1222
|
-
|
|
1223
1373
|
params = {
|
|
1224
1374
|
"label-selector": label_selector,
|
|
1225
1375
|
"kind": kind,
|
|
1226
1376
|
"object-id": object_id,
|
|
1227
1377
|
"force": force,
|
|
1228
|
-
"grace-period": grace_period,
|
|
1229
1378
|
}
|
|
1379
|
+
if grace_period is not None:
|
|
1380
|
+
params["grace-period"] = grace_period
|
|
1230
1381
|
error = "Failed deleting runtime resources"
|
|
1231
1382
|
project_path = project if project else "*"
|
|
1232
1383
|
response = self.api_call(
|
|
@@ -1264,7 +1415,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1264
1415
|
name="run_func_on_tuesdays",
|
|
1265
1416
|
kind="job",
|
|
1266
1417
|
scheduled_object=get_data_func,
|
|
1267
|
-
cron_trigger=schemas.ScheduleCronTrigger(
|
|
1418
|
+
cron_trigger=schemas.ScheduleCronTrigger(
|
|
1419
|
+
day_of_week="tue", hour=15, minute=30
|
|
1420
|
+
),
|
|
1268
1421
|
)
|
|
1269
1422
|
db.create_schedule(project_name, schedule)
|
|
1270
1423
|
"""
|
|
@@ -1367,21 +1520,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1367
1520
|
:param builder_env: Kaniko builder pod env vars dict (for config/credentials)
|
|
1368
1521
|
:param force_build: Force building the image, even when no changes were made
|
|
1369
1522
|
"""
|
|
1370
|
-
|
|
1371
|
-
"s3://"
|
|
1372
|
-
)
|
|
1373
|
-
is_ecr_image = mlrun.utils.is_ecr_url(config.httpdb.builder.docker_registry)
|
|
1374
|
-
if not func.spec.build.load_source_on_run and is_s3_source and is_ecr_image:
|
|
1375
|
-
logger.warning(
|
|
1376
|
-
"Building a function image to ECR and loading an S3 source to the image may require conflicting access "
|
|
1377
|
-
"keys. Only the permissions granted to the platform's configured secret will take affect "
|
|
1378
|
-
"(see mlrun.config.config.httpdb.builder.docker_registry_secret). "
|
|
1379
|
-
"In case the permissions are limited to ECR scope, you may use pull_at_runtime=True instead",
|
|
1380
|
-
source=func.spec.build.source,
|
|
1381
|
-
load_source_on_run=func.spec.build.load_source_on_run,
|
|
1382
|
-
default_docker_registry=config.httpdb.builder.docker_registry,
|
|
1383
|
-
)
|
|
1384
|
-
|
|
1523
|
+
self.warn_on_s3_and_ecr_permissions_conflict(func)
|
|
1385
1524
|
try:
|
|
1386
1525
|
req = {
|
|
1387
1526
|
"function": func.to_dict(),
|
|
@@ -1400,10 +1539,94 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1400
1539
|
|
|
1401
1540
|
if not resp.ok:
|
|
1402
1541
|
logger.error(f"bad resp!!\n{resp.text}")
|
|
1403
|
-
raise ValueError("bad
|
|
1542
|
+
raise ValueError("bad submit build response")
|
|
1404
1543
|
|
|
1405
1544
|
return resp.json()
|
|
1406
1545
|
|
|
1546
|
+
def deploy_nuclio_function(
|
|
1547
|
+
self,
|
|
1548
|
+
func: mlrun.runtimes.RemoteRuntime,
|
|
1549
|
+
builder_env: Optional[dict] = None,
|
|
1550
|
+
):
|
|
1551
|
+
"""
|
|
1552
|
+
Deploy a Nuclio function.
|
|
1553
|
+
|
|
1554
|
+
:param func: Function to build.
|
|
1555
|
+
:param builder_env: Kaniko builder pod env vars dict (for config/credentials)
|
|
1556
|
+
"""
|
|
1557
|
+
func.metadata.project = func.metadata.project or config.default_project
|
|
1558
|
+
self.warn_on_s3_and_ecr_permissions_conflict(func)
|
|
1559
|
+
try:
|
|
1560
|
+
req = {
|
|
1561
|
+
"function": func.to_dict(),
|
|
1562
|
+
}
|
|
1563
|
+
if builder_env:
|
|
1564
|
+
req["builder_env"] = builder_env
|
|
1565
|
+
_path = (
|
|
1566
|
+
f"projects/{func.metadata.project}/nuclio/{func.metadata.name}/deploy"
|
|
1567
|
+
)
|
|
1568
|
+
resp = self.api_call("POST", _path, json=req)
|
|
1569
|
+
except OSError as err:
|
|
1570
|
+
logger.error(f"error submitting nuclio deploy task: {err_to_str(err)}")
|
|
1571
|
+
raise OSError(f"error: cannot submit deploy, {err_to_str(err)}")
|
|
1572
|
+
|
|
1573
|
+
if not resp.ok:
|
|
1574
|
+
logger.error(f"deploy nuclio - bad response:\n{resp.text}")
|
|
1575
|
+
raise ValueError("bad nuclio deploy response")
|
|
1576
|
+
|
|
1577
|
+
return resp.json()
|
|
1578
|
+
|
|
1579
|
+
def get_nuclio_deploy_status(
|
|
1580
|
+
self,
|
|
1581
|
+
func: mlrun.runtimes.RemoteRuntime,
|
|
1582
|
+
last_log_timestamp: float = 0.0,
|
|
1583
|
+
verbose: bool = False,
|
|
1584
|
+
):
|
|
1585
|
+
"""Retrieve the status of a deploy operation currently in progress.
|
|
1586
|
+
|
|
1587
|
+
:param func: Function object that is being built.
|
|
1588
|
+
:param last_log_timestamp: Last timestamp of logs that were already retrieved. Function will return only logs
|
|
1589
|
+
later than this parameter.
|
|
1590
|
+
:param verbose: Add verbose logs into the output.
|
|
1591
|
+
|
|
1592
|
+
:returns: The following parameters:
|
|
1593
|
+
|
|
1594
|
+
- Text of builder logs.
|
|
1595
|
+
- Timestamp of last log retrieved, to be used in subsequent calls to this function.
|
|
1596
|
+
"""
|
|
1597
|
+
|
|
1598
|
+
try:
|
|
1599
|
+
normalized_name = normalize_name(func.metadata.name)
|
|
1600
|
+
params = {
|
|
1601
|
+
"name": normalized_name,
|
|
1602
|
+
"project": func.metadata.project,
|
|
1603
|
+
"tag": func.metadata.tag,
|
|
1604
|
+
"last_log_timestamp": str(last_log_timestamp),
|
|
1605
|
+
"verbose": bool2str(verbose),
|
|
1606
|
+
}
|
|
1607
|
+
_path = f"projects/{func.metadata.project}/nuclio/{normalized_name}/deploy"
|
|
1608
|
+
resp = self.api_call("GET", _path, params=params)
|
|
1609
|
+
except OSError as err:
|
|
1610
|
+
logger.error(f"error getting deploy status: {err_to_str(err)}")
|
|
1611
|
+
raise OSError(f"error: cannot get deploy status, {err_to_str(err)}")
|
|
1612
|
+
|
|
1613
|
+
if not resp.ok:
|
|
1614
|
+
logger.warning(f"failed resp, {resp.text}")
|
|
1615
|
+
raise RunDBError("bad function build response")
|
|
1616
|
+
|
|
1617
|
+
if resp.headers:
|
|
1618
|
+
last_log_timestamp = float(
|
|
1619
|
+
resp.headers.get("x-mlrun-last-timestamp", "0.0")
|
|
1620
|
+
)
|
|
1621
|
+
mlrun.runtimes.nuclio.function.enrich_nuclio_function_from_headers(
|
|
1622
|
+
func, resp.headers
|
|
1623
|
+
)
|
|
1624
|
+
|
|
1625
|
+
text = ""
|
|
1626
|
+
if resp.content:
|
|
1627
|
+
text = resp.content.decode()
|
|
1628
|
+
return text, last_log_timestamp
|
|
1629
|
+
|
|
1407
1630
|
def get_builder_status(
|
|
1408
1631
|
self,
|
|
1409
1632
|
func: BaseRuntime,
|
|
@@ -1453,21 +1676,18 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1453
1676
|
last_log_timestamp = float(
|
|
1454
1677
|
resp.headers.get("x-mlrun-last-timestamp", "0.0")
|
|
1455
1678
|
)
|
|
1456
|
-
if func.kind in mlrun.runtimes.RuntimeKinds.
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
func.status.internal_invocation_urls = resp.headers.get(
|
|
1460
|
-
"x-mlrun-internal-invocation-urls", ""
|
|
1461
|
-
).split(",")
|
|
1462
|
-
func.status.external_invocation_urls = resp.headers.get(
|
|
1463
|
-
"x-mlrun-external-invocation-urls", ""
|
|
1464
|
-
).split(",")
|
|
1465
|
-
func.status.container_image = resp.headers.get(
|
|
1466
|
-
"x-mlrun-container-image", ""
|
|
1679
|
+
if func.kind in mlrun.runtimes.RuntimeKinds.pure_nuclio_deployed_runtimes():
|
|
1680
|
+
mlrun.runtimes.nuclio.function.enrich_nuclio_function_from_headers(
|
|
1681
|
+
func, resp.headers
|
|
1467
1682
|
)
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1683
|
+
|
|
1684
|
+
builder_pod = resp.headers.get("builder_pod", "")
|
|
1685
|
+
if builder_pod:
|
|
1686
|
+
func.status.build_pod = builder_pod
|
|
1687
|
+
|
|
1688
|
+
function_image = resp.headers.get("function_image", "")
|
|
1689
|
+
if function_image:
|
|
1690
|
+
func.spec.image = function_image
|
|
1471
1691
|
|
|
1472
1692
|
text = ""
|
|
1473
1693
|
if resp.content:
|
|
@@ -1530,7 +1750,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1530
1750
|
Retrieve updated information on project background tasks being executed.
|
|
1531
1751
|
If no filter is provided, will return background tasks from the last week.
|
|
1532
1752
|
|
|
1533
|
-
:param project: Project name (defaults to mlrun.
|
|
1753
|
+
:param project: Project name (defaults to mlrun.mlconf.default_project).
|
|
1534
1754
|
:param state: List only background tasks whose state is specified.
|
|
1535
1755
|
:param created_from: Filter by background task created time in ``[created_from, created_to]``.
|
|
1536
1756
|
:param created_to: Filter by background task created time in ``[created_from, created_to]``.
|
|
@@ -1663,14 +1883,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1663
1883
|
if isinstance(pipeline, str):
|
|
1664
1884
|
pipe_file = pipeline
|
|
1665
1885
|
else:
|
|
1666
|
-
pipe_file =
|
|
1667
|
-
conf = new_pipe_metadata(
|
|
1886
|
+
pipe_file = compile_pipeline(
|
|
1668
1887
|
artifact_path=artifact_path,
|
|
1669
1888
|
cleanup_ttl=cleanup_ttl,
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
kfp.compiler.Compiler().compile(
|
|
1673
|
-
pipeline, pipe_file, type_check=False, pipeline_conf=conf
|
|
1889
|
+
ops=ops,
|
|
1890
|
+
pipeline=pipeline,
|
|
1674
1891
|
)
|
|
1675
1892
|
|
|
1676
1893
|
if pipe_file.endswith(".yaml"):
|
|
@@ -1725,8 +1942,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1725
1942
|
page_token: str = "",
|
|
1726
1943
|
filter_: str = "",
|
|
1727
1944
|
format_: Union[
|
|
1728
|
-
str, mlrun.common.
|
|
1729
|
-
] = mlrun.common.
|
|
1945
|
+
str, mlrun.common.formatters.PipelineFormat
|
|
1946
|
+
] = mlrun.common.formatters.PipelineFormat.metadata_only,
|
|
1730
1947
|
page_size: int = None,
|
|
1731
1948
|
) -> mlrun.common.schemas.PipelinesOutput:
|
|
1732
1949
|
"""Retrieve a list of KFP pipelines. This function can be invoked to get all pipelines from all projects,
|
|
@@ -1772,8 +1989,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1772
1989
|
namespace: str = None,
|
|
1773
1990
|
timeout: int = 30,
|
|
1774
1991
|
format_: Union[
|
|
1775
|
-
str, mlrun.common.
|
|
1776
|
-
] = mlrun.common.
|
|
1992
|
+
str, mlrun.common.formatters.PipelineFormat
|
|
1993
|
+
] = mlrun.common.formatters.PipelineFormat.summary,
|
|
1777
1994
|
project: str = None,
|
|
1778
1995
|
):
|
|
1779
1996
|
"""Retrieve details of a specific pipeline using its run ID (as provided when the pipeline was executed)."""
|
|
@@ -1865,9 +2082,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1865
2082
|
project: str,
|
|
1866
2083
|
name: str = None,
|
|
1867
2084
|
tag: str = None,
|
|
1868
|
-
entities:
|
|
1869
|
-
labels:
|
|
1870
|
-
) ->
|
|
2085
|
+
entities: list[str] = None,
|
|
2086
|
+
labels: list[str] = None,
|
|
2087
|
+
) -> list[dict]:
|
|
1871
2088
|
"""List feature-sets which contain specific features. This function may return multiple versions of the same
|
|
1872
2089
|
feature-set if a specific tag is not requested. Note that the various filters of this function actually
|
|
1873
2090
|
refer to the feature-set object containing the features, not to the features themselves.
|
|
@@ -1897,13 +2114,48 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1897
2114
|
resp = self.api_call("GET", path, error_message, params=params)
|
|
1898
2115
|
return resp.json()["features"]
|
|
1899
2116
|
|
|
2117
|
+
def list_features_v2(
|
|
2118
|
+
self,
|
|
2119
|
+
project: str,
|
|
2120
|
+
name: str = None,
|
|
2121
|
+
tag: str = None,
|
|
2122
|
+
entities: list[str] = None,
|
|
2123
|
+
labels: list[str] = None,
|
|
2124
|
+
) -> dict[str, list[dict]]:
|
|
2125
|
+
"""List feature-sets which contain specific features. This function may return multiple versions of the same
|
|
2126
|
+
feature-set if a specific tag is not requested. Note that the various filters of this function actually
|
|
2127
|
+
refer to the feature-set object containing the features, not to the features themselves.
|
|
2128
|
+
|
|
2129
|
+
:param project: Project which contains these features.
|
|
2130
|
+
:param name: Name of the feature to look for. The name is used in a like query, and is not case-sensitive. For
|
|
2131
|
+
example, looking for ``feat`` will return features which are named ``MyFeature`` as well as ``defeat``.
|
|
2132
|
+
:param tag: Return feature-sets which contain the features looked for, and are tagged with the specific tag.
|
|
2133
|
+
:param entities: Return only feature-sets which contain an entity whose name is contained in this list.
|
|
2134
|
+
:param labels: Return only feature-sets which are labeled as requested.
|
|
2135
|
+
:returns: A list of features, and a list of their corresponding feature sets.
|
|
2136
|
+
"""
|
|
2137
|
+
|
|
2138
|
+
project = project or config.default_project
|
|
2139
|
+
params = {
|
|
2140
|
+
"name": name,
|
|
2141
|
+
"tag": tag,
|
|
2142
|
+
"entity": entities or [],
|
|
2143
|
+
"label": labels or [],
|
|
2144
|
+
}
|
|
2145
|
+
|
|
2146
|
+
path = f"projects/{project}/features"
|
|
2147
|
+
|
|
2148
|
+
error_message = f"Failed listing features, project: {project}, query: {params}"
|
|
2149
|
+
resp = self.api_call("GET", path, error_message, params=params, version="v2")
|
|
2150
|
+
return resp.json()
|
|
2151
|
+
|
|
1900
2152
|
def list_entities(
|
|
1901
2153
|
self,
|
|
1902
2154
|
project: str,
|
|
1903
2155
|
name: str = None,
|
|
1904
2156
|
tag: str = None,
|
|
1905
|
-
labels:
|
|
1906
|
-
) ->
|
|
2157
|
+
labels: list[str] = None,
|
|
2158
|
+
) -> list[dict]:
|
|
1907
2159
|
"""Retrieve a list of entities and their mapping to the containing feature-sets. This function is similar
|
|
1908
2160
|
to the :py:func:`~list_features` function, and uses the same logic. However, the entities are matched
|
|
1909
2161
|
against the name rather than the features.
|
|
@@ -1922,6 +2174,31 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1922
2174
|
resp = self.api_call("GET", path, error_message, params=params)
|
|
1923
2175
|
return resp.json()["entities"]
|
|
1924
2176
|
|
|
2177
|
+
def list_entities_v2(
|
|
2178
|
+
self,
|
|
2179
|
+
project: str,
|
|
2180
|
+
name: str = None,
|
|
2181
|
+
tag: str = None,
|
|
2182
|
+
labels: list[str] = None,
|
|
2183
|
+
) -> dict[str, list[dict]]:
|
|
2184
|
+
"""Retrieve a list of entities and their mapping to the containing feature-sets. This function is similar
|
|
2185
|
+
to the :py:func:`~list_features_v2` function, and uses the same logic. However, the entities are matched
|
|
2186
|
+
against the name rather than the features.
|
|
2187
|
+
"""
|
|
2188
|
+
|
|
2189
|
+
project = project or config.default_project
|
|
2190
|
+
params = {
|
|
2191
|
+
"name": name,
|
|
2192
|
+
"tag": tag,
|
|
2193
|
+
"label": labels or [],
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
path = f"projects/{project}/entities"
|
|
2197
|
+
|
|
2198
|
+
error_message = f"Failed listing entities, project: {project}, query: {params}"
|
|
2199
|
+
resp = self.api_call("GET", path, error_message, params=params, version="v2")
|
|
2200
|
+
return resp.json()
|
|
2201
|
+
|
|
1925
2202
|
@staticmethod
|
|
1926
2203
|
def _generate_partition_by_params(
|
|
1927
2204
|
partition_by_cls,
|
|
@@ -1947,9 +2224,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1947
2224
|
name: str = None,
|
|
1948
2225
|
tag: str = None,
|
|
1949
2226
|
state: str = None,
|
|
1950
|
-
entities:
|
|
1951
|
-
features:
|
|
1952
|
-
labels:
|
|
2227
|
+
entities: list[str] = None,
|
|
2228
|
+
features: list[str] = None,
|
|
2229
|
+
labels: list[str] = None,
|
|
1953
2230
|
partition_by: Union[
|
|
1954
2231
|
mlrun.common.schemas.FeatureStorePartitionByField, str
|
|
1955
2232
|
] = None,
|
|
@@ -1958,7 +2235,10 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1958
2235
|
partition_order: Union[
|
|
1959
2236
|
mlrun.common.schemas.OrderType, str
|
|
1960
2237
|
] = mlrun.common.schemas.OrderType.desc,
|
|
1961
|
-
|
|
2238
|
+
format_: Union[
|
|
2239
|
+
str, mlrun.common.formatters.FeatureSetFormat
|
|
2240
|
+
] = mlrun.common.formatters.FeatureSetFormat.full,
|
|
2241
|
+
) -> list[FeatureSet]:
|
|
1962
2242
|
"""Retrieve a list of feature-sets matching the criteria provided.
|
|
1963
2243
|
|
|
1964
2244
|
:param project: Project name.
|
|
@@ -1975,6 +2255,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1975
2255
|
:param partition_sort_by: What field to sort the results by, within each partition defined by `partition_by`.
|
|
1976
2256
|
Currently the only allowed value are `created` and `updated`.
|
|
1977
2257
|
:param partition_order: Order of sorting within partitions - `asc` or `desc`. Default is `desc`.
|
|
2258
|
+
:param format_: Format of the results. Possible values are:
|
|
2259
|
+
- ``minimal`` - Return minimal feature set objects, not including stats and preview for each feature set.
|
|
2260
|
+
- ``full`` - Return full feature set objects.
|
|
1978
2261
|
:returns: List of matching :py:class:`~mlrun.feature_store.FeatureSet` objects.
|
|
1979
2262
|
"""
|
|
1980
2263
|
|
|
@@ -1987,6 +2270,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1987
2270
|
"entity": entities or [],
|
|
1988
2271
|
"feature": features or [],
|
|
1989
2272
|
"label": labels or [],
|
|
2273
|
+
"format": format_,
|
|
1990
2274
|
}
|
|
1991
2275
|
if partition_by:
|
|
1992
2276
|
params.update(
|
|
@@ -2073,7 +2357,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2073
2357
|
not a full object.
|
|
2074
2358
|
Example::
|
|
2075
2359
|
|
|
2076
|
-
feature_set_update = {"status": {"processed"
|
|
2360
|
+
feature_set_update = {"status": {"processed": True}}
|
|
2077
2361
|
|
|
2078
2362
|
Will apply the field ``status.processed`` to the existing object.
|
|
2079
2363
|
:param project: Project which contains the modified object.
|
|
@@ -2168,7 +2452,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2168
2452
|
name: str = None,
|
|
2169
2453
|
tag: str = None,
|
|
2170
2454
|
state: str = None,
|
|
2171
|
-
labels:
|
|
2455
|
+
labels: list[str] = None,
|
|
2172
2456
|
partition_by: Union[
|
|
2173
2457
|
mlrun.common.schemas.FeatureStorePartitionByField, str
|
|
2174
2458
|
] = None,
|
|
@@ -2177,7 +2461,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2177
2461
|
partition_order: Union[
|
|
2178
2462
|
mlrun.common.schemas.OrderType, str
|
|
2179
2463
|
] = mlrun.common.schemas.OrderType.desc,
|
|
2180
|
-
) ->
|
|
2464
|
+
) -> list[FeatureVector]:
|
|
2181
2465
|
"""Retrieve a list of feature-vectors matching the criteria provided.
|
|
2182
2466
|
|
|
2183
2467
|
:param project: Project name.
|
|
@@ -2379,7 +2663,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2379
2663
|
|
|
2380
2664
|
def tag_artifacts(
|
|
2381
2665
|
self,
|
|
2382
|
-
artifacts: Union[
|
|
2666
|
+
artifacts: Union[list[Artifact], list[dict], Artifact, dict],
|
|
2383
2667
|
project: str,
|
|
2384
2668
|
tag_name: str,
|
|
2385
2669
|
replace: bool = False,
|
|
@@ -2415,11 +2699,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2415
2699
|
self,
|
|
2416
2700
|
owner: str = None,
|
|
2417
2701
|
format_: Union[
|
|
2418
|
-
str, mlrun.common.
|
|
2419
|
-
] = mlrun.common.
|
|
2420
|
-
labels:
|
|
2702
|
+
str, mlrun.common.formatters.ProjectFormat
|
|
2703
|
+
] = mlrun.common.formatters.ProjectFormat.name_only,
|
|
2704
|
+
labels: list[str] = None,
|
|
2421
2705
|
state: Union[str, mlrun.common.schemas.ProjectState] = None,
|
|
2422
|
-
) ->
|
|
2706
|
+
) -> list[Union[mlrun.projects.MlrunProject, str]]:
|
|
2423
2707
|
"""Return a list of the existing projects, potentially filtered by specific criteria.
|
|
2424
2708
|
|
|
2425
2709
|
:param owner: List only projects belonging to this specific owner.
|
|
@@ -2442,7 +2726,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2442
2726
|
|
|
2443
2727
|
error_message = f"Failed listing projects, query: {params}"
|
|
2444
2728
|
response = self.api_call("GET", "projects", error_message, params=params)
|
|
2445
|
-
if format_ == mlrun.common.
|
|
2729
|
+
if format_ == mlrun.common.formatters.ProjectFormat.name_only:
|
|
2446
2730
|
# projects is just a list of strings
|
|
2447
2731
|
return response.json()["projects"]
|
|
2448
2732
|
|
|
@@ -2470,7 +2754,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2470
2754
|
deletion_strategy: Union[
|
|
2471
2755
|
str, mlrun.common.schemas.DeletionStrategy
|
|
2472
2756
|
] = mlrun.common.schemas.DeletionStrategy.default(),
|
|
2473
|
-
):
|
|
2757
|
+
) -> None:
|
|
2474
2758
|
"""Delete a project.
|
|
2475
2759
|
|
|
2476
2760
|
:param name: Name of the project to delete.
|
|
@@ -2489,7 +2773,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2489
2773
|
"DELETE", f"projects/{name}", error_message, headers=headers, version="v2"
|
|
2490
2774
|
)
|
|
2491
2775
|
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
2492
|
-
logger.info("
|
|
2776
|
+
logger.info("Waiting for project to be deleted", project_name=name)
|
|
2493
2777
|
background_task = mlrun.common.schemas.BackgroundTask(**response.json())
|
|
2494
2778
|
background_task = self._wait_for_background_task_to_reach_terminal_state(
|
|
2495
2779
|
background_task.metadata.name
|
|
@@ -2499,10 +2783,17 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2499
2783
|
== mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
2500
2784
|
):
|
|
2501
2785
|
logger.info("Project deleted", project_name=name)
|
|
2502
|
-
|
|
2786
|
+
elif (
|
|
2787
|
+
background_task.status.state
|
|
2788
|
+
== mlrun.common.schemas.BackgroundTaskState.failed
|
|
2789
|
+
):
|
|
2790
|
+
logger.error(
|
|
2791
|
+
"Project deletion failed",
|
|
2792
|
+
project_name=name,
|
|
2793
|
+
error=background_task.status.error,
|
|
2794
|
+
)
|
|
2503
2795
|
elif response.status_code == http.HTTPStatus.NO_CONTENT:
|
|
2504
2796
|
logger.info("Project deleted", project_name=name)
|
|
2505
|
-
return
|
|
2506
2797
|
|
|
2507
2798
|
def store_project(
|
|
2508
2799
|
self,
|
|
@@ -2647,11 +2938,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2647
2938
|
:param secrets: A set of secret values to store.
|
|
2648
2939
|
Example::
|
|
2649
2940
|
|
|
2650
|
-
secrets = {
|
|
2941
|
+
secrets = {"password": "myPassw0rd", "aws_key": "111222333"}
|
|
2651
2942
|
db.create_project_secrets(
|
|
2652
2943
|
"project1",
|
|
2653
2944
|
provider=mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2654
|
-
secrets=secrets
|
|
2945
|
+
secrets=secrets,
|
|
2655
2946
|
)
|
|
2656
2947
|
"""
|
|
2657
2948
|
path = f"projects/{project}/secrets"
|
|
@@ -2674,7 +2965,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2674
2965
|
provider: Union[
|
|
2675
2966
|
str, mlrun.common.schemas.SecretProviderName
|
|
2676
2967
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2677
|
-
secrets:
|
|
2968
|
+
secrets: list[str] = None,
|
|
2678
2969
|
) -> mlrun.common.schemas.SecretsData:
|
|
2679
2970
|
"""Retrieve project-context secrets from Vault.
|
|
2680
2971
|
|
|
@@ -2763,7 +3054,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2763
3054
|
provider: Union[
|
|
2764
3055
|
str, mlrun.common.schemas.SecretProviderName
|
|
2765
3056
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2766
|
-
secrets:
|
|
3057
|
+
secrets: list[str] = None,
|
|
2767
3058
|
):
|
|
2768
3059
|
"""Delete project-context secrets from Kubernetes.
|
|
2769
3060
|
|
|
@@ -2920,13 +3211,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2920
3211
|
project: str,
|
|
2921
3212
|
model: Optional[str] = None,
|
|
2922
3213
|
function: Optional[str] = None,
|
|
2923
|
-
labels:
|
|
3214
|
+
labels: list[str] = None,
|
|
2924
3215
|
start: str = "now-1h",
|
|
2925
3216
|
end: str = "now",
|
|
2926
|
-
metrics: Optional[
|
|
3217
|
+
metrics: Optional[list[str]] = None,
|
|
2927
3218
|
top_level: bool = False,
|
|
2928
|
-
uids: Optional[
|
|
2929
|
-
) ->
|
|
3219
|
+
uids: Optional[list[str]] = None,
|
|
3220
|
+
) -> list[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
|
|
2930
3221
|
"""
|
|
2931
3222
|
Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
|
|
2932
3223
|
model endpoint. This functions supports filtering by the following parameters:
|
|
@@ -2947,14 +3238,12 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2947
3238
|
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a
|
|
2948
3239
|
label (i.e. list("key=value")) or by looking for the existence of a given key (i.e. "key")
|
|
2949
3240
|
:param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
|
|
2950
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
|
|
2957
|
-
days), or 0 for the earliest time.
|
|
3241
|
+
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time, a
|
|
3242
|
+
Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
|
|
3243
|
+
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3244
|
+
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time, a
|
|
3245
|
+
Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
|
|
3246
|
+
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
2958
3247
|
:param top_level: if true will return only routers and endpoint that are NOT children of any router
|
|
2959
3248
|
:param uids: if passed will return a list `ModelEndpoint` object with uid in uids
|
|
2960
3249
|
"""
|
|
@@ -2994,7 +3283,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2994
3283
|
endpoint_id: str,
|
|
2995
3284
|
start: Optional[str] = None,
|
|
2996
3285
|
end: Optional[str] = None,
|
|
2997
|
-
metrics: Optional[
|
|
3286
|
+
metrics: Optional[list[str]] = None,
|
|
2998
3287
|
feature_analysis: bool = False,
|
|
2999
3288
|
) -> mlrun.model_monitoring.model_endpoint.ModelEndpoint:
|
|
3000
3289
|
"""
|
|
@@ -3003,13 +3292,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3003
3292
|
:param project: The name of the project
|
|
3004
3293
|
:param endpoint_id: The unique id of the model endpoint.
|
|
3005
3294
|
:param start: The start time of the metrics. Can be represented by a string containing an
|
|
3006
|
-
RFC 3339 time, a
|
|
3007
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
3008
|
-
0 for the earliest time.
|
|
3295
|
+
RFC 3339 time, a Unix timestamp in milliseconds, a relative time
|
|
3296
|
+
(`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
3297
|
+
`'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3009
3298
|
:param end: The end time of the metrics. Can be represented by a string containing an
|
|
3010
|
-
RFC 3339 time, a
|
|
3011
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
3012
|
-
0 for the earliest time.
|
|
3299
|
+
RFC 3339 time, a Unix timestamp in milliseconds, a relative time
|
|
3300
|
+
(`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
3301
|
+
`'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3013
3302
|
:param metrics: A list of metrics to return for the model endpoint. There are pre-defined
|
|
3014
3303
|
metrics for model endpoints such as predictions_per_second and
|
|
3015
3304
|
latency_avg_5m but also custom metrics defined by the user. Please note that
|
|
@@ -3018,7 +3307,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3018
3307
|
:param feature_analysis: When True, the base feature statistics and current feature statistics will
|
|
3019
3308
|
be added to the output of the resulting object.
|
|
3020
3309
|
|
|
3021
|
-
:
|
|
3310
|
+
:returns: A `ModelEndpoint` object.
|
|
3022
3311
|
"""
|
|
3023
3312
|
|
|
3024
3313
|
path = f"projects/{project}/model-endpoints/{endpoint_id}"
|
|
@@ -3079,65 +3368,210 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3079
3368
|
params=attributes,
|
|
3080
3369
|
)
|
|
3081
3370
|
|
|
3082
|
-
def
|
|
3371
|
+
def update_model_monitoring_controller(
|
|
3083
3372
|
self,
|
|
3084
|
-
project: str
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
):
|
|
3373
|
+
project: str,
|
|
3374
|
+
base_period: int = 10,
|
|
3375
|
+
image: str = "mlrun/mlrun",
|
|
3376
|
+
) -> None:
|
|
3088
3377
|
"""
|
|
3089
|
-
|
|
3090
|
-
To submit a scheduled job as well, please set with_schedule = True.
|
|
3378
|
+
Redeploy model monitoring application controller function.
|
|
3091
3379
|
|
|
3092
|
-
:param project:
|
|
3093
|
-
:param
|
|
3094
|
-
|
|
3095
|
-
:param
|
|
3380
|
+
:param project: Project name.
|
|
3381
|
+
:param base_period: The time period in minutes in which the model monitoring controller function
|
|
3382
|
+
triggers. By default, the base period is 10 minutes.
|
|
3383
|
+
:param image: The image of the model monitoring controller function.
|
|
3384
|
+
By default, the image is mlrun/mlrun.
|
|
3385
|
+
"""
|
|
3386
|
+
self.api_call(
|
|
3387
|
+
method=mlrun.common.types.HTTPMethod.PATCH,
|
|
3388
|
+
path=f"projects/{project}/model-monitoring/model-monitoring-controller",
|
|
3389
|
+
params={
|
|
3390
|
+
"base_period": base_period,
|
|
3391
|
+
"image": image,
|
|
3392
|
+
},
|
|
3393
|
+
)
|
|
3096
3394
|
|
|
3395
|
+
def enable_model_monitoring(
|
|
3396
|
+
self,
|
|
3397
|
+
project: str,
|
|
3398
|
+
base_period: int = 10,
|
|
3399
|
+
image: str = "mlrun/mlrun",
|
|
3400
|
+
deploy_histogram_data_drift_app: bool = True,
|
|
3401
|
+
rebuild_images: bool = False,
|
|
3402
|
+
fetch_credentials_from_sys_config: bool = False,
|
|
3403
|
+
) -> None:
|
|
3404
|
+
"""
|
|
3405
|
+
Deploy model monitoring application controller, writer and stream functions.
|
|
3406
|
+
While the main goal of the controller function is to handle the monitoring processing and triggering
|
|
3407
|
+
applications, the goal of the model monitoring writer function is to write all the monitoring
|
|
3408
|
+
application results to the databases.
|
|
3409
|
+
The stream function goal is to monitor the log of the data stream. It is triggered when a new log entry
|
|
3410
|
+
is detected. It processes the new events into statistics that are then written to statistics databases.
|
|
3411
|
+
|
|
3412
|
+
:param project: Project name.
|
|
3413
|
+
:param base_period: The time period in minutes in which the model monitoring controller
|
|
3414
|
+
function triggers. By default, the base period is 10 minutes.
|
|
3415
|
+
:param image: The image of the model monitoring controller, writer & monitoring
|
|
3416
|
+
stream functions, which are real time nuclio functions.
|
|
3417
|
+
By default, the image is mlrun/mlrun.
|
|
3418
|
+
:param deploy_histogram_data_drift_app: If true, deploy the default histogram-based data drift application.
|
|
3419
|
+
:param rebuild_images: If true, force rebuild of model monitoring infrastructure images.
|
|
3420
|
+
:param fetch_credentials_from_sys_config: If true, fetch the credentials from the system configuration.
|
|
3097
3421
|
|
|
3098
|
-
:returns: model monitoring batch job as a dictionary. You can easily convert the returned function into a
|
|
3099
|
-
runtime object by calling ~mlrun.new_function.
|
|
3100
3422
|
"""
|
|
3423
|
+
self.api_call(
|
|
3424
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3425
|
+
path=f"projects/{project}/model-monitoring/enable-model-monitoring",
|
|
3426
|
+
params={
|
|
3427
|
+
"base_period": base_period,
|
|
3428
|
+
"image": image,
|
|
3429
|
+
"deploy_histogram_data_drift_app": deploy_histogram_data_drift_app,
|
|
3430
|
+
"rebuild_images": rebuild_images,
|
|
3431
|
+
"fetch_credentials_from_sys_config": fetch_credentials_from_sys_config,
|
|
3432
|
+
},
|
|
3433
|
+
)
|
|
3101
3434
|
|
|
3102
|
-
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3435
|
+
def disable_model_monitoring(
|
|
3436
|
+
self,
|
|
3437
|
+
project: str,
|
|
3438
|
+
delete_resources: bool = True,
|
|
3439
|
+
delete_stream_function: bool = False,
|
|
3440
|
+
delete_histogram_data_drift_app: bool = True,
|
|
3441
|
+
delete_user_applications: bool = False,
|
|
3442
|
+
user_application_list: list[str] = None,
|
|
3443
|
+
) -> bool:
|
|
3444
|
+
"""
|
|
3445
|
+
Disable model monitoring application controller, writer, stream, histogram data drift application
|
|
3446
|
+
and the user's applications functions, according to the given params.
|
|
3447
|
+
|
|
3448
|
+
:param project: Project name.
|
|
3449
|
+
:param delete_resources: If True, it would delete the model monitoring controller & writer
|
|
3450
|
+
functions. Default True
|
|
3451
|
+
:param delete_stream_function: If True, it would delete model monitoring stream function,
|
|
3452
|
+
need to use wisely because if you're deleting this function
|
|
3453
|
+
this can cause data loss in case you will want to
|
|
3454
|
+
enable the model monitoring capability to the project.
|
|
3455
|
+
Default False.
|
|
3456
|
+
:param delete_histogram_data_drift_app: If True, it would delete the default histogram-based data drift
|
|
3457
|
+
application. Default False.
|
|
3458
|
+
:param delete_user_applications: If True, it would delete the user's model monitoring
|
|
3459
|
+
application according to user_application_list, Default False.
|
|
3460
|
+
:param user_application_list: List of the user's model monitoring application to disable.
|
|
3461
|
+
Default all the applications.
|
|
3462
|
+
Note: you have to set delete_user_applications to True
|
|
3463
|
+
in order to delete the desired application.
|
|
3464
|
+
|
|
3465
|
+
:returns: True if the deletion was successful, False otherwise.
|
|
3466
|
+
"""
|
|
3467
|
+
response = self.api_call(
|
|
3468
|
+
method=mlrun.common.types.HTTPMethod.DELETE,
|
|
3469
|
+
path=f"projects/{project}/model-monitoring/disable-model-monitoring",
|
|
3470
|
+
params={
|
|
3471
|
+
"delete_resources": delete_resources,
|
|
3472
|
+
"delete_stream_function": delete_stream_function,
|
|
3473
|
+
"delete_histogram_data_drift_app": delete_histogram_data_drift_app,
|
|
3474
|
+
"delete_user_applications": delete_user_applications,
|
|
3475
|
+
"user_application_list": user_application_list,
|
|
3476
|
+
},
|
|
3477
|
+
)
|
|
3478
|
+
deletion_failed = False
|
|
3479
|
+
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
3480
|
+
if delete_resources:
|
|
3481
|
+
logger.info(
|
|
3482
|
+
"Model Monitoring is being disabled",
|
|
3483
|
+
project_name=project,
|
|
3484
|
+
)
|
|
3485
|
+
if delete_user_applications:
|
|
3486
|
+
logger.info("User applications are being deleted", project_name=project)
|
|
3487
|
+
background_tasks = mlrun.common.schemas.BackgroundTaskList(
|
|
3488
|
+
**response.json()
|
|
3489
|
+
).background_tasks
|
|
3490
|
+
for task in background_tasks:
|
|
3491
|
+
task = self._wait_for_background_task_to_reach_terminal_state(
|
|
3492
|
+
task.metadata.name, project=project
|
|
3493
|
+
)
|
|
3494
|
+
if (
|
|
3495
|
+
task.status.state
|
|
3496
|
+
== mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
3497
|
+
):
|
|
3498
|
+
continue
|
|
3499
|
+
elif (
|
|
3500
|
+
task.status.state == mlrun.common.schemas.BackgroundTaskState.failed
|
|
3501
|
+
):
|
|
3502
|
+
deletion_failed = True
|
|
3503
|
+
return not deletion_failed
|
|
3504
|
+
|
|
3505
|
+
def delete_model_monitoring_function(
|
|
3506
|
+
self, project: str, functions: list[str]
|
|
3507
|
+
) -> bool:
|
|
3508
|
+
"""
|
|
3509
|
+
Delete a model monitoring application.
|
|
3107
3510
|
|
|
3108
|
-
|
|
3109
|
-
|
|
3511
|
+
:param functions: List of the model monitoring function to delete.
|
|
3512
|
+
:param project: Project name.
|
|
3110
3513
|
|
|
3111
|
-
|
|
3112
|
-
self,
|
|
3113
|
-
project: str = "",
|
|
3114
|
-
default_controller_image: str = "mlrun/mlrun",
|
|
3115
|
-
base_period: int = 10,
|
|
3116
|
-
):
|
|
3514
|
+
:returns: True if the deletion was successful, False otherwise.
|
|
3117
3515
|
"""
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3516
|
+
response = self.api_call(
|
|
3517
|
+
method=mlrun.common.types.HTTPMethod.DELETE,
|
|
3518
|
+
path=f"projects/{project}/model-monitoring/functions",
|
|
3519
|
+
params={"functions": functions},
|
|
3520
|
+
)
|
|
3521
|
+
deletion_failed = False
|
|
3522
|
+
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
3523
|
+
logger.info("User applications are being deleted", project_name=project)
|
|
3524
|
+
background_tasks = mlrun.common.schemas.BackgroundTaskList(
|
|
3525
|
+
**response.json()
|
|
3526
|
+
).background_tasks
|
|
3527
|
+
for task in background_tasks:
|
|
3528
|
+
task = self._wait_for_background_task_to_reach_terminal_state(
|
|
3529
|
+
task.metadata.name, project=project
|
|
3530
|
+
)
|
|
3531
|
+
if (
|
|
3532
|
+
task.status.state
|
|
3533
|
+
== mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
3534
|
+
):
|
|
3535
|
+
continue
|
|
3536
|
+
elif (
|
|
3537
|
+
task.status.state == mlrun.common.schemas.BackgroundTaskState.failed
|
|
3538
|
+
):
|
|
3539
|
+
deletion_failed = True
|
|
3540
|
+
return not deletion_failed
|
|
3541
|
+
|
|
3542
|
+
def deploy_histogram_data_drift_app(
|
|
3543
|
+
self, project: str, image: str = "mlrun/mlrun"
|
|
3544
|
+
) -> None:
|
|
3545
|
+
"""
|
|
3546
|
+
Deploy the histogram data drift application.
|
|
3122
3547
|
|
|
3123
|
-
:param project:
|
|
3124
|
-
:param
|
|
3125
|
-
function, which is a real time nuclio functino, will be deployed with the same
|
|
3126
|
-
image. By default, the image is mlrun/mlrun.
|
|
3127
|
-
:param base_period: Minutes to determine the frequency in which the model monitoring controller job
|
|
3128
|
-
is running. By default, the base period is 5 minutes.
|
|
3129
|
-
:returns: model monitoring controller job as a dictionary. You can easily convert the returned function into a
|
|
3130
|
-
runtime object by calling ~mlrun.new_function.
|
|
3548
|
+
:param project: Project name.
|
|
3549
|
+
:param image: The image on which the application will run.
|
|
3131
3550
|
"""
|
|
3551
|
+
self.api_call(
|
|
3552
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3553
|
+
path=f"projects/{project}/model-monitoring/deploy-histogram-data-drift-app",
|
|
3554
|
+
params={"image": image},
|
|
3555
|
+
)
|
|
3132
3556
|
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3557
|
+
def set_model_monitoring_credentials(
|
|
3558
|
+
self,
|
|
3559
|
+
project: str,
|
|
3560
|
+
credentials: dict[str, str],
|
|
3561
|
+
replace_creds: bool,
|
|
3562
|
+
) -> None:
|
|
3563
|
+
"""
|
|
3564
|
+
Set the credentials for the model monitoring application.
|
|
3138
3565
|
|
|
3139
|
-
|
|
3140
|
-
|
|
3566
|
+
:param project: Project name.
|
|
3567
|
+
:param credentials: Credentials to set.
|
|
3568
|
+
:param replace_creds: If True, will override the existing credentials.
|
|
3569
|
+
"""
|
|
3570
|
+
self.api_call(
|
|
3571
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3572
|
+
path=f"projects/{project}/model-monitoring/set-model-monitoring-credentials",
|
|
3573
|
+
params={**credentials, "replace_creds": replace_creds},
|
|
3574
|
+
)
|
|
3141
3575
|
|
|
3142
3576
|
def create_hub_source(
|
|
3143
3577
|
self, source: Union[dict, mlrun.common.schemas.IndexedHubSource]
|
|
@@ -3168,8 +3602,10 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3168
3602
|
metadata=mlrun.common.schemas.HubObjectMetadata(
|
|
3169
3603
|
name="priv", description="a private source"
|
|
3170
3604
|
),
|
|
3171
|
-
spec=mlrun.common.schemas.HubSourceSpec(
|
|
3172
|
-
|
|
3605
|
+
spec=mlrun.common.schemas.HubSourceSpec(
|
|
3606
|
+
path="/local/path/to/source", channel="development"
|
|
3607
|
+
),
|
|
3608
|
+
),
|
|
3173
3609
|
)
|
|
3174
3610
|
db.create_hub_source(private_source)
|
|
3175
3611
|
|
|
@@ -3183,9 +3619,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3183
3619
|
spec=mlrun.common.schemas.HubSourceSpec(
|
|
3184
3620
|
path="/local/path/to/source/2",
|
|
3185
3621
|
channel="development",
|
|
3186
|
-
credentials={...}
|
|
3187
|
-
)
|
|
3188
|
-
)
|
|
3622
|
+
credentials={...},
|
|
3623
|
+
),
|
|
3624
|
+
),
|
|
3189
3625
|
)
|
|
3190
3626
|
db.create_hub_source(another_source)
|
|
3191
3627
|
|
|
@@ -3227,7 +3663,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3227
3663
|
item_name: Optional[str] = None,
|
|
3228
3664
|
tag: Optional[str] = None,
|
|
3229
3665
|
version: Optional[str] = None,
|
|
3230
|
-
) ->
|
|
3666
|
+
) -> list[mlrun.common.schemas.hub.IndexedHubSource]:
|
|
3231
3667
|
"""
|
|
3232
3668
|
List hub sources in the MLRun DB.
|
|
3233
3669
|
|
|
@@ -3349,7 +3785,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3349
3785
|
:param version: Get a specific version of the item. Default is ``None``.
|
|
3350
3786
|
:param tag: Get a specific version of the item identified by tag. Default is ``latest``.
|
|
3351
3787
|
|
|
3352
|
-
:
|
|
3788
|
+
:returns: http response with the asset in the content attribute
|
|
3353
3789
|
"""
|
|
3354
3790
|
path = f"hub/sources/{source_name}/items/{item_name}/assets/{asset_name}"
|
|
3355
3791
|
params = {
|
|
@@ -3377,24 +3813,81 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3377
3813
|
body=dict_to_json(authorization_verification_input.dict()),
|
|
3378
3814
|
)
|
|
3379
3815
|
|
|
3380
|
-
def list_api_gateways(self, project=None):
|
|
3816
|
+
def list_api_gateways(self, project=None) -> mlrun.common.schemas.APIGatewaysOutput:
|
|
3381
3817
|
"""
|
|
3382
3818
|
Returns a list of Nuclio api gateways
|
|
3383
|
-
:param project: optional str parameter to filter by project, if not passed, default Nuclio's value is taken
|
|
3384
3819
|
|
|
3385
|
-
:
|
|
3386
|
-
|
|
3387
|
-
|
|
3820
|
+
:param project: optional str parameter to filter by project, if not passed, default project value is taken
|
|
3821
|
+
|
|
3822
|
+
:returns: :py:class:`~mlrun.common.schemas.APIGateways`.
|
|
3388
3823
|
"""
|
|
3389
3824
|
project = project or config.default_project
|
|
3390
3825
|
error = "list api gateways"
|
|
3391
|
-
endpoint_path = f"projects/{project}/
|
|
3392
|
-
|
|
3393
|
-
return
|
|
3826
|
+
endpoint_path = f"projects/{project}/api-gateways"
|
|
3827
|
+
response = self.api_call("GET", endpoint_path, error)
|
|
3828
|
+
return mlrun.common.schemas.APIGatewaysOutput(**response.json())
|
|
3829
|
+
|
|
3830
|
+
def get_api_gateway(self, name, project=None) -> mlrun.common.schemas.APIGateway:
|
|
3831
|
+
"""
|
|
3832
|
+
Returns an API gateway
|
|
3833
|
+
|
|
3834
|
+
:param name: API gateway name
|
|
3835
|
+
:param project: optional str parameter to filter by project, if not passed, default project value is taken
|
|
3836
|
+
|
|
3837
|
+
:returns: :py:class:`~mlrun.common.schemas.APIGateway`.
|
|
3838
|
+
"""
|
|
3839
|
+
project = project or config.default_project
|
|
3840
|
+
error = "get api gateway"
|
|
3841
|
+
endpoint_path = f"projects/{project}/api-gateways/{name}"
|
|
3842
|
+
response = self.api_call("GET", endpoint_path, error)
|
|
3843
|
+
return mlrun.common.schemas.APIGateway(**response.json())
|
|
3844
|
+
|
|
3845
|
+
def delete_api_gateway(self, name, project=None):
|
|
3846
|
+
"""
|
|
3847
|
+
Deletes an API gateway
|
|
3848
|
+
|
|
3849
|
+
:param name: API gateway name
|
|
3850
|
+
:param project: Project name
|
|
3851
|
+
"""
|
|
3852
|
+
project = project or config.default_project
|
|
3853
|
+
error = "delete api gateway"
|
|
3854
|
+
endpoint_path = f"projects/{project}/api-gateways/{name}"
|
|
3855
|
+
self.api_call("DELETE", endpoint_path, error)
|
|
3856
|
+
|
|
3857
|
+
def store_api_gateway(
|
|
3858
|
+
self,
|
|
3859
|
+
api_gateway: Union[
|
|
3860
|
+
mlrun.common.schemas.APIGateway,
|
|
3861
|
+
mlrun.runtimes.nuclio.api_gateway.APIGateway,
|
|
3862
|
+
],
|
|
3863
|
+
project: Optional[str] = None,
|
|
3864
|
+
) -> mlrun.common.schemas.APIGateway:
|
|
3865
|
+
"""
|
|
3866
|
+
Stores an API Gateway.
|
|
3867
|
+
|
|
3868
|
+
:param api_gateway: :py:class:`~mlrun.runtimes.nuclio.APIGateway`
|
|
3869
|
+
or :py:class:`~mlrun.common.schemas.APIGateway`: API Gateway entity.
|
|
3870
|
+
:param project: project name. Mandatory if api_gateway is mlrun.common.schemas.APIGateway.
|
|
3871
|
+
|
|
3872
|
+
:returns: :py:class:`~mlrun.common.schemas.APIGateway`.
|
|
3873
|
+
"""
|
|
3874
|
+
|
|
3875
|
+
if isinstance(api_gateway, mlrun.runtimes.nuclio.api_gateway.APIGateway):
|
|
3876
|
+
api_gateway = api_gateway.to_scheme()
|
|
3877
|
+
endpoint_path = f"projects/{project}/api-gateways/{api_gateway.metadata.name}"
|
|
3878
|
+
error = "store api gateways"
|
|
3879
|
+
response = self.api_call(
|
|
3880
|
+
"PUT",
|
|
3881
|
+
endpoint_path,
|
|
3882
|
+
error,
|
|
3883
|
+
json=api_gateway.dict(exclude_none=True),
|
|
3884
|
+
)
|
|
3885
|
+
return mlrun.common.schemas.APIGateway(**response.json())
|
|
3394
3886
|
|
|
3395
3887
|
def trigger_migrations(self) -> Optional[mlrun.common.schemas.BackgroundTask]:
|
|
3396
3888
|
"""Trigger migrations (will do nothing if no migrations are needed) and wait for them to finish if actually
|
|
3397
3889
|
triggered
|
|
3890
|
+
|
|
3398
3891
|
:returns: :py:class:`~mlrun.common.schemas.BackgroundTask`.
|
|
3399
3892
|
"""
|
|
3400
3893
|
response = self.api_call(
|
|
@@ -3413,10 +3906,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3413
3906
|
self,
|
|
3414
3907
|
project: str,
|
|
3415
3908
|
run_uid: str,
|
|
3416
|
-
notifications:
|
|
3909
|
+
notifications: list[mlrun.model.Notification] = None,
|
|
3417
3910
|
):
|
|
3418
3911
|
"""
|
|
3419
3912
|
Set notifications on a run. This will override any existing notifications on the run.
|
|
3913
|
+
|
|
3420
3914
|
:param project: Project containing the run.
|
|
3421
3915
|
:param run_uid: UID of the run.
|
|
3422
3916
|
:param notifications: List of notifications to set on the run. Default is an empty list.
|
|
@@ -3438,10 +3932,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3438
3932
|
self,
|
|
3439
3933
|
project: str,
|
|
3440
3934
|
schedule_name: str,
|
|
3441
|
-
notifications:
|
|
3935
|
+
notifications: list[mlrun.model.Notification] = None,
|
|
3442
3936
|
):
|
|
3443
3937
|
"""
|
|
3444
3938
|
Set notifications on a schedule. This will override any existing notifications on the schedule.
|
|
3939
|
+
|
|
3445
3940
|
:param project: Project containing the schedule.
|
|
3446
3941
|
:param schedule_name: Name of the schedule.
|
|
3447
3942
|
:param notifications: List of notifications to set on the schedule. Default is an empty list.
|
|
@@ -3461,7 +3956,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3461
3956
|
|
|
3462
3957
|
def store_run_notifications(
|
|
3463
3958
|
self,
|
|
3464
|
-
notification_objects:
|
|
3959
|
+
notification_objects: list[mlrun.model.Notification],
|
|
3465
3960
|
run_uid: str,
|
|
3466
3961
|
project: str = None,
|
|
3467
3962
|
mask_params: bool = True,
|
|
@@ -3473,6 +3968,16 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3473
3968
|
"""
|
|
3474
3969
|
pass
|
|
3475
3970
|
|
|
3971
|
+
def store_alert_notifications(
|
|
3972
|
+
self,
|
|
3973
|
+
session,
|
|
3974
|
+
notification_objects: list[mlrun.model.Notification],
|
|
3975
|
+
alert_id: str,
|
|
3976
|
+
project: str,
|
|
3977
|
+
mask_params: bool = True,
|
|
3978
|
+
):
|
|
3979
|
+
pass
|
|
3980
|
+
|
|
3476
3981
|
def submit_workflow(
|
|
3477
3982
|
self,
|
|
3478
3983
|
project: str,
|
|
@@ -3482,7 +3987,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3482
3987
|
mlrun.common.schemas.WorkflowSpec,
|
|
3483
3988
|
dict,
|
|
3484
3989
|
],
|
|
3485
|
-
arguments: Optional[
|
|
3990
|
+
arguments: Optional[dict] = None,
|
|
3486
3991
|
artifact_path: Optional[str] = None,
|
|
3487
3992
|
source: Optional[str] = None,
|
|
3488
3993
|
run_name: Optional[str] = None,
|
|
@@ -3575,20 +4080,21 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3575
4080
|
self,
|
|
3576
4081
|
name: str,
|
|
3577
4082
|
url: str,
|
|
3578
|
-
secrets: Optional[
|
|
4083
|
+
secrets: Optional[dict] = None,
|
|
3579
4084
|
save_secrets: bool = True,
|
|
3580
4085
|
) -> str:
|
|
3581
4086
|
"""
|
|
3582
4087
|
Loading a project remotely from the given source.
|
|
4088
|
+
|
|
3583
4089
|
:param name: project name
|
|
3584
4090
|
:param url: git or tar.gz or .zip sources archive path e.g.:
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
|
|
4091
|
+
git://github.com/mlrun/demo-xgb-project.git
|
|
4092
|
+
http://mysite/archived-project.zip
|
|
4093
|
+
The git project should include the project yaml file.
|
|
3588
4094
|
:param secrets: Secrets to store in project in order to load it from the provided url. For more
|
|
3589
|
-
|
|
4095
|
+
information see :py:func:`mlrun.load_project` function.
|
|
3590
4096
|
:param save_secrets: Whether to store secrets in the loaded project. Setting to False will cause waiting
|
|
3591
|
-
|
|
4097
|
+
for the process completion.
|
|
3592
4098
|
|
|
3593
4099
|
:returns: The terminal state of load project process.
|
|
3594
4100
|
"""
|
|
@@ -3638,7 +4144,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3638
4144
|
|
|
3639
4145
|
def list_datastore_profiles(
|
|
3640
4146
|
self, project: str
|
|
3641
|
-
) ->
|
|
4147
|
+
) -> list[mlrun.common.schemas.DatastoreProfile]:
|
|
3642
4148
|
project = project or config.default_project
|
|
3643
4149
|
_path = self._path_of("datastore-profiles", project)
|
|
3644
4150
|
|
|
@@ -3664,6 +4170,168 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3664
4170
|
|
|
3665
4171
|
self.api_call(method="PUT", path=_path, json=profile.dict())
|
|
3666
4172
|
|
|
4173
|
+
@staticmethod
|
|
4174
|
+
def warn_on_s3_and_ecr_permissions_conflict(func):
|
|
4175
|
+
is_s3_source = func.spec.build.source and func.spec.build.source.startswith(
|
|
4176
|
+
"s3://"
|
|
4177
|
+
)
|
|
4178
|
+
is_ecr_image = mlrun.utils.is_ecr_url(config.httpdb.builder.docker_registry)
|
|
4179
|
+
if not func.spec.build.load_source_on_run and is_s3_source and is_ecr_image:
|
|
4180
|
+
logger.warning(
|
|
4181
|
+
"Building a function image to ECR and loading an S3 source to the image may require conflicting access "
|
|
4182
|
+
"keys. Only the permissions granted to the platform's configured secret will take affect "
|
|
4183
|
+
"(see mlrun.mlconf.httpdb.builder.docker_registry_secret). "
|
|
4184
|
+
"In case the permissions are limited to ECR scope, you may use pull_at_runtime=True instead",
|
|
4185
|
+
source=func.spec.build.source,
|
|
4186
|
+
load_source_on_run=func.spec.build.load_source_on_run,
|
|
4187
|
+
default_docker_registry=config.httpdb.builder.docker_registry,
|
|
4188
|
+
)
|
|
4189
|
+
|
|
4190
|
+
def generate_event(
|
|
4191
|
+
self, name: str, event_data: Union[dict, mlrun.common.schemas.Event], project=""
|
|
4192
|
+
):
|
|
4193
|
+
"""
|
|
4194
|
+
Generate an event.
|
|
4195
|
+
|
|
4196
|
+
:param name: The name of the event.
|
|
4197
|
+
:param event_data: The data of the event.
|
|
4198
|
+
:param project: The project that the event belongs to.
|
|
4199
|
+
"""
|
|
4200
|
+
if mlrun.mlconf.alerts.mode == mlrun.common.schemas.alert.AlertsModes.disabled:
|
|
4201
|
+
logger.warning("Alerts are disabled, event will not be generated")
|
|
4202
|
+
|
|
4203
|
+
project = project or config.default_project
|
|
4204
|
+
endpoint_path = f"projects/{project}/events/{name}"
|
|
4205
|
+
error_message = f"post event {project}/events/{name}"
|
|
4206
|
+
if isinstance(event_data, mlrun.common.schemas.Event):
|
|
4207
|
+
event_data = event_data.dict()
|
|
4208
|
+
self.api_call(
|
|
4209
|
+
"POST", endpoint_path, error_message, body=dict_to_json(event_data)
|
|
4210
|
+
)
|
|
4211
|
+
|
|
4212
|
+
def store_alert_config(
|
|
4213
|
+
self,
|
|
4214
|
+
alert_name: str,
|
|
4215
|
+
alert_data: Union[dict, AlertConfig],
|
|
4216
|
+
project="",
|
|
4217
|
+
) -> AlertConfig:
|
|
4218
|
+
"""
|
|
4219
|
+
Create/modify an alert.
|
|
4220
|
+
|
|
4221
|
+
:param alert_name: The name of the alert.
|
|
4222
|
+
:param alert_data: The data of the alert.
|
|
4223
|
+
:param project: The project that the alert belongs to.
|
|
4224
|
+
:returns: The created/modified alert.
|
|
4225
|
+
"""
|
|
4226
|
+
if not alert_data:
|
|
4227
|
+
raise mlrun.errors.MLRunInvalidArgumentError("Alert data must be provided")
|
|
4228
|
+
|
|
4229
|
+
if mlrun.mlconf.alerts.mode == mlrun.common.schemas.alert.AlertsModes.disabled:
|
|
4230
|
+
logger.warning(
|
|
4231
|
+
"Alerts are disabled, alert will still be stored but will not be triggered"
|
|
4232
|
+
)
|
|
4233
|
+
|
|
4234
|
+
project = project or config.default_project
|
|
4235
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}"
|
|
4236
|
+
error_message = f"put alert {project}/alerts/{alert_name}"
|
|
4237
|
+
alert_instance = (
|
|
4238
|
+
alert_data
|
|
4239
|
+
if isinstance(alert_data, AlertConfig)
|
|
4240
|
+
else AlertConfig.from_dict(alert_data)
|
|
4241
|
+
)
|
|
4242
|
+
# Validation is necessary here because users can directly invoke this function
|
|
4243
|
+
# through `mlrun.get_run_db().store_alert_config()`.
|
|
4244
|
+
alert_instance.validate_required_fields()
|
|
4245
|
+
|
|
4246
|
+
alert_data = alert_instance.to_dict()
|
|
4247
|
+
body = _as_json(alert_data)
|
|
4248
|
+
response = self.api_call("PUT", endpoint_path, error_message, body=body)
|
|
4249
|
+
return AlertConfig.from_dict(response.json())
|
|
4250
|
+
|
|
4251
|
+
def get_alert_config(self, alert_name: str, project="") -> AlertConfig:
|
|
4252
|
+
"""
|
|
4253
|
+
Retrieve an alert.
|
|
4254
|
+
|
|
4255
|
+
:param alert_name: The name of the alert to retrieve.
|
|
4256
|
+
:param project: The project that the alert belongs to.
|
|
4257
|
+
|
|
4258
|
+
:returns: The alert object.
|
|
4259
|
+
"""
|
|
4260
|
+
project = project or config.default_project
|
|
4261
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}"
|
|
4262
|
+
error_message = f"get alert {project}/alerts/{alert_name}"
|
|
4263
|
+
response = self.api_call("GET", endpoint_path, error_message)
|
|
4264
|
+
return AlertConfig.from_dict(response.json())
|
|
4265
|
+
|
|
4266
|
+
def list_alerts_configs(self, project="") -> list[AlertConfig]:
|
|
4267
|
+
"""
|
|
4268
|
+
Retrieve list of alerts of a project.
|
|
4269
|
+
|
|
4270
|
+
:param project: The project name.
|
|
4271
|
+
|
|
4272
|
+
:returns: All the alerts objects of the project.
|
|
4273
|
+
"""
|
|
4274
|
+
project = project or config.default_project
|
|
4275
|
+
endpoint_path = f"projects/{project}/alerts"
|
|
4276
|
+
error_message = f"get alerts {project}/alerts"
|
|
4277
|
+
response = self.api_call("GET", endpoint_path, error_message).json()
|
|
4278
|
+
results = []
|
|
4279
|
+
for item in response:
|
|
4280
|
+
results.append(AlertConfig(**item))
|
|
4281
|
+
return results
|
|
4282
|
+
|
|
4283
|
+
def delete_alert_config(self, alert_name: str, project=""):
|
|
4284
|
+
"""
|
|
4285
|
+
Delete an alert.
|
|
4286
|
+
:param alert_name: The name of the alert to delete.
|
|
4287
|
+
:param project: The project that the alert belongs to.
|
|
4288
|
+
"""
|
|
4289
|
+
project = project or config.default_project
|
|
4290
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}"
|
|
4291
|
+
error_message = f"delete alert {project}/alerts/{alert_name}"
|
|
4292
|
+
self.api_call("DELETE", endpoint_path, error_message)
|
|
4293
|
+
|
|
4294
|
+
def reset_alert_config(self, alert_name: str, project=""):
|
|
4295
|
+
"""
|
|
4296
|
+
Reset an alert.
|
|
4297
|
+
|
|
4298
|
+
:param alert_name: The name of the alert to reset.
|
|
4299
|
+
:param project: The project that the alert belongs to.
|
|
4300
|
+
"""
|
|
4301
|
+
project = project or config.default_project
|
|
4302
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}/reset"
|
|
4303
|
+
error_message = f"post alert {project}/alerts/{alert_name}/reset"
|
|
4304
|
+
self.api_call("POST", endpoint_path, error_message)
|
|
4305
|
+
|
|
4306
|
+
def get_alert_template(
|
|
4307
|
+
self, template_name: str
|
|
4308
|
+
) -> mlrun.common.schemas.AlertTemplate:
|
|
4309
|
+
"""
|
|
4310
|
+
Retrieve a specific alert template.
|
|
4311
|
+
|
|
4312
|
+
:param template_name: The name of the template to retrieve.
|
|
4313
|
+
|
|
4314
|
+
:returns: The template object.
|
|
4315
|
+
"""
|
|
4316
|
+
endpoint_path = f"alert-templates/{template_name}"
|
|
4317
|
+
error_message = f"get template alert-templates/{template_name}"
|
|
4318
|
+
response = self.api_call("GET", endpoint_path, error_message)
|
|
4319
|
+
return mlrun.common.schemas.AlertTemplate(**response.json())
|
|
4320
|
+
|
|
4321
|
+
def list_alert_templates(self) -> list[mlrun.common.schemas.AlertTemplate]:
|
|
4322
|
+
"""
|
|
4323
|
+
Retrieve list of all alert templates.
|
|
4324
|
+
|
|
4325
|
+
:returns: All the alert template objects in the database.
|
|
4326
|
+
"""
|
|
4327
|
+
endpoint_path = "alert-templates"
|
|
4328
|
+
error_message = "get templates /alert-templates"
|
|
4329
|
+
response = self.api_call("GET", endpoint_path, error_message).json()
|
|
4330
|
+
results = []
|
|
4331
|
+
for item in response:
|
|
4332
|
+
results.append(mlrun.common.schemas.AlertTemplate(**item))
|
|
4333
|
+
return results
|
|
4334
|
+
|
|
3667
4335
|
|
|
3668
4336
|
def _as_json(obj):
|
|
3669
4337
|
fn = getattr(obj, "to_json", None)
|