mlrun 1.7.0rc22__py3-none-any.whl → 1.7.0rc28__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/__main__.py +10 -8
- mlrun/alerts/alert.py +13 -1
- mlrun/artifacts/manager.py +5 -0
- mlrun/common/constants.py +2 -2
- mlrun/common/formatters/__init__.py +1 -0
- mlrun/common/formatters/artifact.py +26 -3
- mlrun/common/formatters/base.py +9 -9
- mlrun/common/formatters/run.py +26 -0
- mlrun/common/helpers.py +11 -0
- mlrun/common/schemas/__init__.py +4 -0
- mlrun/common/schemas/alert.py +5 -9
- mlrun/common/schemas/api_gateway.py +64 -16
- mlrun/common/schemas/artifact.py +11 -0
- mlrun/common/schemas/constants.py +3 -0
- mlrun/common/schemas/feature_store.py +58 -28
- mlrun/common/schemas/model_monitoring/constants.py +21 -12
- mlrun/common/schemas/model_monitoring/model_endpoints.py +0 -12
- mlrun/common/schemas/pipeline.py +16 -0
- mlrun/common/schemas/project.py +17 -0
- mlrun/common/schemas/runs.py +17 -0
- mlrun/common/schemas/schedule.py +1 -1
- mlrun/common/types.py +5 -0
- mlrun/config.py +10 -25
- mlrun/datastore/azure_blob.py +2 -1
- mlrun/datastore/datastore.py +3 -3
- mlrun/datastore/google_cloud_storage.py +6 -2
- mlrun/datastore/snowflake_utils.py +3 -1
- mlrun/datastore/sources.py +26 -11
- mlrun/datastore/store_resources.py +2 -0
- mlrun/datastore/targets.py +68 -16
- mlrun/db/base.py +64 -2
- mlrun/db/httpdb.py +129 -41
- mlrun/db/nopdb.py +44 -3
- mlrun/errors.py +5 -3
- mlrun/execution.py +18 -10
- mlrun/feature_store/retrieval/spark_merger.py +2 -1
- mlrun/frameworks/__init__.py +0 -6
- mlrun/model.py +23 -0
- mlrun/model_monitoring/api.py +6 -52
- mlrun/model_monitoring/applications/histogram_data_drift.py +1 -1
- mlrun/model_monitoring/db/stores/__init__.py +37 -24
- mlrun/model_monitoring/db/stores/base/store.py +40 -1
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +42 -87
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +27 -35
- mlrun/model_monitoring/db/tsdb/__init__.py +15 -15
- mlrun/model_monitoring/db/tsdb/base.py +1 -1
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +6 -4
- mlrun/model_monitoring/helpers.py +17 -9
- mlrun/model_monitoring/stream_processing.py +9 -11
- mlrun/model_monitoring/writer.py +11 -11
- mlrun/package/__init__.py +1 -13
- mlrun/package/packagers/__init__.py +1 -6
- mlrun/projects/pipelines.py +10 -9
- mlrun/projects/project.py +95 -81
- mlrun/render.py +10 -5
- mlrun/run.py +13 -8
- mlrun/runtimes/base.py +11 -4
- mlrun/runtimes/daskjob.py +7 -1
- mlrun/runtimes/local.py +16 -3
- mlrun/runtimes/nuclio/application/application.py +0 -2
- mlrun/runtimes/nuclio/function.py +20 -0
- mlrun/runtimes/nuclio/serving.py +9 -6
- mlrun/runtimes/pod.py +5 -29
- mlrun/serving/routers.py +75 -59
- mlrun/serving/server.py +11 -0
- mlrun/serving/states.py +29 -0
- mlrun/serving/v2_serving.py +62 -39
- mlrun/utils/helpers.py +39 -1
- mlrun/utils/logger.py +36 -2
- mlrun/utils/notifications/notification/base.py +43 -7
- mlrun/utils/notifications/notification/git.py +21 -0
- mlrun/utils/notifications/notification/slack.py +9 -14
- mlrun/utils/notifications/notification/webhook.py +41 -1
- mlrun/utils/notifications/notification_pusher.py +3 -9
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc22.dist-info → mlrun-1.7.0rc28.dist-info}/METADATA +12 -7
- {mlrun-1.7.0rc22.dist-info → mlrun-1.7.0rc28.dist-info}/RECORD +81 -80
- {mlrun-1.7.0rc22.dist-info → mlrun-1.7.0rc28.dist-info}/WHEEL +1 -1
- {mlrun-1.7.0rc22.dist-info → mlrun-1.7.0rc28.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc22.dist-info → mlrun-1.7.0rc28.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc22.dist-info → mlrun-1.7.0rc28.dist-info}/top_level.txt +0 -0
|
@@ -66,10 +66,6 @@ class EventStreamProcessor:
|
|
|
66
66
|
self.parquet_batching_max_events = parquet_batching_max_events
|
|
67
67
|
self.parquet_batching_timeout_secs = parquet_batching_timeout_secs
|
|
68
68
|
|
|
69
|
-
self.model_endpoint_store_target = (
|
|
70
|
-
mlrun.mlconf.model_endpoint_monitoring.store_type
|
|
71
|
-
)
|
|
72
|
-
|
|
73
69
|
logger.info(
|
|
74
70
|
"Initializing model monitoring event stream processor",
|
|
75
71
|
parquet_path=self.parquet_path,
|
|
@@ -139,7 +135,7 @@ class EventStreamProcessor:
|
|
|
139
135
|
def apply_monitoring_serving_graph(
|
|
140
136
|
self,
|
|
141
137
|
fn: mlrun.runtimes.ServingRuntime,
|
|
142
|
-
|
|
138
|
+
secret_provider: typing.Optional[typing.Callable[[str], str]] = None,
|
|
143
139
|
) -> None:
|
|
144
140
|
"""
|
|
145
141
|
Apply monitoring serving graph to a given serving function. The following serving graph includes about 4 main
|
|
@@ -167,7 +163,8 @@ class EventStreamProcessor:
|
|
|
167
163
|
using CE, the parquet target path is based on the defined MLRun artifact path.
|
|
168
164
|
|
|
169
165
|
:param fn: A serving function.
|
|
170
|
-
:param
|
|
166
|
+
:param secret_provider: An optional callable function that provides the connection string from the project
|
|
167
|
+
secret.
|
|
171
168
|
"""
|
|
172
169
|
|
|
173
170
|
graph = typing.cast(
|
|
@@ -293,7 +290,6 @@ class EventStreamProcessor:
|
|
|
293
290
|
name="UpdateEndpoint",
|
|
294
291
|
after="ProcessBeforeEndpointUpdate",
|
|
295
292
|
project=self.project,
|
|
296
|
-
model_endpoint_store_target=self.model_endpoint_store_target,
|
|
297
293
|
)
|
|
298
294
|
|
|
299
295
|
apply_update_endpoint()
|
|
@@ -310,7 +306,10 @@ class EventStreamProcessor:
|
|
|
310
306
|
table=self.kv_path,
|
|
311
307
|
)
|
|
312
308
|
|
|
313
|
-
|
|
309
|
+
store_object = mlrun.model_monitoring.get_store_object(
|
|
310
|
+
project=self.project, secret_provider=secret_provider
|
|
311
|
+
)
|
|
312
|
+
if store_object.type == ModelEndpointTarget.V3IO_NOSQL:
|
|
314
313
|
apply_infer_schema()
|
|
315
314
|
|
|
316
315
|
# Emits the event in window size of events based on sample_window size (10 by default)
|
|
@@ -328,7 +327,7 @@ class EventStreamProcessor:
|
|
|
328
327
|
# TSDB branch (skip to Prometheus if in CE env)
|
|
329
328
|
if not mlrun.mlconf.is_ce_mode():
|
|
330
329
|
tsdb_connector = mlrun.model_monitoring.get_tsdb_connector(
|
|
331
|
-
project=self.project, secret_provider=
|
|
330
|
+
project=self.project, secret_provider=secret_provider
|
|
332
331
|
)
|
|
333
332
|
tsdb_connector.apply_monitoring_stream_steps(graph=graph)
|
|
334
333
|
|
|
@@ -904,7 +903,7 @@ class MapFeatureNames(mlrun.feature_store.steps.MapClass):
|
|
|
904
903
|
|
|
905
904
|
|
|
906
905
|
class UpdateEndpoint(mlrun.feature_store.steps.MapClass):
|
|
907
|
-
def __init__(self, project: str,
|
|
906
|
+
def __init__(self, project: str, **kwargs):
|
|
908
907
|
"""
|
|
909
908
|
Update the model endpoint record in the DB. Note that the event at this point includes metadata and stats about
|
|
910
909
|
the average latency and the amount of predictions over time. This data will be used in the monitoring dashboards
|
|
@@ -914,7 +913,6 @@ class UpdateEndpoint(mlrun.feature_store.steps.MapClass):
|
|
|
914
913
|
"""
|
|
915
914
|
super().__init__(**kwargs)
|
|
916
915
|
self.project = project
|
|
917
|
-
self.model_endpoint_store_target = model_endpoint_store_target
|
|
918
916
|
|
|
919
917
|
def do(self, event: dict):
|
|
920
918
|
# Remove labels from the event
|
mlrun/model_monitoring/writer.py
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
import json
|
|
16
|
-
from typing import Any, NewType
|
|
16
|
+
from typing import Any, Callable, NewType
|
|
17
17
|
|
|
18
18
|
import mlrun.common.model_monitoring
|
|
19
19
|
import mlrun.common.schemas
|
|
@@ -30,7 +30,7 @@ from mlrun.common.schemas.model_monitoring.constants import (
|
|
|
30
30
|
WriterEventKind,
|
|
31
31
|
)
|
|
32
32
|
from mlrun.common.schemas.notification import NotificationKind, NotificationSeverity
|
|
33
|
-
from mlrun.model_monitoring.helpers import
|
|
33
|
+
from mlrun.model_monitoring.helpers import get_result_instance_fqn
|
|
34
34
|
from mlrun.serving.utils import StepToDict
|
|
35
35
|
from mlrun.utils import logger
|
|
36
36
|
from mlrun.utils.notifications.notification_pusher import CustomNotificationPusher
|
|
@@ -102,7 +102,11 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
102
102
|
|
|
103
103
|
kind = "monitoring_application_stream_pusher"
|
|
104
104
|
|
|
105
|
-
def __init__(
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
project: str,
|
|
108
|
+
secret_provider: Callable = None,
|
|
109
|
+
) -> None:
|
|
106
110
|
self.project = project
|
|
107
111
|
self.name = project # required for the deployment process
|
|
108
112
|
|
|
@@ -111,10 +115,10 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
111
115
|
)
|
|
112
116
|
|
|
113
117
|
self._app_result_store = mlrun.model_monitoring.get_store_object(
|
|
114
|
-
project=self.project
|
|
118
|
+
project=self.project, secret_provider=secret_provider
|
|
115
119
|
)
|
|
116
120
|
self._tsdb_connector = mlrun.model_monitoring.get_tsdb_connector(
|
|
117
|
-
project=self.project, secret_provider=
|
|
121
|
+
project=self.project, secret_provider=secret_provider
|
|
118
122
|
)
|
|
119
123
|
self._endpoints_records = {}
|
|
120
124
|
|
|
@@ -149,11 +153,7 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
149
153
|
result_kind: int, result_status: int
|
|
150
154
|
) -> alert_objects.EventKind:
|
|
151
155
|
"""Generate the required Event Kind format for the alerting system"""
|
|
152
|
-
|
|
153
|
-
# Custom kind is represented as an anomaly detection
|
|
154
|
-
event_kind = "mm_app_anomaly"
|
|
155
|
-
else:
|
|
156
|
-
event_kind = ResultKindApp(value=result_kind).name
|
|
156
|
+
event_kind = ResultKindApp(value=result_kind).name
|
|
157
157
|
|
|
158
158
|
if result_status == ResultStatusApp.detected.value:
|
|
159
159
|
event_kind = f"{event_kind}_detected"
|
|
@@ -223,7 +223,7 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
223
223
|
endpoint_id = event[WriterEvent.ENDPOINT_ID]
|
|
224
224
|
endpoint_record = self._endpoints_records.setdefault(
|
|
225
225
|
endpoint_id,
|
|
226
|
-
|
|
226
|
+
self._app_result_store.get_model_endpoint(endpoint_id=endpoint_id),
|
|
227
227
|
)
|
|
228
228
|
event_value = {
|
|
229
229
|
"app_name": event[WriterEvent.APPLICATION_NAME],
|
mlrun/package/__init__.py
CHANGED
|
@@ -12,19 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
|
-
|
|
16
|
-
MLRun package enables fully-automated experiment and pipeline tracking and reproducibility, and easy passing of
|
|
17
|
-
python objects between remote jobs, while not requiring any form of editing to the actual function original code.
|
|
18
|
-
Simply set the function code in a project and run it, MLRun takes care of the rest.
|
|
19
|
-
|
|
20
|
-
MLRun uses packagers: classes that perform 2 tasks:
|
|
21
|
-
|
|
22
|
-
#. **Parsing inputs** - automatically cast the runtime's inputs (user's input passed to the function via
|
|
23
|
-
the ``inputs`` parameter of the ``run`` method) to the relevant hinted type. (Does not require handling of data items.)
|
|
24
|
-
#. **Logging outputs** - automatically save, log, and upload the function's returned objects by the provided
|
|
25
|
-
log hints (user's input passed to the function via the ``returns`` parameter of the ``run`` method).
|
|
26
|
-
(Does not require handling of files and artifacts.)
|
|
27
|
-
"""
|
|
15
|
+
|
|
28
16
|
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
29
17
|
|
|
30
18
|
import functools
|
|
@@ -12,12 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
|
-
r"""
|
|
16
|
-
MLRun comes with the following list of modules, out of the box. All of the packagers listed here
|
|
17
|
-
use the implementation of :ref:`DefaultPackager <mlrun.package.packagers.default\_packager.DefaultPackager>` and are
|
|
18
|
-
available by default at the start of each run.
|
|
19
|
-
"""
|
|
20
|
-
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
21
15
|
|
|
16
|
+
# flake8: noqa - this is until we take care of the F401 violations with respect to __all__ & sphinx
|
|
22
17
|
from .default_packager import DefaultPackager
|
|
23
18
|
from .numpy_packagers import NumPySupportedFormat
|
mlrun/projects/pipelines.py
CHANGED
|
@@ -22,8 +22,7 @@ import uuid
|
|
|
22
22
|
|
|
23
23
|
import mlrun_pipelines.common.models
|
|
24
24
|
import mlrun_pipelines.patcher
|
|
25
|
-
|
|
26
|
-
from mlrun_pipelines.helpers import new_pipe_metadata
|
|
25
|
+
import mlrun_pipelines.utils
|
|
27
26
|
|
|
28
27
|
import mlrun
|
|
29
28
|
import mlrun.common.runtimes.constants
|
|
@@ -220,9 +219,10 @@ class _PipelineContext:
|
|
|
220
219
|
force_run_local = mlrun.mlconf.force_run_local
|
|
221
220
|
if force_run_local is None or force_run_local == "auto":
|
|
222
221
|
force_run_local = not mlrun.mlconf.is_api_running_on_k8s()
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
if not mlrun.mlconf.kfp_url:
|
|
223
|
+
logger.debug("Kubeflow pipeline URL is not set, running locally")
|
|
225
224
|
force_run_local = True
|
|
225
|
+
|
|
226
226
|
if self.workflow:
|
|
227
227
|
force_run_local = force_run_local or self.workflow.run_local
|
|
228
228
|
|
|
@@ -502,13 +502,14 @@ class _KFPRunner(_PipelineRunner):
|
|
|
502
502
|
functions,
|
|
503
503
|
secrets=project._secrets,
|
|
504
504
|
)
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
conf = new_pipe_metadata(
|
|
508
|
-
artifact_path=artifact_path,
|
|
505
|
+
mlrun_pipelines.utils.compile_pipeline(
|
|
506
|
+
artifact_path=artifact_path or project.spec.artifact_path,
|
|
509
507
|
cleanup_ttl=workflow_spec.cleanup_ttl,
|
|
508
|
+
ops=None,
|
|
509
|
+
pipeline=pipeline,
|
|
510
|
+
pipe_file=target,
|
|
511
|
+
type_check=True,
|
|
510
512
|
)
|
|
511
|
-
compiler.Compiler().compile(pipeline, target, pipeline_conf=conf)
|
|
512
513
|
workflow_spec.clear_tmp()
|
|
513
514
|
pipeline_context.clear()
|
|
514
515
|
|
mlrun/projects/project.py
CHANGED
|
@@ -51,6 +51,7 @@ import mlrun.runtimes.nuclio.api_gateway
|
|
|
51
51
|
import mlrun.runtimes.pod
|
|
52
52
|
import mlrun.runtimes.utils
|
|
53
53
|
import mlrun.serving
|
|
54
|
+
import mlrun.utils
|
|
54
55
|
import mlrun.utils.regex
|
|
55
56
|
from mlrun.alerts.alert import AlertConfig
|
|
56
57
|
from mlrun.common.schemas.alert import AlertTemplate
|
|
@@ -713,7 +714,8 @@ def _project_instance_from_struct(struct, name, allow_cross_project):
|
|
|
713
714
|
name_from_struct = struct.get("metadata", {}).get("name", "")
|
|
714
715
|
if name and name_from_struct and name_from_struct != name:
|
|
715
716
|
error_message = (
|
|
716
|
-
f"
|
|
717
|
+
f"Project name mismatch, {name_from_struct} != {name}, project is loaded from {name_from_struct} "
|
|
718
|
+
f"project yaml. To prevent/allow this, you can take one of the following actions:\n"
|
|
717
719
|
"1. Set the `allow_cross_project=True` when loading the project.\n"
|
|
718
720
|
f"2. Delete the existing project yaml, or ensure its name is equal to {name}.\n"
|
|
719
721
|
"3. Use different project context dir."
|
|
@@ -721,14 +723,14 @@ def _project_instance_from_struct(struct, name, allow_cross_project):
|
|
|
721
723
|
|
|
722
724
|
if allow_cross_project is None:
|
|
723
725
|
# TODO: Remove this warning in version 1.9.0 and also fix cli to support allow_cross_project
|
|
724
|
-
|
|
725
|
-
"Project name is different than specified on
|
|
726
|
-
"
|
|
727
|
-
description=error_message,
|
|
726
|
+
warnings.warn(
|
|
727
|
+
f"Project {name=} is different than specified on the context's project yaml. "
|
|
728
|
+
"This behavior is deprecated and will not be supported in version 1.9.0."
|
|
728
729
|
)
|
|
730
|
+
logger.warn(error_message)
|
|
729
731
|
elif allow_cross_project:
|
|
730
|
-
logger.
|
|
731
|
-
"Project name is different than specified on
|
|
732
|
+
logger.debug(
|
|
733
|
+
"Project name is different than specified on the context's project yaml. Overriding.",
|
|
732
734
|
existing_name=name_from_struct,
|
|
733
735
|
overriding_name=name,
|
|
734
736
|
)
|
|
@@ -993,15 +995,29 @@ class ProjectSpec(ModelObj):
|
|
|
993
995
|
|
|
994
996
|
artifacts_dict = {}
|
|
995
997
|
for artifact in artifacts:
|
|
996
|
-
|
|
998
|
+
invalid_object_type = not isinstance(artifact, dict) and not hasattr(
|
|
999
|
+
artifact, "to_dict"
|
|
1000
|
+
)
|
|
1001
|
+
is_artifact_model = not isinstance(artifact, dict) and hasattr(
|
|
1002
|
+
artifact, "to_dict"
|
|
1003
|
+
)
|
|
1004
|
+
|
|
1005
|
+
if invalid_object_type:
|
|
997
1006
|
raise ValueError("artifacts must be a dict or class")
|
|
998
|
-
|
|
999
|
-
key = artifact.get("metadata", {}).get("key", "")
|
|
1000
|
-
if not key:
|
|
1001
|
-
raise ValueError('artifacts "metadata.key" must be specified')
|
|
1002
|
-
else:
|
|
1007
|
+
elif is_artifact_model:
|
|
1003
1008
|
key = artifact.key
|
|
1004
1009
|
artifact = artifact.to_dict()
|
|
1010
|
+
else: # artifact is a dict
|
|
1011
|
+
# imported/legacy artifacts don't have metadata,spec,status fields
|
|
1012
|
+
key_field = (
|
|
1013
|
+
"key"
|
|
1014
|
+
if _is_imported_artifact(artifact)
|
|
1015
|
+
or mlrun.utils.is_legacy_artifact(artifact)
|
|
1016
|
+
else "metadata.key"
|
|
1017
|
+
)
|
|
1018
|
+
key = mlrun.utils.get_in(artifact, key_field, "")
|
|
1019
|
+
if not key:
|
|
1020
|
+
raise ValueError(f'artifacts "{key_field}" must be specified')
|
|
1005
1021
|
|
|
1006
1022
|
artifacts_dict[key] = artifact
|
|
1007
1023
|
|
|
@@ -2116,6 +2132,8 @@ class MlrunProject(ModelObj):
|
|
|
2116
2132
|
*,
|
|
2117
2133
|
deploy_histogram_data_drift_app: bool = True,
|
|
2118
2134
|
wait_for_deployment: bool = False,
|
|
2135
|
+
rebuild_images: bool = False,
|
|
2136
|
+
fetch_credentials_from_sys_config: bool = False,
|
|
2119
2137
|
) -> None:
|
|
2120
2138
|
"""
|
|
2121
2139
|
Deploy model monitoring application controller, writer and stream functions.
|
|
@@ -2125,16 +2143,18 @@ class MlrunProject(ModelObj):
|
|
|
2125
2143
|
The stream function goal is to monitor the log of the data stream. It is triggered when a new log entry
|
|
2126
2144
|
is detected. It processes the new events into statistics that are then written to statistics databases.
|
|
2127
2145
|
|
|
2128
|
-
:param default_controller_image:
|
|
2129
|
-
:param base_period:
|
|
2130
|
-
|
|
2131
|
-
:param image:
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
:param deploy_histogram_data_drift_app:
|
|
2135
|
-
:param wait_for_deployment:
|
|
2136
|
-
|
|
2137
|
-
|
|
2146
|
+
:param default_controller_image: Deprecated.
|
|
2147
|
+
:param base_period: The time period in minutes in which the model monitoring controller
|
|
2148
|
+
function is triggered. By default, the base period is 10 minutes.
|
|
2149
|
+
:param image: The image of the model monitoring controller, writer, monitoring
|
|
2150
|
+
stream & histogram data drift functions, which are real time nuclio
|
|
2151
|
+
functions. By default, the image is mlrun/mlrun.
|
|
2152
|
+
:param deploy_histogram_data_drift_app: If true, deploy the default histogram-based data drift application.
|
|
2153
|
+
:param wait_for_deployment: If true, return only after the deployment is done on the backend.
|
|
2154
|
+
Otherwise, deploy the model monitoring infrastructure on the
|
|
2155
|
+
background, including the histogram data drift app if selected.
|
|
2156
|
+
:param rebuild_images: If true, force rebuild of model monitoring infrastructure images.
|
|
2157
|
+
:param fetch_credentials_from_sys_config: If true, fetch the credentials from the system configuration.
|
|
2138
2158
|
"""
|
|
2139
2159
|
if default_controller_image != "mlrun/mlrun":
|
|
2140
2160
|
# TODO: Remove this in 1.9.0
|
|
@@ -2150,6 +2170,8 @@ class MlrunProject(ModelObj):
|
|
|
2150
2170
|
image=image,
|
|
2151
2171
|
base_period=base_period,
|
|
2152
2172
|
deploy_histogram_data_drift_app=deploy_histogram_data_drift_app,
|
|
2173
|
+
rebuild_images=rebuild_images,
|
|
2174
|
+
fetch_credentials_from_sys_config=fetch_credentials_from_sys_config,
|
|
2153
2175
|
)
|
|
2154
2176
|
|
|
2155
2177
|
if wait_for_deployment:
|
|
@@ -2324,7 +2346,8 @@ class MlrunProject(ModelObj):
|
|
|
2324
2346
|
Default: job
|
|
2325
2347
|
:param image: Docker image to be used, can also be specified in the function object/yaml
|
|
2326
2348
|
:param handler: Default function handler to invoke (can only be set with .py/.ipynb files)
|
|
2327
|
-
:param with_repo: Add (clone) the current repo to the build source
|
|
2349
|
+
:param with_repo: Add (clone) the current repo to the build source - use when the function code is in
|
|
2350
|
+
the project repo (project.spec.source).
|
|
2328
2351
|
:param tag: Function version tag to set (none for current or 'latest')
|
|
2329
2352
|
Specifying a tag as a parameter will update the project's tagged function
|
|
2330
2353
|
(myfunc:v1) and the untagged function (myfunc)
|
|
@@ -2471,25 +2494,17 @@ class MlrunProject(ModelObj):
|
|
|
2471
2494
|
self.spec.remove_function(name)
|
|
2472
2495
|
|
|
2473
2496
|
def remove_model_monitoring_function(self, name: Union[str, list[str]]):
|
|
2474
|
-
"""
|
|
2497
|
+
"""delete the specified model-monitoring-app function/s
|
|
2475
2498
|
|
|
2476
2499
|
:param name: name of the model-monitoring-function/s (under the project)
|
|
2477
2500
|
"""
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
self.remove_function(name=func_name)
|
|
2486
|
-
logger.info(
|
|
2487
|
-
f"{func_name} function has been removed from {self.name} project"
|
|
2488
|
-
)
|
|
2489
|
-
else:
|
|
2490
|
-
raise logger.warn(
|
|
2491
|
-
f"There is no model monitoring function with {func_name} name"
|
|
2492
|
-
)
|
|
2501
|
+
# TODO: Remove this in 1.9.0
|
|
2502
|
+
warnings.warn(
|
|
2503
|
+
"'remove_model_monitoring_function' is deprecated and will be removed in 1.9.0. "
|
|
2504
|
+
"Please use `delete_model_monitoring_function` instead.",
|
|
2505
|
+
FutureWarning,
|
|
2506
|
+
)
|
|
2507
|
+
self.delete_model_monitoring_function(name)
|
|
2493
2508
|
|
|
2494
2509
|
def delete_model_monitoring_function(self, name: Union[str, list[str]]):
|
|
2495
2510
|
"""delete the specified model-monitoring-app function/s
|
|
@@ -3191,48 +3206,44 @@ class MlrunProject(ModelObj):
|
|
|
3191
3206
|
stream_path: Optional[str] = None,
|
|
3192
3207
|
tsdb_connection: Optional[str] = None,
|
|
3193
3208
|
):
|
|
3194
|
-
"""Set the credentials that will be used by the project's model monitoring
|
|
3195
|
-
infrastructure functions.
|
|
3196
|
-
|
|
3197
|
-
:param access_key: Model Monitoring access key for managing user permissions
|
|
3198
|
-
:param endpoint_store_connection: Endpoint store connection string
|
|
3199
|
-
:param stream_path: Path to the model monitoring stream
|
|
3200
|
-
:param tsdb_connection: Connection string to the time series database
|
|
3201
3209
|
"""
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3210
|
+
Set the credentials that will be used by the project's model monitoring
|
|
3211
|
+
infrastructure functions. Important to note that you have to set the credentials before deploying any
|
|
3212
|
+
model monitoring or serving function.
|
|
3213
|
+
|
|
3214
|
+
:param access_key: Model Monitoring access key for managing user permissions.
|
|
3215
|
+
:param endpoint_store_connection: Endpoint store connection string. By default, None.
|
|
3216
|
+
Options:
|
|
3217
|
+
1. None, will be set from the system configuration.
|
|
3218
|
+
2. v3io - for v3io endpoint store,
|
|
3219
|
+
pass `v3io` and the system will generate the exact path.
|
|
3220
|
+
3. MySQL/SQLite - for SQL endpoint store, please provide full
|
|
3221
|
+
connection string, for example
|
|
3222
|
+
mysql+pymysql://<username>:<password>@<host>:<port>/<db_name>
|
|
3223
|
+
:param stream_path: Path to the model monitoring stream. By default, None.
|
|
3224
|
+
Options:
|
|
3225
|
+
1. None, will be set from the system configuration.
|
|
3226
|
+
2. v3io - for v3io stream,
|
|
3227
|
+
pass `v3io` and the system will generate the exact path.
|
|
3228
|
+
3. Kafka - for Kafka stream, please provide full connection string without
|
|
3229
|
+
custom topic, for example kafka://<some_kafka_broker>:<port>.
|
|
3230
|
+
:param tsdb_connection: Connection string to the time series database. By default, None.
|
|
3231
|
+
Options:
|
|
3232
|
+
1. None, will be set from the system configuration.
|
|
3233
|
+
2. v3io - for v3io stream,
|
|
3234
|
+
pass `v3io` and the system will generate the exact path.
|
|
3235
|
+
3. TDEngine - for TDEngine tsdb, please provide full websocket connection URL,
|
|
3236
|
+
for example taosws://<username>:<password>@<host>:<port>.
|
|
3237
|
+
"""
|
|
3238
|
+
db = mlrun.db.get_run_db(secrets=self._secrets)
|
|
3239
|
+
db.set_model_monitoring_credentials(
|
|
3240
|
+
project=self.name,
|
|
3241
|
+
credentials={
|
|
3242
|
+
"access_key": access_key,
|
|
3243
|
+
"endpoint_store_connection": endpoint_store_connection,
|
|
3244
|
+
"stream_path": stream_path,
|
|
3245
|
+
"tsdb_connection": tsdb_connection,
|
|
3246
|
+
},
|
|
3236
3247
|
)
|
|
3237
3248
|
|
|
3238
3249
|
def run_function(
|
|
@@ -3649,6 +3660,7 @@ class MlrunProject(ModelObj):
|
|
|
3649
3660
|
kind: str = None,
|
|
3650
3661
|
category: typing.Union[str, mlrun.common.schemas.ArtifactCategories] = None,
|
|
3651
3662
|
tree: str = None,
|
|
3663
|
+
limit: int = None,
|
|
3652
3664
|
) -> mlrun.lists.ArtifactList:
|
|
3653
3665
|
"""List artifacts filtered by various parameters.
|
|
3654
3666
|
|
|
@@ -3678,6 +3690,7 @@ class MlrunProject(ModelObj):
|
|
|
3678
3690
|
:param kind: Return artifacts of the requested kind.
|
|
3679
3691
|
:param category: Return artifacts of the requested category.
|
|
3680
3692
|
:param tree: Return artifacts of the requested tree.
|
|
3693
|
+
:param limit: Maximum number of artifacts to return.
|
|
3681
3694
|
"""
|
|
3682
3695
|
db = mlrun.db.get_run_db(secrets=self._secrets)
|
|
3683
3696
|
return db.list_artifacts(
|
|
@@ -3692,6 +3705,7 @@ class MlrunProject(ModelObj):
|
|
|
3692
3705
|
kind=kind,
|
|
3693
3706
|
category=category,
|
|
3694
3707
|
tree=tree,
|
|
3708
|
+
limit=limit,
|
|
3695
3709
|
)
|
|
3696
3710
|
|
|
3697
3711
|
def list_models(
|
mlrun/render.py
CHANGED
|
@@ -283,9 +283,14 @@ function copyToClipboard(fld) {
|
|
|
283
283
|
}
|
|
284
284
|
function expandPanel(el) {
|
|
285
285
|
const panelName = "#" + el.getAttribute('paneName');
|
|
286
|
-
console.log(el.title);
|
|
287
286
|
|
|
288
|
-
|
|
287
|
+
// Get the base URL of the current notebook
|
|
288
|
+
var baseUrl = window.location.origin;
|
|
289
|
+
|
|
290
|
+
// Construct the full URL
|
|
291
|
+
var fullUrl = new URL(el.title, baseUrl).href;
|
|
292
|
+
|
|
293
|
+
document.querySelector(panelName + "-title").innerHTML = fullUrl
|
|
289
294
|
iframe = document.querySelector(panelName + "-body");
|
|
290
295
|
|
|
291
296
|
const tblcss = `<style> body { font-family: Arial, Helvetica, sans-serif;}
|
|
@@ -299,7 +304,7 @@ function expandPanel(el) {
|
|
|
299
304
|
}
|
|
300
305
|
|
|
301
306
|
function reqListener () {
|
|
302
|
-
if (
|
|
307
|
+
if (fullUrl.endsWith(".csv")) {
|
|
303
308
|
iframe.setAttribute("srcdoc", tblcss + csvToHtmlTable(this.responseText));
|
|
304
309
|
} else {
|
|
305
310
|
iframe.setAttribute("srcdoc", this.responseText);
|
|
@@ -309,11 +314,11 @@ function expandPanel(el) {
|
|
|
309
314
|
|
|
310
315
|
const oReq = new XMLHttpRequest();
|
|
311
316
|
oReq.addEventListener("load", reqListener);
|
|
312
|
-
oReq.open("GET",
|
|
317
|
+
oReq.open("GET", fullUrl);
|
|
313
318
|
oReq.send();
|
|
314
319
|
|
|
315
320
|
|
|
316
|
-
//iframe.src =
|
|
321
|
+
//iframe.src = fullUrl;
|
|
317
322
|
const resultPane = document.querySelector(panelName + "-pane");
|
|
318
323
|
if (resultPane.classList.contains("hidden")) {
|
|
319
324
|
resultPane.classList.remove("hidden");
|
mlrun/run.py
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
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 importlib.util as imputil
|
|
15
16
|
import json
|
|
16
17
|
import os
|
|
@@ -28,9 +29,9 @@ from typing import Optional, Union
|
|
|
28
29
|
|
|
29
30
|
import nuclio
|
|
30
31
|
import yaml
|
|
31
|
-
from kfp import Client
|
|
32
32
|
from mlrun_pipelines.common.models import RunStatuses
|
|
33
33
|
from mlrun_pipelines.common.ops import format_summary_from_kfp_run, show_kfp_run
|
|
34
|
+
from mlrun_pipelines.utils import get_client
|
|
34
35
|
|
|
35
36
|
import mlrun.common.constants as mlrun_constants
|
|
36
37
|
import mlrun.common.formatters
|
|
@@ -62,11 +63,11 @@ from .runtimes.funcdoc import update_function_entry_points
|
|
|
62
63
|
from .runtimes.nuclio.application import ApplicationRuntime
|
|
63
64
|
from .runtimes.utils import add_code_metadata, global_context
|
|
64
65
|
from .utils import (
|
|
66
|
+
RunKeys,
|
|
65
67
|
extend_hub_uri_if_needed,
|
|
66
68
|
get_in,
|
|
67
69
|
logger,
|
|
68
70
|
retry_until_successful,
|
|
69
|
-
run_keys,
|
|
70
71
|
update_in,
|
|
71
72
|
)
|
|
72
73
|
|
|
@@ -279,7 +280,7 @@ def get_or_create_ctx(
|
|
|
279
280
|
artifact_path = mlrun.utils.helpers.template_artifact_path(
|
|
280
281
|
mlconf.artifact_path, project or mlconf.default_project
|
|
281
282
|
)
|
|
282
|
-
update_in(newspec, ["spec",
|
|
283
|
+
update_in(newspec, ["spec", RunKeys.output_path], artifact_path)
|
|
283
284
|
|
|
284
285
|
newspec.setdefault("metadata", {})
|
|
285
286
|
update_in(newspec, "metadata.name", name, replace=False)
|
|
@@ -293,10 +294,14 @@ def get_or_create_ctx(
|
|
|
293
294
|
newspec["metadata"]["project"] = (
|
|
294
295
|
newspec["metadata"].get("project") or project or mlconf.default_project
|
|
295
296
|
)
|
|
297
|
+
|
|
296
298
|
newspec["metadata"].setdefault("labels", {})
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
299
|
+
|
|
300
|
+
# This function can also be called as a local run if it is not called within a function.
|
|
301
|
+
# It will create a local run, and the run kind must be local by default.
|
|
302
|
+
newspec["metadata"]["labels"].setdefault(
|
|
303
|
+
mlrun_constants.MLRunInternalLabels.kind, RuntimeKinds.local
|
|
304
|
+
)
|
|
300
305
|
|
|
301
306
|
ctx = MLClientCtx.from_dict(
|
|
302
307
|
newspec, rundb=out, autocommit=autocommit, tmp=tmp, host=socket.gethostname()
|
|
@@ -948,7 +953,7 @@ def wait_for_pipeline_completion(
|
|
|
948
953
|
_wait_for_pipeline_completion,
|
|
949
954
|
)
|
|
950
955
|
else:
|
|
951
|
-
client =
|
|
956
|
+
client = get_client(namespace=namespace)
|
|
952
957
|
resp = client.wait_for_run_completion(run_id, timeout)
|
|
953
958
|
if resp:
|
|
954
959
|
resp = resp.to_dict()
|
|
@@ -1009,7 +1014,7 @@ def get_pipeline(
|
|
|
1009
1014
|
)
|
|
1010
1015
|
|
|
1011
1016
|
else:
|
|
1012
|
-
client =
|
|
1017
|
+
client = get_client(namespace=namespace)
|
|
1013
1018
|
resp = client.get_run(run_id)
|
|
1014
1019
|
if resp:
|
|
1015
1020
|
resp = resp.to_dict()
|
mlrun/runtimes/base.py
CHANGED
|
@@ -426,13 +426,19 @@ class BaseRuntime(ModelObj):
|
|
|
426
426
|
reset_on_run=reset_on_run,
|
|
427
427
|
)
|
|
428
428
|
|
|
429
|
-
def _get_db_run(
|
|
429
|
+
def _get_db_run(
|
|
430
|
+
self,
|
|
431
|
+
task: RunObject = None,
|
|
432
|
+
run_format: mlrun.common.formatters.RunFormat = mlrun.common.formatters.RunFormat.full,
|
|
433
|
+
):
|
|
430
434
|
if self._get_db() and task:
|
|
431
435
|
project = task.metadata.project
|
|
432
436
|
uid = task.metadata.uid
|
|
433
437
|
iter = task.metadata.iteration
|
|
434
438
|
try:
|
|
435
|
-
return self._get_db().read_run(
|
|
439
|
+
return self._get_db().read_run(
|
|
440
|
+
uid, project, iter=iter, format_=run_format
|
|
441
|
+
)
|
|
436
442
|
except mlrun.db.RunDBError:
|
|
437
443
|
return None
|
|
438
444
|
if task:
|
|
@@ -549,13 +555,14 @@ class BaseRuntime(ModelObj):
|
|
|
549
555
|
self,
|
|
550
556
|
resp: dict = None,
|
|
551
557
|
task: RunObject = None,
|
|
552
|
-
err=None,
|
|
558
|
+
err: Union[Exception, str] = None,
|
|
559
|
+
run_format: mlrun.common.formatters.RunFormat = mlrun.common.formatters.RunFormat.full,
|
|
553
560
|
) -> typing.Optional[dict]:
|
|
554
561
|
"""update the task state in the DB"""
|
|
555
562
|
was_none = False
|
|
556
563
|
if resp is None and task:
|
|
557
564
|
was_none = True
|
|
558
|
-
resp = self._get_db_run(task)
|
|
565
|
+
resp = self._get_db_run(task, run_format)
|
|
559
566
|
|
|
560
567
|
if not resp:
|
|
561
568
|
self.store_run(task)
|