mlrun 1.6.4rc2__py3-none-any.whl → 1.7.0rc20__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 +26 -112
- mlrun/alerts/__init__.py +15 -0
- mlrun/alerts/alert.py +144 -0
- mlrun/api/schemas/__init__.py +5 -4
- mlrun/artifacts/__init__.py +8 -3
- mlrun/artifacts/base.py +46 -257
- mlrun/artifacts/dataset.py +11 -192
- mlrun/artifacts/manager.py +47 -48
- mlrun/artifacts/model.py +31 -159
- mlrun/artifacts/plots.py +23 -380
- mlrun/common/constants.py +69 -0
- mlrun/common/db/sql_session.py +2 -3
- mlrun/common/formatters/__init__.py +19 -0
- mlrun/common/formatters/artifact.py +21 -0
- mlrun/common/formatters/base.py +78 -0
- mlrun/common/formatters/function.py +41 -0
- mlrun/common/formatters/pipeline.py +53 -0
- mlrun/common/formatters/project.py +51 -0
- mlrun/common/helpers.py +1 -2
- mlrun/common/model_monitoring/helpers.py +9 -5
- mlrun/{runtimes → common/runtimes}/constants.py +37 -9
- mlrun/common/schemas/__init__.py +24 -4
- mlrun/common/schemas/alert.py +203 -0
- mlrun/common/schemas/api_gateway.py +148 -0
- mlrun/common/schemas/artifact.py +18 -8
- mlrun/common/schemas/auth.py +11 -5
- mlrun/common/schemas/background_task.py +1 -1
- mlrun/common/schemas/client_spec.py +4 -1
- mlrun/common/schemas/feature_store.py +16 -16
- mlrun/common/schemas/frontend_spec.py +8 -7
- mlrun/common/schemas/function.py +5 -1
- mlrun/common/schemas/hub.py +11 -18
- mlrun/common/schemas/memory_reports.py +2 -2
- mlrun/common/schemas/model_monitoring/__init__.py +18 -3
- mlrun/common/schemas/model_monitoring/constants.py +83 -26
- mlrun/common/schemas/model_monitoring/grafana.py +13 -9
- mlrun/common/schemas/model_monitoring/model_endpoints.py +99 -16
- mlrun/common/schemas/notification.py +4 -4
- mlrun/common/schemas/object.py +2 -2
- mlrun/{runtimes/mpijob/v1alpha1.py → common/schemas/pagination.py} +10 -13
- mlrun/common/schemas/pipeline.py +1 -10
- mlrun/common/schemas/project.py +24 -23
- mlrun/common/schemas/runtime_resource.py +8 -12
- mlrun/common/schemas/schedule.py +3 -3
- mlrun/common/schemas/tag.py +1 -2
- mlrun/common/schemas/workflow.py +2 -2
- mlrun/common/types.py +7 -1
- mlrun/config.py +54 -17
- mlrun/data_types/to_pandas.py +10 -12
- mlrun/datastore/__init__.py +5 -8
- mlrun/datastore/alibaba_oss.py +130 -0
- mlrun/datastore/azure_blob.py +17 -5
- mlrun/datastore/base.py +62 -39
- mlrun/datastore/datastore.py +28 -9
- mlrun/datastore/datastore_profile.py +146 -20
- mlrun/datastore/filestore.py +0 -1
- mlrun/datastore/google_cloud_storage.py +6 -2
- mlrun/datastore/hdfs.py +56 -0
- mlrun/datastore/inmem.py +2 -2
- mlrun/datastore/redis.py +6 -2
- mlrun/datastore/s3.py +9 -0
- mlrun/datastore/snowflake_utils.py +43 -0
- mlrun/datastore/sources.py +201 -96
- mlrun/datastore/spark_utils.py +1 -2
- mlrun/datastore/store_resources.py +7 -7
- mlrun/datastore/targets.py +358 -104
- mlrun/datastore/utils.py +72 -58
- mlrun/datastore/v3io.py +5 -1
- mlrun/db/base.py +185 -35
- mlrun/db/factory.py +1 -1
- mlrun/db/httpdb.py +614 -179
- mlrun/db/nopdb.py +210 -26
- mlrun/errors.py +12 -1
- mlrun/execution.py +41 -24
- mlrun/feature_store/__init__.py +0 -2
- mlrun/feature_store/api.py +40 -72
- mlrun/feature_store/common.py +1 -1
- mlrun/feature_store/feature_set.py +76 -55
- mlrun/feature_store/feature_vector.py +28 -30
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/base.py +16 -11
- mlrun/feature_store/retrieval/conversion.py +11 -13
- mlrun/feature_store/retrieval/dask_merger.py +2 -0
- mlrun/feature_store/retrieval/job.py +9 -3
- mlrun/feature_store/retrieval/local_merger.py +2 -0
- mlrun/feature_store/retrieval/spark_merger.py +34 -24
- mlrun/feature_store/steps.py +37 -34
- mlrun/features.py +9 -20
- 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 +2 -3
- 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 +1 -1
- 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 +4 -3
- 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 +3 -6
- 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 +14 -16
- mlrun/launcher/__init__.py +1 -1
- mlrun/launcher/base.py +16 -15
- mlrun/launcher/client.py +8 -6
- mlrun/launcher/factory.py +1 -1
- mlrun/launcher/local.py +17 -11
- mlrun/launcher/remote.py +16 -10
- mlrun/lists.py +7 -6
- mlrun/model.py +238 -73
- mlrun/model_monitoring/__init__.py +1 -1
- mlrun/model_monitoring/api.py +138 -315
- mlrun/model_monitoring/application.py +5 -296
- mlrun/model_monitoring/applications/__init__.py +24 -0
- mlrun/model_monitoring/applications/_application_steps.py +157 -0
- mlrun/model_monitoring/applications/base.py +282 -0
- mlrun/model_monitoring/applications/context.py +214 -0
- mlrun/model_monitoring/applications/evidently_base.py +211 -0
- mlrun/model_monitoring/applications/histogram_data_drift.py +349 -0
- mlrun/model_monitoring/applications/results.py +99 -0
- mlrun/model_monitoring/controller.py +104 -84
- mlrun/model_monitoring/controller_handler.py +13 -5
- mlrun/model_monitoring/db/__init__.py +18 -0
- mlrun/model_monitoring/{stores → db/stores}/__init__.py +43 -36
- mlrun/model_monitoring/db/stores/base/__init__.py +15 -0
- mlrun/model_monitoring/{stores/model_endpoint_store.py → db/stores/base/store.py} +64 -40
- mlrun/model_monitoring/db/stores/sqldb/__init__.py +13 -0
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +71 -0
- mlrun/model_monitoring/{stores → db/stores/sqldb}/models/base.py +109 -5
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +88 -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 +684 -0
- mlrun/model_monitoring/db/stores/v3io_kv/__init__.py +13 -0
- mlrun/model_monitoring/{stores/kv_model_endpoint_store.py → db/stores/v3io_kv/kv_store.py} +310 -165
- mlrun/model_monitoring/db/tsdb/__init__.py +100 -0
- mlrun/model_monitoring/db/tsdb/base.py +329 -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 +240 -0
- mlrun/model_monitoring/db/tsdb/tdengine/stream_graph_steps.py +45 -0
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +397 -0
- mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +630 -0
- mlrun/model_monitoring/evidently_application.py +6 -118
- mlrun/model_monitoring/features_drift_table.py +134 -106
- mlrun/model_monitoring/helpers.py +127 -28
- 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/prometheus.py +1 -4
- mlrun/model_monitoring/stream_processing.py +62 -231
- mlrun/model_monitoring/tracking_policy.py +9 -2
- mlrun/model_monitoring/writer.py +152 -124
- 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 +6 -6
- 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 +35 -21
- mlrun/projects/pipelines.py +68 -99
- mlrun/projects/project.py +830 -266
- mlrun/render.py +3 -11
- mlrun/run.py +162 -166
- mlrun/runtimes/__init__.py +62 -7
- mlrun/runtimes/base.py +39 -32
- mlrun/runtimes/daskjob.py +8 -8
- mlrun/runtimes/databricks_job/databricks_cancel_task.py +1 -1
- mlrun/runtimes/databricks_job/databricks_runtime.py +7 -7
- mlrun/runtimes/databricks_job/databricks_wrapper.py +1 -1
- mlrun/runtimes/funcdoc.py +0 -28
- mlrun/runtimes/function_reference.py +1 -1
- mlrun/runtimes/kubejob.py +28 -122
- mlrun/runtimes/local.py +6 -3
- 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 +709 -0
- mlrun/runtimes/nuclio/application/__init__.py +15 -0
- mlrun/runtimes/nuclio/application/application.py +523 -0
- mlrun/runtimes/nuclio/application/reverse_proxy.go +95 -0
- mlrun/runtimes/{function.py → nuclio/function.py} +112 -73
- mlrun/runtimes/{nuclio.py → nuclio/nuclio.py} +6 -6
- mlrun/runtimes/{serving.py → nuclio/serving.py} +45 -51
- mlrun/runtimes/pod.py +286 -88
- mlrun/runtimes/remotesparkjob.py +2 -2
- mlrun/runtimes/sparkjob/spark3job.py +51 -34
- mlrun/runtimes/utils.py +7 -75
- mlrun/secrets.py +9 -5
- mlrun/serving/remote.py +2 -7
- mlrun/serving/routers.py +13 -10
- mlrun/serving/server.py +22 -26
- mlrun/serving/states.py +99 -25
- mlrun/serving/utils.py +3 -3
- mlrun/serving/v1_serving.py +6 -7
- mlrun/serving/v2_serving.py +59 -20
- mlrun/track/tracker.py +2 -1
- mlrun/track/tracker_manager.py +3 -3
- mlrun/track/trackers/mlflow_tracker.py +1 -2
- mlrun/utils/async_http.py +5 -7
- mlrun/utils/azure_vault.py +1 -1
- mlrun/utils/clones.py +1 -2
- mlrun/utils/condition_evaluator.py +3 -3
- mlrun/utils/db.py +3 -3
- mlrun/utils/helpers.py +183 -197
- mlrun/utils/http.py +2 -5
- mlrun/utils/logger.py +76 -14
- mlrun/utils/notifications/notification/__init__.py +17 -12
- mlrun/utils/notifications/notification/base.py +14 -2
- mlrun/utils/notifications/notification/console.py +2 -0
- mlrun/utils/notifications/notification/git.py +3 -1
- mlrun/utils/notifications/notification/ipython.py +3 -1
- mlrun/utils/notifications/notification/slack.py +101 -21
- mlrun/utils/notifications/notification/webhook.py +11 -1
- mlrun/utils/notifications/notification_pusher.py +155 -30
- mlrun/utils/retryer.py +208 -0
- mlrun/utils/singleton.py +1 -1
- mlrun/utils/v3io_clients.py +2 -4
- mlrun/utils/version/version.json +2 -2
- mlrun/utils/version/version.py +2 -6
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/METADATA +31 -19
- mlrun-1.7.0rc20.dist-info/RECORD +353 -0
- mlrun/kfpops.py +0 -868
- mlrun/model_monitoring/batch.py +0 -1095
- mlrun/model_monitoring/stores/models/__init__.py +0 -27
- mlrun/model_monitoring/stores/sql_model_endpoint_store.py +0 -384
- mlrun/platforms/other.py +0 -306
- mlrun-1.6.4rc2.dist-info/RECORD +0 -314
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/LICENSE +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/WHEEL +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/entry_points.txt +0 -0
- {mlrun-1.6.4rc2.dist-info → mlrun-1.7.0rc20.dist-info}/top_level.txt +0 -0
mlrun/db/httpdb.py
CHANGED
|
@@ -11,28 +11,35 @@
|
|
|
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.utils
|
|
42
|
+
from mlrun.alerts.alert import AlertConfig
|
|
36
43
|
from mlrun.db.auth_utils import OAuthClientIDTokenProvider, StaticTokenProvider
|
|
37
44
|
from mlrun.errors import MLRunInvalidArgumentError, err_to_str
|
|
38
45
|
|
|
@@ -46,7 +53,6 @@ from ..utils import (
|
|
|
46
53
|
datetime_to_iso,
|
|
47
54
|
dict_to_json,
|
|
48
55
|
logger,
|
|
49
|
-
new_pipe_metadata,
|
|
50
56
|
normalize_name,
|
|
51
57
|
version,
|
|
52
58
|
)
|
|
@@ -191,7 +197,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
191
197
|
headers=None,
|
|
192
198
|
timeout=45,
|
|
193
199
|
version=None,
|
|
194
|
-
):
|
|
200
|
+
) -> requests.Response:
|
|
195
201
|
"""Perform a direct REST API call on the :py:mod:`mlrun` API server.
|
|
196
202
|
|
|
197
203
|
Caution:
|
|
@@ -209,7 +215,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
209
215
|
:param version: API version to use, None (the default) will mean to use the default value from config,
|
|
210
216
|
for un-versioned api set an empty string.
|
|
211
217
|
|
|
212
|
-
:return:
|
|
218
|
+
:return: `requests.Response` HTTP response object
|
|
213
219
|
"""
|
|
214
220
|
url = self.get_base_api_url(path, version)
|
|
215
221
|
kw = {
|
|
@@ -292,6 +298,68 @@ class HTTPRunDB(RunDBInterface):
|
|
|
292
298
|
|
|
293
299
|
return response
|
|
294
300
|
|
|
301
|
+
def paginated_api_call(
|
|
302
|
+
self,
|
|
303
|
+
method,
|
|
304
|
+
path,
|
|
305
|
+
error=None,
|
|
306
|
+
params=None,
|
|
307
|
+
body=None,
|
|
308
|
+
json=None,
|
|
309
|
+
headers=None,
|
|
310
|
+
timeout=45,
|
|
311
|
+
version=None,
|
|
312
|
+
) -> typing.Generator[requests.Response, None, None]:
|
|
313
|
+
"""
|
|
314
|
+
Calls the api with pagination, yielding each page of the response
|
|
315
|
+
"""
|
|
316
|
+
|
|
317
|
+
def _api_call(_params):
|
|
318
|
+
return self.api_call(
|
|
319
|
+
method=method,
|
|
320
|
+
path=path,
|
|
321
|
+
error=error,
|
|
322
|
+
params=_params,
|
|
323
|
+
body=body,
|
|
324
|
+
json=json,
|
|
325
|
+
headers=headers,
|
|
326
|
+
timeout=timeout,
|
|
327
|
+
version=version,
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
first_page_params = deepcopy(params) or {}
|
|
331
|
+
first_page_params["page"] = 1
|
|
332
|
+
first_page_params["page-size"] = config.httpdb.pagination.default_page_size
|
|
333
|
+
response = _api_call(first_page_params)
|
|
334
|
+
page_token = response.json().get("pagination", {}).get("page-token")
|
|
335
|
+
if not page_token:
|
|
336
|
+
yield response
|
|
337
|
+
return
|
|
338
|
+
|
|
339
|
+
params_with_page_token = deepcopy(params) or {}
|
|
340
|
+
params_with_page_token["page-token"] = page_token
|
|
341
|
+
while page_token:
|
|
342
|
+
yield response
|
|
343
|
+
try:
|
|
344
|
+
response = _api_call(params_with_page_token)
|
|
345
|
+
except mlrun.errors.MLRunNotFoundError:
|
|
346
|
+
# pagination token expired
|
|
347
|
+
break
|
|
348
|
+
|
|
349
|
+
page_token = response.json().get("pagination", {}).get("page-token", None)
|
|
350
|
+
|
|
351
|
+
@staticmethod
|
|
352
|
+
def process_paginated_responses(
|
|
353
|
+
responses: typing.Generator[requests.Response, None, None], key: str = "data"
|
|
354
|
+
) -> list[typing.Any]:
|
|
355
|
+
"""
|
|
356
|
+
Processes the paginated responses and returns the combined data
|
|
357
|
+
"""
|
|
358
|
+
data = []
|
|
359
|
+
for response in responses:
|
|
360
|
+
data.extend(response.json().get(key, []))
|
|
361
|
+
return data
|
|
362
|
+
|
|
295
363
|
def _init_session(self, retry_on_post: bool = False):
|
|
296
364
|
return mlrun.utils.HTTPSessionWithRetry(
|
|
297
365
|
retry_on_exception=config.httpdb.retry_api_call_on_exception
|
|
@@ -324,7 +392,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
324
392
|
|
|
325
393
|
For example::
|
|
326
394
|
|
|
327
|
-
config.dbpath = config.dbpath or
|
|
395
|
+
config.dbpath = config.dbpath or "http://mlrun-api:8080"
|
|
328
396
|
db = get_run_db().connect()
|
|
329
397
|
"""
|
|
330
398
|
# hack to allow unit tests to instantiate HTTPRunDB without a real server behind
|
|
@@ -464,6 +532,10 @@ class HTTPRunDB(RunDBInterface):
|
|
|
464
532
|
server_cfg.get("model_endpoint_monitoring_endpoint_store_connection")
|
|
465
533
|
or config.model_endpoint_monitoring.endpoint_store_connection
|
|
466
534
|
)
|
|
535
|
+
config.model_endpoint_monitoring.tsdb_connection = (
|
|
536
|
+
server_cfg.get("model_monitoring_tsdb_connection")
|
|
537
|
+
or config.model_endpoint_monitoring.tsdb_connection
|
|
538
|
+
)
|
|
467
539
|
config.packagers = server_cfg.get("packagers") or config.packagers
|
|
468
540
|
server_data_prefixes = server_cfg.get("feature_store_data_prefixes") or {}
|
|
469
541
|
for prefix in ["default", "nosql", "redisnosql"]:
|
|
@@ -472,6 +544,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
472
544
|
setattr(
|
|
473
545
|
config.feature_store.data_prefixes, prefix, server_prefix_value
|
|
474
546
|
)
|
|
547
|
+
config.feature_store.default_targets = (
|
|
548
|
+
server_cfg.get("feature_store_default_targets")
|
|
549
|
+
or config.feature_store.default_targets
|
|
550
|
+
)
|
|
551
|
+
config.alerts.mode = server_cfg.get("alerts_mode") or config.alerts.mode
|
|
475
552
|
|
|
476
553
|
except Exception as exc:
|
|
477
554
|
logger.warning(
|
|
@@ -518,7 +595,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
518
595
|
if offset < 0:
|
|
519
596
|
raise MLRunInvalidArgumentError("Offset cannot be negative")
|
|
520
597
|
if size is None:
|
|
521
|
-
size = int(
|
|
598
|
+
size = int(mlrun.mlconf.httpdb.logs.pull_logs_default_size_limit)
|
|
522
599
|
elif size == -1:
|
|
523
600
|
logger.warning(
|
|
524
601
|
"Retrieving all logs. This may be inefficient and can result in a large log."
|
|
@@ -564,33 +641,35 @@ class HTTPRunDB(RunDBInterface):
|
|
|
564
641
|
|
|
565
642
|
state, text = self.get_log(uid, project, offset=offset)
|
|
566
643
|
if text:
|
|
567
|
-
print(text.decode(errors=
|
|
644
|
+
print(text.decode(errors=mlrun.mlconf.httpdb.logs.decode.errors))
|
|
568
645
|
nil_resp = 0
|
|
569
646
|
while True:
|
|
570
647
|
offset += len(text)
|
|
571
648
|
# if we get 3 nil responses in a row, increase the sleep time to 10 seconds
|
|
572
649
|
# TODO: refactor this to use a conditional backoff mechanism
|
|
573
650
|
if nil_resp < 3:
|
|
574
|
-
time.sleep(int(
|
|
651
|
+
time.sleep(int(mlrun.mlconf.httpdb.logs.pull_logs_default_interval))
|
|
575
652
|
else:
|
|
576
653
|
time.sleep(
|
|
577
|
-
int(
|
|
654
|
+
int(
|
|
655
|
+
mlrun.mlconf.httpdb.logs.pull_logs_backoff_no_logs_default_interval
|
|
656
|
+
)
|
|
578
657
|
)
|
|
579
658
|
state, text = self.get_log(uid, project, offset=offset)
|
|
580
659
|
if text:
|
|
581
660
|
nil_resp = 0
|
|
582
661
|
print(
|
|
583
|
-
text.decode(errors=
|
|
662
|
+
text.decode(errors=mlrun.mlconf.httpdb.logs.decode.errors),
|
|
584
663
|
end="",
|
|
585
664
|
)
|
|
586
665
|
else:
|
|
587
666
|
nil_resp += 1
|
|
588
667
|
|
|
589
668
|
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,
|
|
669
|
+
mlrun.common.runtimes.constants.RunStates.pending,
|
|
670
|
+
mlrun.common.runtimes.constants.RunStates.running,
|
|
671
|
+
mlrun.common.runtimes.constants.RunStates.created,
|
|
672
|
+
mlrun.common.runtimes.constants.RunStates.aborting,
|
|
594
673
|
]:
|
|
595
674
|
continue
|
|
596
675
|
else:
|
|
@@ -676,10 +755,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
676
755
|
def list_runs(
|
|
677
756
|
self,
|
|
678
757
|
name: Optional[str] = None,
|
|
679
|
-
uid: Optional[Union[str,
|
|
758
|
+
uid: Optional[Union[str, list[str]]] = None,
|
|
680
759
|
project: Optional[str] = None,
|
|
681
|
-
labels: Optional[Union[str,
|
|
682
|
-
state: Optional[
|
|
760
|
+
labels: Optional[Union[str, list[str]]] = None,
|
|
761
|
+
state: Optional[
|
|
762
|
+
mlrun.common.runtimes.constants.RunStates
|
|
763
|
+
] = None, # Backward compatibility
|
|
764
|
+
states: typing.Optional[list[mlrun.common.runtimes.constants.RunStates]] = None,
|
|
683
765
|
sort: bool = True,
|
|
684
766
|
last: int = 0,
|
|
685
767
|
iter: bool = False,
|
|
@@ -704,9 +786,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
704
786
|
|
|
705
787
|
Example::
|
|
706
788
|
|
|
707
|
-
runs = db.list_runs(
|
|
789
|
+
runs = db.list_runs(
|
|
790
|
+
name="download", project="iris", labels=["owner=admin", "kind=job"]
|
|
791
|
+
)
|
|
708
792
|
# If running in Jupyter, can use the .show() function to display the results
|
|
709
|
-
db.list_runs(name=
|
|
793
|
+
db.list_runs(name="", project=project_name).show()
|
|
710
794
|
|
|
711
795
|
|
|
712
796
|
:param name: Name of the run to retrieve.
|
|
@@ -715,7 +799,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
715
799
|
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value
|
|
716
800
|
of a label (i.e. list("key=value")) or by looking for the existence of a given
|
|
717
801
|
key (i.e. "key").
|
|
718
|
-
:param state: List only runs whose state is specified.
|
|
802
|
+
:param state: Deprecated - List only runs whose state is specified (will be removed in 1.9.0)
|
|
803
|
+
:param states: List only runs whose state is one of the provided states.
|
|
719
804
|
:param sort: Whether to sort the result according to their start time. Otherwise, results will be
|
|
720
805
|
returned by their internal order in the DB (order will not be guaranteed).
|
|
721
806
|
:param last: Deprecated - currently not used (will be removed in 1.8.0).
|
|
@@ -751,11 +836,19 @@ class HTTPRunDB(RunDBInterface):
|
|
|
751
836
|
FutureWarning,
|
|
752
837
|
)
|
|
753
838
|
|
|
839
|
+
if state:
|
|
840
|
+
# TODO: Remove this in 1.9.0
|
|
841
|
+
warnings.warn(
|
|
842
|
+
"'state' is deprecated and will be removed in 1.9.0. Use 'states' instead.",
|
|
843
|
+
FutureWarning,
|
|
844
|
+
)
|
|
845
|
+
|
|
754
846
|
if (
|
|
755
847
|
not name
|
|
756
848
|
and not uid
|
|
757
849
|
and not labels
|
|
758
850
|
and not state
|
|
851
|
+
and not states
|
|
759
852
|
and not last
|
|
760
853
|
and not start_time_from
|
|
761
854
|
and not start_time_to
|
|
@@ -774,7 +867,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
774
867
|
"name": name,
|
|
775
868
|
"uid": uid,
|
|
776
869
|
"label": labels or [],
|
|
777
|
-
"state": state
|
|
870
|
+
"state": mlrun.utils.helpers.as_list(state)
|
|
871
|
+
if state is not None
|
|
872
|
+
else states or None,
|
|
778
873
|
"sort": bool2str(sort),
|
|
779
874
|
"iter": bool2str(iter),
|
|
780
875
|
"start_time_from": datetime_to_iso(start_time_from),
|
|
@@ -797,15 +892,15 @@ class HTTPRunDB(RunDBInterface):
|
|
|
797
892
|
)
|
|
798
893
|
error = "list runs"
|
|
799
894
|
_path = self._path_of("runs", project)
|
|
800
|
-
|
|
801
|
-
return RunList(
|
|
895
|
+
responses = self.paginated_api_call("GET", _path, error, params=params)
|
|
896
|
+
return RunList(self.process_paginated_responses(responses, "runs"))
|
|
802
897
|
|
|
803
898
|
def del_runs(self, name=None, project=None, labels=None, state=None, days_ago=0):
|
|
804
899
|
"""Delete a group of runs identified by the parameters of the function.
|
|
805
900
|
|
|
806
901
|
Example::
|
|
807
902
|
|
|
808
|
-
db.del_runs(state=
|
|
903
|
+
db.del_runs(state="completed")
|
|
809
904
|
|
|
810
905
|
:param name: Name of the task which the runs belong to.
|
|
811
906
|
:param project: Project to which the runs belong.
|
|
@@ -901,7 +996,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
901
996
|
error = f"read artifact {project}/{key}"
|
|
902
997
|
# explicitly set artifacts format to 'full' since old servers may default to 'legacy'
|
|
903
998
|
params = {
|
|
904
|
-
"format": mlrun.common.
|
|
999
|
+
"format": mlrun.common.formatters.ArtifactFormat.full.value,
|
|
905
1000
|
"tag": tag,
|
|
906
1001
|
"tree": tree,
|
|
907
1002
|
"uid": uid,
|
|
@@ -911,7 +1006,18 @@ class HTTPRunDB(RunDBInterface):
|
|
|
911
1006
|
resp = self.api_call("GET", endpoint_path, error, params=params, version="v2")
|
|
912
1007
|
return resp.json()
|
|
913
1008
|
|
|
914
|
-
def del_artifact(
|
|
1009
|
+
def del_artifact(
|
|
1010
|
+
self,
|
|
1011
|
+
key,
|
|
1012
|
+
tag=None,
|
|
1013
|
+
project="",
|
|
1014
|
+
tree=None,
|
|
1015
|
+
uid=None,
|
|
1016
|
+
deletion_strategy: mlrun.common.schemas.artifact.ArtifactsDeletionStrategies = (
|
|
1017
|
+
mlrun.common.schemas.artifact.ArtifactsDeletionStrategies.metadata_only
|
|
1018
|
+
),
|
|
1019
|
+
secrets: dict = None,
|
|
1020
|
+
):
|
|
915
1021
|
"""Delete an artifact.
|
|
916
1022
|
|
|
917
1023
|
:param key: Identifying key of the artifact.
|
|
@@ -919,6 +1025,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
919
1025
|
:param project: Project that the artifact belongs to.
|
|
920
1026
|
:param tree: The tree which generated this artifact.
|
|
921
1027
|
:param uid: A unique ID for this specific version of the artifact (the uid that was generated in the backend)
|
|
1028
|
+
:param deletion_strategy: The artifact deletion strategy types.
|
|
1029
|
+
:param secrets: Credentials needed to access the artifact data.
|
|
922
1030
|
"""
|
|
923
1031
|
|
|
924
1032
|
endpoint_path = f"projects/{project}/artifacts/{key}"
|
|
@@ -927,16 +1035,24 @@ class HTTPRunDB(RunDBInterface):
|
|
|
927
1035
|
"tag": tag,
|
|
928
1036
|
"tree": tree,
|
|
929
1037
|
"uid": uid,
|
|
1038
|
+
"deletion_strategy": deletion_strategy,
|
|
930
1039
|
}
|
|
931
1040
|
error = f"del artifact {project}/{key}"
|
|
932
|
-
self.api_call(
|
|
1041
|
+
self.api_call(
|
|
1042
|
+
"DELETE",
|
|
1043
|
+
endpoint_path,
|
|
1044
|
+
error,
|
|
1045
|
+
params=params,
|
|
1046
|
+
version="v2",
|
|
1047
|
+
body=dict_to_json(secrets),
|
|
1048
|
+
)
|
|
933
1049
|
|
|
934
1050
|
def list_artifacts(
|
|
935
1051
|
self,
|
|
936
1052
|
name=None,
|
|
937
1053
|
project=None,
|
|
938
1054
|
tag=None,
|
|
939
|
-
labels: Optional[Union[
|
|
1055
|
+
labels: Optional[Union[dict[str, str], list[str]]] = None,
|
|
940
1056
|
since=None,
|
|
941
1057
|
until=None,
|
|
942
1058
|
iter: int = None,
|
|
@@ -951,11 +1067,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
951
1067
|
Examples::
|
|
952
1068
|
|
|
953
1069
|
# Show latest version of all artifacts in project
|
|
954
|
-
latest_artifacts = db.list_artifacts(
|
|
1070
|
+
latest_artifacts = db.list_artifacts("", tag="latest", project="iris")
|
|
955
1071
|
# check different artifact versions for a specific artifact
|
|
956
|
-
result_versions = db.list_artifacts(
|
|
1072
|
+
result_versions = db.list_artifacts("results", tag="*", project="iris")
|
|
957
1073
|
# Show artifacts with label filters - both uploaded and of binary type
|
|
958
|
-
result_labels = db.list_artifacts(
|
|
1074
|
+
result_labels = db.list_artifacts(
|
|
1075
|
+
"results", tag="*", project="iris", labels=["uploaded", "type=binary"]
|
|
1076
|
+
)
|
|
959
1077
|
|
|
960
1078
|
:param name: Name of artifacts to retrieve. Name with '~' prefix is used as a like query, and is not
|
|
961
1079
|
case-sensitive. This means that querying for ``~name`` may return artifacts named
|
|
@@ -994,7 +1112,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
994
1112
|
"kind": kind,
|
|
995
1113
|
"category": category,
|
|
996
1114
|
"tree": tree,
|
|
997
|
-
"format": mlrun.common.
|
|
1115
|
+
"format": mlrun.common.formatters.ArtifactFormat.full.value,
|
|
998
1116
|
"producer_uri": producer_uri,
|
|
999
1117
|
}
|
|
1000
1118
|
error = "list artifacts"
|
|
@@ -1032,7 +1150,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1032
1150
|
self,
|
|
1033
1151
|
project=None,
|
|
1034
1152
|
category: Union[str, mlrun.common.schemas.ArtifactCategories] = None,
|
|
1035
|
-
) ->
|
|
1153
|
+
) -> list[str]:
|
|
1036
1154
|
"""Return a list of all the tags assigned to artifacts in the scope of the given project."""
|
|
1037
1155
|
|
|
1038
1156
|
project = project or config.default_project
|
|
@@ -1085,7 +1203,29 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1085
1203
|
project = project or config.default_project
|
|
1086
1204
|
path = f"projects/{project}/functions/{name}"
|
|
1087
1205
|
error_message = f"Failed deleting function {project}/{name}"
|
|
1088
|
-
self.api_call("DELETE", path, error_message)
|
|
1206
|
+
response = self.api_call("DELETE", path, error_message, version="v2")
|
|
1207
|
+
if response.status_code == http.HTTPStatus.ACCEPTED:
|
|
1208
|
+
logger.info(
|
|
1209
|
+
"Function is being deleted", project_name=project, function_name=name
|
|
1210
|
+
)
|
|
1211
|
+
background_task = mlrun.common.schemas.BackgroundTask(**response.json())
|
|
1212
|
+
background_task = self._wait_for_background_task_to_reach_terminal_state(
|
|
1213
|
+
background_task.metadata.name, project=project
|
|
1214
|
+
)
|
|
1215
|
+
if (
|
|
1216
|
+
background_task.status.state
|
|
1217
|
+
== mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
1218
|
+
):
|
|
1219
|
+
logger.info(
|
|
1220
|
+
"Function deleted", project_name=project, function_name=name
|
|
1221
|
+
)
|
|
1222
|
+
elif (
|
|
1223
|
+
background_task.status.state
|
|
1224
|
+
== mlrun.common.schemas.BackgroundTaskState.failed
|
|
1225
|
+
):
|
|
1226
|
+
logger.info(
|
|
1227
|
+
"Function deletion failed", project_name=project, function_name=name
|
|
1228
|
+
)
|
|
1089
1229
|
|
|
1090
1230
|
def list_functions(self, name=None, project=None, tag=None, labels=None):
|
|
1091
1231
|
"""Retrieve a list of functions, filtered by specific criteria.
|
|
@@ -1104,8 +1244,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1104
1244
|
}
|
|
1105
1245
|
error = "list functions"
|
|
1106
1246
|
path = f"projects/{project}/functions"
|
|
1107
|
-
|
|
1108
|
-
return
|
|
1247
|
+
responses = self.paginated_api_call("GET", path, error, params=params)
|
|
1248
|
+
return self.process_paginated_responses(responses, "funcs")
|
|
1109
1249
|
|
|
1110
1250
|
def list_runtime_resources(
|
|
1111
1251
|
self,
|
|
@@ -1195,7 +1335,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1195
1335
|
period didn't pass.
|
|
1196
1336
|
:param grace_period: Grace period given to the runtime resource before they are actually removed, counted from
|
|
1197
1337
|
the moment they moved to terminal state
|
|
1198
|
-
(defaults to mlrun.
|
|
1338
|
+
(defaults to mlrun.mlconf.runtime_resources_deletion_grace_period).
|
|
1199
1339
|
|
|
1200
1340
|
:returns: :py:class:`~mlrun.common.schemas.GroupedByProjectRuntimeResourcesOutput` listing the runtime resources
|
|
1201
1341
|
that were removed.
|
|
@@ -1251,7 +1391,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1251
1391
|
name="run_func_on_tuesdays",
|
|
1252
1392
|
kind="job",
|
|
1253
1393
|
scheduled_object=get_data_func,
|
|
1254
|
-
cron_trigger=schemas.ScheduleCronTrigger(
|
|
1394
|
+
cron_trigger=schemas.ScheduleCronTrigger(
|
|
1395
|
+
day_of_week="tue", hour=15, minute=30
|
|
1396
|
+
),
|
|
1255
1397
|
)
|
|
1256
1398
|
db.create_schedule(project_name, schedule)
|
|
1257
1399
|
"""
|
|
@@ -1354,21 +1496,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1354
1496
|
:param builder_env: Kaniko builder pod env vars dict (for config/credentials)
|
|
1355
1497
|
:param force_build: Force building the image, even when no changes were made
|
|
1356
1498
|
"""
|
|
1357
|
-
|
|
1358
|
-
"s3://"
|
|
1359
|
-
)
|
|
1360
|
-
is_ecr_image = mlrun.utils.is_ecr_url(config.httpdb.builder.docker_registry)
|
|
1361
|
-
if not func.spec.build.load_source_on_run and is_s3_source and is_ecr_image:
|
|
1362
|
-
logger.warning(
|
|
1363
|
-
"Building a function image to ECR and loading an S3 source to the image may require conflicting access "
|
|
1364
|
-
"keys. Only the permissions granted to the platform's configured secret will take affect "
|
|
1365
|
-
"(see mlrun.config.config.httpdb.builder.docker_registry_secret). "
|
|
1366
|
-
"In case the permissions are limited to ECR scope, you may use pull_at_runtime=True instead",
|
|
1367
|
-
source=func.spec.build.source,
|
|
1368
|
-
load_source_on_run=func.spec.build.load_source_on_run,
|
|
1369
|
-
default_docker_registry=config.httpdb.builder.docker_registry,
|
|
1370
|
-
)
|
|
1371
|
-
|
|
1499
|
+
self.warn_on_s3_and_ecr_permissions_conflict(func)
|
|
1372
1500
|
try:
|
|
1373
1501
|
req = {
|
|
1374
1502
|
"function": func.to_dict(),
|
|
@@ -1387,10 +1515,102 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1387
1515
|
|
|
1388
1516
|
if not resp.ok:
|
|
1389
1517
|
logger.error(f"bad resp!!\n{resp.text}")
|
|
1390
|
-
raise ValueError("bad
|
|
1518
|
+
raise ValueError("bad submit build response")
|
|
1519
|
+
|
|
1520
|
+
return resp.json()
|
|
1521
|
+
|
|
1522
|
+
def deploy_nuclio_function(
|
|
1523
|
+
self,
|
|
1524
|
+
func: mlrun.runtimes.RemoteRuntime,
|
|
1525
|
+
builder_env: Optional[dict] = None,
|
|
1526
|
+
):
|
|
1527
|
+
"""
|
|
1528
|
+
Deploy a Nuclio function.
|
|
1529
|
+
:param func: Function to build.
|
|
1530
|
+
:param builder_env: Kaniko builder pod env vars dict (for config/credentials)
|
|
1531
|
+
"""
|
|
1532
|
+
func.metadata.project = func.metadata.project or config.default_project
|
|
1533
|
+
self.warn_on_s3_and_ecr_permissions_conflict(func)
|
|
1534
|
+
try:
|
|
1535
|
+
req = {
|
|
1536
|
+
"function": func.to_dict(),
|
|
1537
|
+
}
|
|
1538
|
+
if builder_env:
|
|
1539
|
+
req["builder_env"] = builder_env
|
|
1540
|
+
_path = (
|
|
1541
|
+
f"projects/{func.metadata.project}/nuclio/{func.metadata.name}/deploy"
|
|
1542
|
+
)
|
|
1543
|
+
resp = self.api_call("POST", _path, json=req)
|
|
1544
|
+
except OSError as err:
|
|
1545
|
+
logger.error(f"error submitting nuclio deploy task: {err_to_str(err)}")
|
|
1546
|
+
raise OSError(f"error: cannot submit deploy, {err_to_str(err)}")
|
|
1547
|
+
|
|
1548
|
+
if not resp.ok:
|
|
1549
|
+
logger.error(f"deploy nuclio - bad response:\n{resp.text}")
|
|
1550
|
+
raise ValueError("bad nuclio deploy response")
|
|
1391
1551
|
|
|
1392
1552
|
return resp.json()
|
|
1393
1553
|
|
|
1554
|
+
def get_nuclio_deploy_status(
|
|
1555
|
+
self,
|
|
1556
|
+
func: mlrun.runtimes.RemoteRuntime,
|
|
1557
|
+
last_log_timestamp: float = 0.0,
|
|
1558
|
+
verbose: bool = False,
|
|
1559
|
+
):
|
|
1560
|
+
"""Retrieve the status of a deploy operation currently in progress.
|
|
1561
|
+
|
|
1562
|
+
:param func: Function object that is being built.
|
|
1563
|
+
:param last_log_timestamp: Last timestamp of logs that were already retrieved. Function will return only logs
|
|
1564
|
+
later than this parameter.
|
|
1565
|
+
:param verbose: Add verbose logs into the output.
|
|
1566
|
+
|
|
1567
|
+
:returns: The following parameters:
|
|
1568
|
+
|
|
1569
|
+
- Text of builder logs.
|
|
1570
|
+
- Timestamp of last log retrieved, to be used in subsequent calls to this function.
|
|
1571
|
+
"""
|
|
1572
|
+
|
|
1573
|
+
try:
|
|
1574
|
+
normalized_name = normalize_name(func.metadata.name)
|
|
1575
|
+
params = {
|
|
1576
|
+
"name": normalized_name,
|
|
1577
|
+
"project": func.metadata.project,
|
|
1578
|
+
"tag": func.metadata.tag,
|
|
1579
|
+
"last_log_timestamp": str(last_log_timestamp),
|
|
1580
|
+
"verbose": bool2str(verbose),
|
|
1581
|
+
}
|
|
1582
|
+
_path = f"projects/{func.metadata.project}/nuclio/{normalized_name}/deploy"
|
|
1583
|
+
resp = self.api_call("GET", _path, params=params)
|
|
1584
|
+
except OSError as err:
|
|
1585
|
+
logger.error(f"error getting deploy status: {err_to_str(err)}")
|
|
1586
|
+
raise OSError(f"error: cannot get deploy status, {err_to_str(err)}")
|
|
1587
|
+
|
|
1588
|
+
if not resp.ok:
|
|
1589
|
+
logger.warning(f"failed resp, {resp.text}")
|
|
1590
|
+
raise RunDBError("bad function build response")
|
|
1591
|
+
|
|
1592
|
+
if resp.headers:
|
|
1593
|
+
func.status.state = resp.headers.get("x-mlrun-function-status", "")
|
|
1594
|
+
last_log_timestamp = float(
|
|
1595
|
+
resp.headers.get("x-mlrun-last-timestamp", "0.0")
|
|
1596
|
+
)
|
|
1597
|
+
func.status.address = resp.headers.get("x-mlrun-address", "")
|
|
1598
|
+
func.status.nuclio_name = resp.headers.get("x-mlrun-name", "")
|
|
1599
|
+
func.status.internal_invocation_urls = resp.headers.get(
|
|
1600
|
+
"x-mlrun-internal-invocation-urls", ""
|
|
1601
|
+
).split(",")
|
|
1602
|
+
func.status.external_invocation_urls = resp.headers.get(
|
|
1603
|
+
"x-mlrun-external-invocation-urls", ""
|
|
1604
|
+
).split(",")
|
|
1605
|
+
func.status.container_image = resp.headers.get(
|
|
1606
|
+
"x-mlrun-container-image", ""
|
|
1607
|
+
)
|
|
1608
|
+
|
|
1609
|
+
text = ""
|
|
1610
|
+
if resp.content:
|
|
1611
|
+
text = resp.content.decode()
|
|
1612
|
+
return text, last_log_timestamp
|
|
1613
|
+
|
|
1394
1614
|
def get_builder_status(
|
|
1395
1615
|
self,
|
|
1396
1616
|
func: BaseRuntime,
|
|
@@ -1452,9 +1672,14 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1452
1672
|
func.status.container_image = resp.headers.get(
|
|
1453
1673
|
"x-mlrun-container-image", ""
|
|
1454
1674
|
)
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1675
|
+
|
|
1676
|
+
builder_pod = resp.headers.get("builder_pod", "")
|
|
1677
|
+
if builder_pod:
|
|
1678
|
+
func.status.build_pod = builder_pod
|
|
1679
|
+
|
|
1680
|
+
function_image = resp.headers.get("function_image", "")
|
|
1681
|
+
if function_image:
|
|
1682
|
+
func.spec.image = function_image
|
|
1458
1683
|
|
|
1459
1684
|
text = ""
|
|
1460
1685
|
if resp.content:
|
|
@@ -1517,7 +1742,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1517
1742
|
Retrieve updated information on project background tasks being executed.
|
|
1518
1743
|
If no filter is provided, will return background tasks from the last week.
|
|
1519
1744
|
|
|
1520
|
-
:param project: Project name (defaults to mlrun.
|
|
1745
|
+
:param project: Project name (defaults to mlrun.mlconf.default_project).
|
|
1521
1746
|
:param state: List only background tasks whose state is specified.
|
|
1522
1747
|
:param created_from: Filter by background task created time in ``[created_from, created_to]``.
|
|
1523
1748
|
:param created_to: Filter by background task created time in ``[created_from, created_to]``.
|
|
@@ -1650,14 +1875,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1650
1875
|
if isinstance(pipeline, str):
|
|
1651
1876
|
pipe_file = pipeline
|
|
1652
1877
|
else:
|
|
1653
|
-
pipe_file =
|
|
1654
|
-
conf = new_pipe_metadata(
|
|
1878
|
+
pipe_file = compile_pipeline(
|
|
1655
1879
|
artifact_path=artifact_path,
|
|
1656
1880
|
cleanup_ttl=cleanup_ttl,
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
kfp.compiler.Compiler().compile(
|
|
1660
|
-
pipeline, pipe_file, type_check=False, pipeline_conf=conf
|
|
1881
|
+
ops=ops,
|
|
1882
|
+
pipeline=pipeline,
|
|
1661
1883
|
)
|
|
1662
1884
|
|
|
1663
1885
|
if pipe_file.endswith(".yaml"):
|
|
@@ -1712,8 +1934,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1712
1934
|
page_token: str = "",
|
|
1713
1935
|
filter_: str = "",
|
|
1714
1936
|
format_: Union[
|
|
1715
|
-
str, mlrun.common.
|
|
1716
|
-
] = mlrun.common.
|
|
1937
|
+
str, mlrun.common.formatters.PipelineFormat
|
|
1938
|
+
] = mlrun.common.formatters.PipelineFormat.metadata_only,
|
|
1717
1939
|
page_size: int = None,
|
|
1718
1940
|
) -> mlrun.common.schemas.PipelinesOutput:
|
|
1719
1941
|
"""Retrieve a list of KFP pipelines. This function can be invoked to get all pipelines from all projects,
|
|
@@ -1759,8 +1981,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1759
1981
|
namespace: str = None,
|
|
1760
1982
|
timeout: int = 30,
|
|
1761
1983
|
format_: Union[
|
|
1762
|
-
str, mlrun.common.
|
|
1763
|
-
] = mlrun.common.
|
|
1984
|
+
str, mlrun.common.formatters.PipelineFormat
|
|
1985
|
+
] = mlrun.common.formatters.PipelineFormat.summary,
|
|
1764
1986
|
project: str = None,
|
|
1765
1987
|
):
|
|
1766
1988
|
"""Retrieve details of a specific pipeline using its run ID (as provided when the pipeline was executed)."""
|
|
@@ -1852,9 +2074,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1852
2074
|
project: str,
|
|
1853
2075
|
name: str = None,
|
|
1854
2076
|
tag: str = None,
|
|
1855
|
-
entities:
|
|
1856
|
-
labels:
|
|
1857
|
-
) ->
|
|
2077
|
+
entities: list[str] = None,
|
|
2078
|
+
labels: list[str] = None,
|
|
2079
|
+
) -> list[dict]:
|
|
1858
2080
|
"""List feature-sets which contain specific features. This function may return multiple versions of the same
|
|
1859
2081
|
feature-set if a specific tag is not requested. Note that the various filters of this function actually
|
|
1860
2082
|
refer to the feature-set object containing the features, not to the features themselves.
|
|
@@ -1889,8 +2111,8 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1889
2111
|
project: str,
|
|
1890
2112
|
name: str = None,
|
|
1891
2113
|
tag: str = None,
|
|
1892
|
-
labels:
|
|
1893
|
-
) ->
|
|
2114
|
+
labels: list[str] = None,
|
|
2115
|
+
) -> list[dict]:
|
|
1894
2116
|
"""Retrieve a list of entities and their mapping to the containing feature-sets. This function is similar
|
|
1895
2117
|
to the :py:func:`~list_features` function, and uses the same logic. However, the entities are matched
|
|
1896
2118
|
against the name rather than the features.
|
|
@@ -1934,9 +2156,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1934
2156
|
name: str = None,
|
|
1935
2157
|
tag: str = None,
|
|
1936
2158
|
state: str = None,
|
|
1937
|
-
entities:
|
|
1938
|
-
features:
|
|
1939
|
-
labels:
|
|
2159
|
+
entities: list[str] = None,
|
|
2160
|
+
features: list[str] = None,
|
|
2161
|
+
labels: list[str] = None,
|
|
1940
2162
|
partition_by: Union[
|
|
1941
2163
|
mlrun.common.schemas.FeatureStorePartitionByField, str
|
|
1942
2164
|
] = None,
|
|
@@ -1945,7 +2167,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
1945
2167
|
partition_order: Union[
|
|
1946
2168
|
mlrun.common.schemas.OrderType, str
|
|
1947
2169
|
] = mlrun.common.schemas.OrderType.desc,
|
|
1948
|
-
) ->
|
|
2170
|
+
) -> list[FeatureSet]:
|
|
1949
2171
|
"""Retrieve a list of feature-sets matching the criteria provided.
|
|
1950
2172
|
|
|
1951
2173
|
:param project: Project name.
|
|
@@ -2060,7 +2282,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2060
2282
|
not a full object.
|
|
2061
2283
|
Example::
|
|
2062
2284
|
|
|
2063
|
-
feature_set_update = {"status": {"processed"
|
|
2285
|
+
feature_set_update = {"status": {"processed": True}}
|
|
2064
2286
|
|
|
2065
2287
|
Will apply the field ``status.processed`` to the existing object.
|
|
2066
2288
|
:param project: Project which contains the modified object.
|
|
@@ -2155,7 +2377,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2155
2377
|
name: str = None,
|
|
2156
2378
|
tag: str = None,
|
|
2157
2379
|
state: str = None,
|
|
2158
|
-
labels:
|
|
2380
|
+
labels: list[str] = None,
|
|
2159
2381
|
partition_by: Union[
|
|
2160
2382
|
mlrun.common.schemas.FeatureStorePartitionByField, str
|
|
2161
2383
|
] = None,
|
|
@@ -2164,7 +2386,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2164
2386
|
partition_order: Union[
|
|
2165
2387
|
mlrun.common.schemas.OrderType, str
|
|
2166
2388
|
] = mlrun.common.schemas.OrderType.desc,
|
|
2167
|
-
) ->
|
|
2389
|
+
) -> list[FeatureVector]:
|
|
2168
2390
|
"""Retrieve a list of feature-vectors matching the criteria provided.
|
|
2169
2391
|
|
|
2170
2392
|
:param project: Project name.
|
|
@@ -2366,7 +2588,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2366
2588
|
|
|
2367
2589
|
def tag_artifacts(
|
|
2368
2590
|
self,
|
|
2369
|
-
artifacts: Union[
|
|
2591
|
+
artifacts: Union[list[Artifact], list[dict], Artifact, dict],
|
|
2370
2592
|
project: str,
|
|
2371
2593
|
tag_name: str,
|
|
2372
2594
|
replace: bool = False,
|
|
@@ -2402,11 +2624,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2402
2624
|
self,
|
|
2403
2625
|
owner: str = None,
|
|
2404
2626
|
format_: Union[
|
|
2405
|
-
str, mlrun.common.
|
|
2406
|
-
] = mlrun.common.
|
|
2407
|
-
labels:
|
|
2627
|
+
str, mlrun.common.formatters.ProjectFormat
|
|
2628
|
+
] = mlrun.common.formatters.ProjectFormat.name_only,
|
|
2629
|
+
labels: list[str] = None,
|
|
2408
2630
|
state: Union[str, mlrun.common.schemas.ProjectState] = None,
|
|
2409
|
-
) ->
|
|
2631
|
+
) -> list[Union[mlrun.projects.MlrunProject, str]]:
|
|
2410
2632
|
"""Return a list of the existing projects, potentially filtered by specific criteria.
|
|
2411
2633
|
|
|
2412
2634
|
:param owner: List only projects belonging to this specific owner.
|
|
@@ -2429,7 +2651,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2429
2651
|
|
|
2430
2652
|
error_message = f"Failed listing projects, query: {params}"
|
|
2431
2653
|
response = self.api_call("GET", "projects", error_message, params=params)
|
|
2432
|
-
if format_ == mlrun.common.
|
|
2654
|
+
if format_ == mlrun.common.formatters.ProjectFormat.name_only:
|
|
2433
2655
|
# projects is just a list of strings
|
|
2434
2656
|
return response.json()["projects"]
|
|
2435
2657
|
|
|
@@ -2634,11 +2856,11 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2634
2856
|
:param secrets: A set of secret values to store.
|
|
2635
2857
|
Example::
|
|
2636
2858
|
|
|
2637
|
-
secrets = {
|
|
2859
|
+
secrets = {"password": "myPassw0rd", "aws_key": "111222333"}
|
|
2638
2860
|
db.create_project_secrets(
|
|
2639
2861
|
"project1",
|
|
2640
2862
|
provider=mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2641
|
-
secrets=secrets
|
|
2863
|
+
secrets=secrets,
|
|
2642
2864
|
)
|
|
2643
2865
|
"""
|
|
2644
2866
|
path = f"projects/{project}/secrets"
|
|
@@ -2661,7 +2883,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2661
2883
|
provider: Union[
|
|
2662
2884
|
str, mlrun.common.schemas.SecretProviderName
|
|
2663
2885
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2664
|
-
secrets:
|
|
2886
|
+
secrets: list[str] = None,
|
|
2665
2887
|
) -> mlrun.common.schemas.SecretsData:
|
|
2666
2888
|
"""Retrieve project-context secrets from Vault.
|
|
2667
2889
|
|
|
@@ -2750,7 +2972,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2750
2972
|
provider: Union[
|
|
2751
2973
|
str, mlrun.common.schemas.SecretProviderName
|
|
2752
2974
|
] = mlrun.common.schemas.SecretProviderName.kubernetes,
|
|
2753
|
-
secrets:
|
|
2975
|
+
secrets: list[str] = None,
|
|
2754
2976
|
):
|
|
2755
2977
|
"""Delete project-context secrets from Kubernetes.
|
|
2756
2978
|
|
|
@@ -2907,13 +3129,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2907
3129
|
project: str,
|
|
2908
3130
|
model: Optional[str] = None,
|
|
2909
3131
|
function: Optional[str] = None,
|
|
2910
|
-
labels:
|
|
3132
|
+
labels: list[str] = None,
|
|
2911
3133
|
start: str = "now-1h",
|
|
2912
3134
|
end: str = "now",
|
|
2913
|
-
metrics: Optional[
|
|
3135
|
+
metrics: Optional[list[str]] = None,
|
|
2914
3136
|
top_level: bool = False,
|
|
2915
|
-
uids: Optional[
|
|
2916
|
-
) ->
|
|
3137
|
+
uids: Optional[list[str]] = None,
|
|
3138
|
+
) -> list[mlrun.model_monitoring.model_endpoint.ModelEndpoint]:
|
|
2917
3139
|
"""
|
|
2918
3140
|
Returns a list of `ModelEndpoint` objects. Each `ModelEndpoint` object represents the current state of a
|
|
2919
3141
|
model endpoint. This functions supports filtering by the following parameters:
|
|
@@ -2934,14 +3156,12 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2934
3156
|
:param labels: A list of labels to filter by. Label filters work by either filtering a specific value of a
|
|
2935
3157
|
label (i.e. list("key=value")) or by looking for the existence of a given key (i.e. "key")
|
|
2936
3158
|
:param metrics: A list of metrics to return for each endpoint, read more in 'TimeMetric'
|
|
2937
|
-
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours, and `'d'` =
|
|
2944
|
-
days), or 0 for the earliest time.
|
|
3159
|
+
:param start: The start time of the metrics. Can be represented by a string containing an RFC 3339 time, a
|
|
3160
|
+
Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
|
|
3161
|
+
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3162
|
+
:param end: The end time of the metrics. Can be represented by a string containing an RFC 3339 time, a
|
|
3163
|
+
Unix timestamp in milliseconds, a relative time (`'now'` or `'now-[0-9]+[mhd]'`, where
|
|
3164
|
+
`m` = minutes, `h` = hours, `'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
2945
3165
|
:param top_level: if true will return only routers and endpoint that are NOT children of any router
|
|
2946
3166
|
:param uids: if passed will return a list `ModelEndpoint` object with uid in uids
|
|
2947
3167
|
"""
|
|
@@ -2981,7 +3201,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2981
3201
|
endpoint_id: str,
|
|
2982
3202
|
start: Optional[str] = None,
|
|
2983
3203
|
end: Optional[str] = None,
|
|
2984
|
-
metrics: Optional[
|
|
3204
|
+
metrics: Optional[list[str]] = None,
|
|
2985
3205
|
feature_analysis: bool = False,
|
|
2986
3206
|
) -> mlrun.model_monitoring.model_endpoint.ModelEndpoint:
|
|
2987
3207
|
"""
|
|
@@ -2990,13 +3210,13 @@ class HTTPRunDB(RunDBInterface):
|
|
|
2990
3210
|
:param project: The name of the project
|
|
2991
3211
|
:param endpoint_id: The unique id of the model endpoint.
|
|
2992
3212
|
:param start: The start time of the metrics. Can be represented by a string containing an
|
|
2993
|
-
RFC 3339 time, a
|
|
2994
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
2995
|
-
0 for the earliest time.
|
|
3213
|
+
RFC 3339 time, a Unix timestamp in milliseconds, a relative time
|
|
3214
|
+
(`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
3215
|
+
`'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
2996
3216
|
:param end: The end time of the metrics. Can be represented by a string containing an
|
|
2997
|
-
RFC 3339 time, a
|
|
2998
|
-
`'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
2999
|
-
0 for the earliest time.
|
|
3217
|
+
RFC 3339 time, a Unix timestamp in milliseconds, a relative time
|
|
3218
|
+
(`'now'` or `'now-[0-9]+[mhd]'`, where `m` = minutes, `h` = hours,
|
|
3219
|
+
`'d'` = days, and `'s'` = seconds), or 0 for the earliest time.
|
|
3000
3220
|
:param metrics: A list of metrics to return for the model endpoint. There are pre-defined
|
|
3001
3221
|
metrics for model endpoints such as predictions_per_second and
|
|
3002
3222
|
latency_avg_5m but also custom metrics defined by the user. Please note that
|
|
@@ -3066,65 +3286,77 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3066
3286
|
params=attributes,
|
|
3067
3287
|
)
|
|
3068
3288
|
|
|
3069
|
-
def
|
|
3289
|
+
def update_model_monitoring_controller(
|
|
3070
3290
|
self,
|
|
3071
|
-
project: str
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
):
|
|
3291
|
+
project: str,
|
|
3292
|
+
base_period: int = 10,
|
|
3293
|
+
image: str = "mlrun/mlrun",
|
|
3294
|
+
) -> None:
|
|
3075
3295
|
"""
|
|
3076
|
-
|
|
3077
|
-
To submit a scheduled job as well, please set with_schedule = True.
|
|
3296
|
+
Redeploy model monitoring application controller function.
|
|
3078
3297
|
|
|
3079
|
-
:param project:
|
|
3080
|
-
:param
|
|
3081
|
-
|
|
3082
|
-
:param
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
:returns: model monitoring batch job as a dictionary. You can easily convert the returned function into a
|
|
3086
|
-
runtime object by calling ~mlrun.new_function.
|
|
3298
|
+
:param project: Project name.
|
|
3299
|
+
:param base_period: The time period in minutes in which the model monitoring controller function
|
|
3300
|
+
triggers. By default, the base period is 10 minutes.
|
|
3301
|
+
:param image: The image of the model monitoring controller function.
|
|
3302
|
+
By default, the image is mlrun/mlrun.
|
|
3087
3303
|
"""
|
|
3304
|
+
self.api_call(
|
|
3305
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3306
|
+
path=f"projects/{project}/model-monitoring/model-monitoring-controller",
|
|
3307
|
+
params={
|
|
3308
|
+
"base_period": base_period,
|
|
3309
|
+
"image": image,
|
|
3310
|
+
},
|
|
3311
|
+
)
|
|
3088
3312
|
|
|
3089
|
-
|
|
3090
|
-
"default_batch_image": default_batch_image,
|
|
3091
|
-
"with_schedule": with_schedule,
|
|
3092
|
-
}
|
|
3093
|
-
path = f"projects/{project}/jobs/batch-monitoring"
|
|
3094
|
-
|
|
3095
|
-
resp = self.api_call(method="POST", path=path, params=params)
|
|
3096
|
-
return resp.json()["func"]
|
|
3097
|
-
|
|
3098
|
-
def create_model_monitoring_controller(
|
|
3313
|
+
def enable_model_monitoring(
|
|
3099
3314
|
self,
|
|
3100
|
-
project: str
|
|
3101
|
-
default_controller_image: str = "mlrun/mlrun",
|
|
3315
|
+
project: str,
|
|
3102
3316
|
base_period: int = 10,
|
|
3103
|
-
|
|
3317
|
+
image: str = "mlrun/mlrun",
|
|
3318
|
+
deploy_histogram_data_drift_app: bool = True,
|
|
3319
|
+
) -> None:
|
|
3320
|
+
"""
|
|
3321
|
+
Deploy model monitoring application controller, writer and stream functions.
|
|
3322
|
+
While the main goal of the controller function is to handle the monitoring processing and triggering
|
|
3323
|
+
applications, the goal of the model monitoring writer function is to write all the monitoring
|
|
3324
|
+
application results to the databases.
|
|
3325
|
+
The stream function goal is to monitor the log of the data stream. It is triggered when a new log entry
|
|
3326
|
+
is detected. It processes the new events into statistics that are then written to statistics databases.
|
|
3327
|
+
|
|
3328
|
+
:param project: Project name.
|
|
3329
|
+
:param base_period: The time period in minutes in which the model monitoring controller function
|
|
3330
|
+
triggers. By default, the base period is 10 minutes.
|
|
3331
|
+
:param image: The image of the model monitoring controller, writer & monitoring
|
|
3332
|
+
stream functions, which are real time nuclio functions.
|
|
3333
|
+
By default, the image is mlrun/mlrun.
|
|
3334
|
+
:param deploy_histogram_data_drift_app: If true, deploy the default histogram-based data drift application.
|
|
3104
3335
|
"""
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3336
|
+
self.api_call(
|
|
3337
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3338
|
+
path=f"projects/{project}/model-monitoring/enable-model-monitoring",
|
|
3339
|
+
params={
|
|
3340
|
+
"base_period": base_period,
|
|
3341
|
+
"image": image,
|
|
3342
|
+
"deploy_histogram_data_drift_app": deploy_histogram_data_drift_app,
|
|
3343
|
+
},
|
|
3344
|
+
)
|
|
3109
3345
|
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
image. By default, the image is mlrun/mlrun.
|
|
3114
|
-
:param base_period: Minutes to determine the frequency in which the model monitoring controller job
|
|
3115
|
-
is running. By default, the base period is 5 minutes.
|
|
3116
|
-
:returns: model monitoring controller job as a dictionary. You can easily convert the returned function into a
|
|
3117
|
-
runtime object by calling ~mlrun.new_function.
|
|
3346
|
+
def deploy_histogram_data_drift_app(
|
|
3347
|
+
self, project: str, image: str = "mlrun/mlrun"
|
|
3348
|
+
) -> None:
|
|
3118
3349
|
"""
|
|
3350
|
+
Deploy the histogram data drift application.
|
|
3119
3351
|
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3352
|
+
:param project: Project name.
|
|
3353
|
+
:param image: The image on which the application will run.
|
|
3354
|
+
"""
|
|
3355
|
+
self.api_call(
|
|
3356
|
+
method=mlrun.common.types.HTTPMethod.POST,
|
|
3357
|
+
path=f"projects/{project}/model-monitoring/deploy-histogram-data-drift-app",
|
|
3358
|
+
params={"image": image},
|
|
3359
|
+
)
|
|
3128
3360
|
|
|
3129
3361
|
def create_hub_source(
|
|
3130
3362
|
self, source: Union[dict, mlrun.common.schemas.IndexedHubSource]
|
|
@@ -3155,8 +3387,10 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3155
3387
|
metadata=mlrun.common.schemas.HubObjectMetadata(
|
|
3156
3388
|
name="priv", description="a private source"
|
|
3157
3389
|
),
|
|
3158
|
-
spec=mlrun.common.schemas.HubSourceSpec(
|
|
3159
|
-
|
|
3390
|
+
spec=mlrun.common.schemas.HubSourceSpec(
|
|
3391
|
+
path="/local/path/to/source", channel="development"
|
|
3392
|
+
),
|
|
3393
|
+
),
|
|
3160
3394
|
)
|
|
3161
3395
|
db.create_hub_source(private_source)
|
|
3162
3396
|
|
|
@@ -3170,9 +3404,9 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3170
3404
|
spec=mlrun.common.schemas.HubSourceSpec(
|
|
3171
3405
|
path="/local/path/to/source/2",
|
|
3172
3406
|
channel="development",
|
|
3173
|
-
credentials={...}
|
|
3174
|
-
)
|
|
3175
|
-
)
|
|
3407
|
+
credentials={...},
|
|
3408
|
+
),
|
|
3409
|
+
),
|
|
3176
3410
|
)
|
|
3177
3411
|
db.create_hub_source(another_source)
|
|
3178
3412
|
|
|
@@ -3214,7 +3448,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3214
3448
|
item_name: Optional[str] = None,
|
|
3215
3449
|
tag: Optional[str] = None,
|
|
3216
3450
|
version: Optional[str] = None,
|
|
3217
|
-
) ->
|
|
3451
|
+
) -> list[mlrun.common.schemas.hub.IndexedHubSource]:
|
|
3218
3452
|
"""
|
|
3219
3453
|
List hub sources in the MLRun DB.
|
|
3220
3454
|
|
|
@@ -3364,20 +3598,72 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3364
3598
|
body=dict_to_json(authorization_verification_input.dict()),
|
|
3365
3599
|
)
|
|
3366
3600
|
|
|
3367
|
-
def list_api_gateways(self, project=None):
|
|
3601
|
+
def list_api_gateways(self, project=None) -> mlrun.common.schemas.APIGatewaysOutput:
|
|
3368
3602
|
"""
|
|
3369
3603
|
Returns a list of Nuclio api gateways
|
|
3370
|
-
:param project: optional str parameter to filter by project, if not passed, default
|
|
3604
|
+
:param project: optional str parameter to filter by project, if not passed, default project value is taken
|
|
3371
3605
|
|
|
3372
|
-
:return:
|
|
3373
|
-
(json example is here
|
|
3374
|
-
https://github.com/nuclio/nuclio/blob/development/docs/reference/api/README.md#listing-all-api-gateways)
|
|
3606
|
+
:return: :py:class:`~mlrun.common.schemas.APIGateways`.
|
|
3375
3607
|
"""
|
|
3376
3608
|
project = project or config.default_project
|
|
3377
3609
|
error = "list api gateways"
|
|
3378
|
-
endpoint_path = f"projects/{project}/
|
|
3379
|
-
|
|
3380
|
-
return
|
|
3610
|
+
endpoint_path = f"projects/{project}/api-gateways"
|
|
3611
|
+
response = self.api_call("GET", endpoint_path, error)
|
|
3612
|
+
return mlrun.common.schemas.APIGatewaysOutput(**response.json())
|
|
3613
|
+
|
|
3614
|
+
def get_api_gateway(self, name, project=None) -> mlrun.common.schemas.APIGateway:
|
|
3615
|
+
"""
|
|
3616
|
+
Returns an API gateway
|
|
3617
|
+
:param name: API gateway name
|
|
3618
|
+
:param project: optional str parameter to filter by project, if not passed, default project value is taken
|
|
3619
|
+
|
|
3620
|
+
:return: :py:class:`~mlrun.common.schemas.APIGateway`.
|
|
3621
|
+
"""
|
|
3622
|
+
project = project or config.default_project
|
|
3623
|
+
error = "get api gateway"
|
|
3624
|
+
endpoint_path = f"projects/{project}/api-gateways/{name}"
|
|
3625
|
+
response = self.api_call("GET", endpoint_path, error)
|
|
3626
|
+
return mlrun.common.schemas.APIGateway(**response.json())
|
|
3627
|
+
|
|
3628
|
+
def delete_api_gateway(self, name, project=None):
|
|
3629
|
+
"""
|
|
3630
|
+
Deletes an API gateway
|
|
3631
|
+
:param name: API gateway name
|
|
3632
|
+
:param project: Project name
|
|
3633
|
+
"""
|
|
3634
|
+
project = project or config.default_project
|
|
3635
|
+
error = "delete api gateway"
|
|
3636
|
+
endpoint_path = f"projects/{project}/api-gateways/{name}"
|
|
3637
|
+
self.api_call("DELETE", endpoint_path, error)
|
|
3638
|
+
|
|
3639
|
+
def store_api_gateway(
|
|
3640
|
+
self,
|
|
3641
|
+
api_gateway: Union[
|
|
3642
|
+
mlrun.common.schemas.APIGateway,
|
|
3643
|
+
mlrun.runtimes.nuclio.api_gateway.APIGateway,
|
|
3644
|
+
],
|
|
3645
|
+
project: Optional[str] = None,
|
|
3646
|
+
) -> mlrun.common.schemas.APIGateway:
|
|
3647
|
+
"""
|
|
3648
|
+
Stores an API Gateway.
|
|
3649
|
+
:param api_gateway :py:class:`~mlrun.runtimes.nuclio.APIGateway`
|
|
3650
|
+
or :py:class:`~mlrun.common.schemas.APIGateway`: API Gateway entity.
|
|
3651
|
+
:param project: project name. Mandatory if api_gateway is mlrun.common.schemas.APIGateway.
|
|
3652
|
+
|
|
3653
|
+
:return: :py:class:`~mlrun.common.schemas.APIGateway`.
|
|
3654
|
+
"""
|
|
3655
|
+
|
|
3656
|
+
if isinstance(api_gateway, mlrun.runtimes.nuclio.api_gateway.APIGateway):
|
|
3657
|
+
api_gateway = api_gateway.to_scheme()
|
|
3658
|
+
endpoint_path = f"projects/{project}/api-gateways/{api_gateway.metadata.name}"
|
|
3659
|
+
error = "store api gateways"
|
|
3660
|
+
response = self.api_call(
|
|
3661
|
+
"PUT",
|
|
3662
|
+
endpoint_path,
|
|
3663
|
+
error,
|
|
3664
|
+
json=api_gateway.dict(exclude_none=True),
|
|
3665
|
+
)
|
|
3666
|
+
return mlrun.common.schemas.APIGateway(**response.json())
|
|
3381
3667
|
|
|
3382
3668
|
def trigger_migrations(self) -> Optional[mlrun.common.schemas.BackgroundTask]:
|
|
3383
3669
|
"""Trigger migrations (will do nothing if no migrations are needed) and wait for them to finish if actually
|
|
@@ -3400,7 +3686,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3400
3686
|
self,
|
|
3401
3687
|
project: str,
|
|
3402
3688
|
run_uid: str,
|
|
3403
|
-
notifications:
|
|
3689
|
+
notifications: list[mlrun.model.Notification] = None,
|
|
3404
3690
|
):
|
|
3405
3691
|
"""
|
|
3406
3692
|
Set notifications on a run. This will override any existing notifications on the run.
|
|
@@ -3425,7 +3711,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3425
3711
|
self,
|
|
3426
3712
|
project: str,
|
|
3427
3713
|
schedule_name: str,
|
|
3428
|
-
notifications:
|
|
3714
|
+
notifications: list[mlrun.model.Notification] = None,
|
|
3429
3715
|
):
|
|
3430
3716
|
"""
|
|
3431
3717
|
Set notifications on a schedule. This will override any existing notifications on the schedule.
|
|
@@ -3448,7 +3734,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3448
3734
|
|
|
3449
3735
|
def store_run_notifications(
|
|
3450
3736
|
self,
|
|
3451
|
-
notification_objects:
|
|
3737
|
+
notification_objects: list[mlrun.model.Notification],
|
|
3452
3738
|
run_uid: str,
|
|
3453
3739
|
project: str = None,
|
|
3454
3740
|
mask_params: bool = True,
|
|
@@ -3460,6 +3746,16 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3460
3746
|
"""
|
|
3461
3747
|
pass
|
|
3462
3748
|
|
|
3749
|
+
def store_alert_notifications(
|
|
3750
|
+
self,
|
|
3751
|
+
session,
|
|
3752
|
+
notification_objects: list[mlrun.model.Notification],
|
|
3753
|
+
alert_id: str,
|
|
3754
|
+
project: str,
|
|
3755
|
+
mask_params: bool = True,
|
|
3756
|
+
):
|
|
3757
|
+
pass
|
|
3758
|
+
|
|
3463
3759
|
def submit_workflow(
|
|
3464
3760
|
self,
|
|
3465
3761
|
project: str,
|
|
@@ -3469,7 +3765,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3469
3765
|
mlrun.common.schemas.WorkflowSpec,
|
|
3470
3766
|
dict,
|
|
3471
3767
|
],
|
|
3472
|
-
arguments: Optional[
|
|
3768
|
+
arguments: Optional[dict] = None,
|
|
3473
3769
|
artifact_path: Optional[str] = None,
|
|
3474
3770
|
source: Optional[str] = None,
|
|
3475
3771
|
run_name: Optional[str] = None,
|
|
@@ -3562,7 +3858,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3562
3858
|
self,
|
|
3563
3859
|
name: str,
|
|
3564
3860
|
url: str,
|
|
3565
|
-
secrets: Optional[
|
|
3861
|
+
secrets: Optional[dict] = None,
|
|
3566
3862
|
save_secrets: bool = True,
|
|
3567
3863
|
) -> str:
|
|
3568
3864
|
"""
|
|
@@ -3625,7 +3921,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3625
3921
|
|
|
3626
3922
|
def list_datastore_profiles(
|
|
3627
3923
|
self, project: str
|
|
3628
|
-
) ->
|
|
3924
|
+
) -> list[mlrun.common.schemas.DatastoreProfile]:
|
|
3629
3925
|
project = project or config.default_project
|
|
3630
3926
|
_path = self._path_of("datastore-profiles", project)
|
|
3631
3927
|
|
|
@@ -3651,6 +3947,145 @@ class HTTPRunDB(RunDBInterface):
|
|
|
3651
3947
|
|
|
3652
3948
|
self.api_call(method="PUT", path=_path, json=profile.dict())
|
|
3653
3949
|
|
|
3950
|
+
@staticmethod
|
|
3951
|
+
def warn_on_s3_and_ecr_permissions_conflict(func):
|
|
3952
|
+
is_s3_source = func.spec.build.source and func.spec.build.source.startswith(
|
|
3953
|
+
"s3://"
|
|
3954
|
+
)
|
|
3955
|
+
is_ecr_image = mlrun.utils.is_ecr_url(config.httpdb.builder.docker_registry)
|
|
3956
|
+
if not func.spec.build.load_source_on_run and is_s3_source and is_ecr_image:
|
|
3957
|
+
logger.warning(
|
|
3958
|
+
"Building a function image to ECR and loading an S3 source to the image may require conflicting access "
|
|
3959
|
+
"keys. Only the permissions granted to the platform's configured secret will take affect "
|
|
3960
|
+
"(see mlrun.mlconf.httpdb.builder.docker_registry_secret). "
|
|
3961
|
+
"In case the permissions are limited to ECR scope, you may use pull_at_runtime=True instead",
|
|
3962
|
+
source=func.spec.build.source,
|
|
3963
|
+
load_source_on_run=func.spec.build.load_source_on_run,
|
|
3964
|
+
default_docker_registry=config.httpdb.builder.docker_registry,
|
|
3965
|
+
)
|
|
3966
|
+
|
|
3967
|
+
def generate_event(
|
|
3968
|
+
self, name: str, event_data: Union[dict, mlrun.common.schemas.Event], project=""
|
|
3969
|
+
):
|
|
3970
|
+
"""
|
|
3971
|
+
Generate an event.
|
|
3972
|
+
:param name: The name of the event.
|
|
3973
|
+
:param event_data: The data of the event.
|
|
3974
|
+
:param project: The project that the event belongs to.
|
|
3975
|
+
"""
|
|
3976
|
+
project = project or config.default_project
|
|
3977
|
+
endpoint_path = f"projects/{project}/events/{name}"
|
|
3978
|
+
error_message = f"post event {project}/events/{name}"
|
|
3979
|
+
if isinstance(event_data, mlrun.common.schemas.Event):
|
|
3980
|
+
event_data = event_data.dict()
|
|
3981
|
+
self.api_call(
|
|
3982
|
+
"POST", endpoint_path, error_message, body=dict_to_json(event_data)
|
|
3983
|
+
)
|
|
3984
|
+
|
|
3985
|
+
def store_alert_config(
|
|
3986
|
+
self,
|
|
3987
|
+
alert_name: str,
|
|
3988
|
+
alert_data: Union[dict, AlertConfig],
|
|
3989
|
+
project="",
|
|
3990
|
+
) -> AlertConfig:
|
|
3991
|
+
"""
|
|
3992
|
+
Create/modify an alert.
|
|
3993
|
+
:param alert_name: The name of the alert.
|
|
3994
|
+
:param alert_data: The data of the alert.
|
|
3995
|
+
:param project: the project that the alert belongs to.
|
|
3996
|
+
:return: The created/modified alert.
|
|
3997
|
+
"""
|
|
3998
|
+
project = project or config.default_project
|
|
3999
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}"
|
|
4000
|
+
error_message = f"put alert {project}/alerts/{alert_name}"
|
|
4001
|
+
alert_instance = (
|
|
4002
|
+
alert_data
|
|
4003
|
+
if isinstance(alert_data, AlertConfig)
|
|
4004
|
+
else AlertConfig.from_dict(alert_data)
|
|
4005
|
+
)
|
|
4006
|
+
alert_instance.validate_required_fields()
|
|
4007
|
+
|
|
4008
|
+
alert_data = alert_instance.to_dict()
|
|
4009
|
+
body = _as_json(alert_data)
|
|
4010
|
+
response = self.api_call("PUT", endpoint_path, error_message, body=body)
|
|
4011
|
+
return AlertConfig.from_dict(response.json())
|
|
4012
|
+
|
|
4013
|
+
def get_alert_config(self, alert_name: str, project="") -> AlertConfig:
|
|
4014
|
+
"""
|
|
4015
|
+
Retrieve an alert.
|
|
4016
|
+
:param alert_name: The name of the alert to retrieve.
|
|
4017
|
+
:param project: The project that the alert belongs to.
|
|
4018
|
+
:return: The alert object.
|
|
4019
|
+
"""
|
|
4020
|
+
project = project or config.default_project
|
|
4021
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}"
|
|
4022
|
+
error_message = f"get alert {project}/alerts/{alert_name}"
|
|
4023
|
+
response = self.api_call("GET", endpoint_path, error_message)
|
|
4024
|
+
return AlertConfig.from_dict(response.json())
|
|
4025
|
+
|
|
4026
|
+
def list_alerts_configs(self, project="") -> list[AlertConfig]:
|
|
4027
|
+
"""
|
|
4028
|
+
Retrieve list of alerts of a project.
|
|
4029
|
+
:param project: The project name.
|
|
4030
|
+
:return: All the alerts objects of the project.
|
|
4031
|
+
"""
|
|
4032
|
+
project = project or config.default_project
|
|
4033
|
+
endpoint_path = f"projects/{project}/alerts"
|
|
4034
|
+
error_message = f"get alerts {project}/alerts"
|
|
4035
|
+
response = self.api_call("GET", endpoint_path, error_message).json()
|
|
4036
|
+
results = []
|
|
4037
|
+
for item in response:
|
|
4038
|
+
results.append(AlertConfig(**item))
|
|
4039
|
+
return results
|
|
4040
|
+
|
|
4041
|
+
def delete_alert_config(self, alert_name: str, project=""):
|
|
4042
|
+
"""
|
|
4043
|
+
Delete an alert.
|
|
4044
|
+
:param alert_name: The name of the alert to delete.
|
|
4045
|
+
:param project: The project that the alert belongs to.
|
|
4046
|
+
"""
|
|
4047
|
+
project = project or config.default_project
|
|
4048
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}"
|
|
4049
|
+
error_message = f"delete alert {project}/alerts/{alert_name}"
|
|
4050
|
+
self.api_call("DELETE", endpoint_path, error_message)
|
|
4051
|
+
|
|
4052
|
+
def reset_alert_config(self, alert_name: str, project=""):
|
|
4053
|
+
"""
|
|
4054
|
+
Reset an alert.
|
|
4055
|
+
:param alert_name: The name of the alert to reset.
|
|
4056
|
+
:param project: The project that the alert belongs to.
|
|
4057
|
+
"""
|
|
4058
|
+
project = project or config.default_project
|
|
4059
|
+
endpoint_path = f"projects/{project}/alerts/{alert_name}/reset"
|
|
4060
|
+
error_message = f"post alert {project}/alerts/{alert_name}/reset"
|
|
4061
|
+
self.api_call("POST", endpoint_path, error_message)
|
|
4062
|
+
|
|
4063
|
+
def get_alert_template(
|
|
4064
|
+
self, template_name: str
|
|
4065
|
+
) -> mlrun.common.schemas.AlertTemplate:
|
|
4066
|
+
"""
|
|
4067
|
+
Retrieve a specific alert template.
|
|
4068
|
+
:param template_name: The name of the template to retrieve.
|
|
4069
|
+
:return: The template object.
|
|
4070
|
+
"""
|
|
4071
|
+
endpoint_path = f"alert-templates/{template_name}"
|
|
4072
|
+
error_message = f"get template alert-templates/{template_name}"
|
|
4073
|
+
response = self.api_call("GET", endpoint_path, error_message)
|
|
4074
|
+
return mlrun.common.schemas.AlertTemplate(**response.json())
|
|
4075
|
+
|
|
4076
|
+
def list_alert_templates(self) -> list[mlrun.common.schemas.AlertTemplate]:
|
|
4077
|
+
"""
|
|
4078
|
+
Retrieve list of all alert templates.
|
|
4079
|
+
:return: All the alert template objects in the database.
|
|
4080
|
+
"""
|
|
4081
|
+
endpoint_path = "alert-templates"
|
|
4082
|
+
error_message = "get templates /alert-templates"
|
|
4083
|
+
response = self.api_call("GET", endpoint_path, error_message).json()
|
|
4084
|
+
results = []
|
|
4085
|
+
for item in response:
|
|
4086
|
+
results.append(mlrun.common.schemas.AlertTemplate(**item))
|
|
4087
|
+
return results
|
|
4088
|
+
|
|
3654
4089
|
|
|
3655
4090
|
def _as_json(obj):
|
|
3656
4091
|
fn = getattr(obj, "to_json", None)
|