mlrun 1.7.0rc36__py3-none-any.whl → 1.7.0rc37__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/alerts/alert.py +63 -0
- mlrun/common/schemas/alert.py +2 -2
- mlrun/common/schemas/notification.py +23 -4
- mlrun/datastore/s3.py +8 -1
- mlrun/model_monitoring/api.py +1 -1
- mlrun/model_monitoring/applications/_application_steps.py +9 -4
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +14 -1
- mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +1 -1
- mlrun/model_monitoring/db/tsdb/base.py +20 -11
- mlrun/model_monitoring/helpers.py +1 -2
- mlrun/model_monitoring/writer.py +4 -1
- mlrun/projects/operations.py +4 -0
- mlrun/projects/project.py +4 -0
- mlrun/runtimes/base.py +3 -0
- mlrun/runtimes/nuclio/application/application.py +53 -12
- mlrun/runtimes/nuclio/function.py +5 -1
- mlrun/runtimes/sparkjob/spark3job.py +4 -7
- mlrun/serving/routers.py +1 -4
- mlrun/serving/server.py +4 -7
- mlrun/serving/states.py +1 -1
- mlrun/serving/v2_serving.py +4 -7
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc36.dist-info → mlrun-1.7.0rc37.dist-info}/METADATA +6 -6
- {mlrun-1.7.0rc36.dist-info → mlrun-1.7.0rc37.dist-info}/RECORD +28 -28
- {mlrun-1.7.0rc36.dist-info → mlrun-1.7.0rc37.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc36.dist-info → mlrun-1.7.0rc37.dist-info}/WHEEL +0 -0
- {mlrun-1.7.0rc36.dist-info → mlrun-1.7.0rc37.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc36.dist-info → mlrun-1.7.0rc37.dist-info}/top_level.txt +0 -0
mlrun/alerts/alert.py
CHANGED
|
@@ -28,6 +28,7 @@ class AlertConfig(ModelObj):
|
|
|
28
28
|
"severity",
|
|
29
29
|
"reset_policy",
|
|
30
30
|
"state",
|
|
31
|
+
"count",
|
|
31
32
|
]
|
|
32
33
|
_fields_to_serialize = ModelObj._fields_to_serialize + [
|
|
33
34
|
"entities",
|
|
@@ -54,6 +55,68 @@ class AlertConfig(ModelObj):
|
|
|
54
55
|
created: str = None,
|
|
55
56
|
count: int = None,
|
|
56
57
|
):
|
|
58
|
+
"""
|
|
59
|
+
Alert config object
|
|
60
|
+
|
|
61
|
+
Example::
|
|
62
|
+
# create an alert on endpoint_id, which will be triggered to slack if there is a "data_drift_detected" event
|
|
63
|
+
3 times in the next hour.
|
|
64
|
+
from mlrun.alerts import AlertConfig
|
|
65
|
+
import mlrun.common.schemas.alert as alert_objects
|
|
66
|
+
|
|
67
|
+
entity_kind = alert_objects.EventEntityKind.MODEL_ENDPOINT_RESULT
|
|
68
|
+
entity_id = get_default_result_instance_fqn(endpoint_id)
|
|
69
|
+
event_name = alert_objects.EventKind.DATA_DRIFT_DETECTED
|
|
70
|
+
notification = mlrun.model.Notification(
|
|
71
|
+
kind="slack",
|
|
72
|
+
name="slack_notification",
|
|
73
|
+
message="drift was detected",
|
|
74
|
+
severity="warning",
|
|
75
|
+
when=["now"],
|
|
76
|
+
condition="failed",
|
|
77
|
+
secret_params={
|
|
78
|
+
"webhook": "https://hooks.slack.com/",
|
|
79
|
+
},
|
|
80
|
+
).to_dict()
|
|
81
|
+
|
|
82
|
+
alert_data = AlertConfig(
|
|
83
|
+
project="my-project",
|
|
84
|
+
name="drift-alert",
|
|
85
|
+
summary="a drift was detected",
|
|
86
|
+
severity=alert_objects.AlertSeverity.LOW,
|
|
87
|
+
entities=alert_objects.EventEntities(
|
|
88
|
+
kind=entity_kind, project="my-project", ids=[entity_id]
|
|
89
|
+
),
|
|
90
|
+
trigger=alert_objects.AlertTrigger(events=[event_name]),
|
|
91
|
+
criteria=alert_objects.AlertCriteria(count=3, period="1h"),
|
|
92
|
+
notifications=[alert_objects.AlertNotification(notification=notification)],
|
|
93
|
+
)
|
|
94
|
+
project.store_alert_config(alert_data)
|
|
95
|
+
|
|
96
|
+
:param project: name of the project to associate the alert with
|
|
97
|
+
:param name: name of the alert
|
|
98
|
+
:param template: optional parameter that allows to create an alert based on a predefined template.
|
|
99
|
+
you can pass either an AlertTemplate object or a string (the template name).
|
|
100
|
+
if a template is used, many fields of the alert will be auto-generated based on the
|
|
101
|
+
template. however, you still need to provide the following fields:
|
|
102
|
+
`name`, `project`, `entity`, `notifications`
|
|
103
|
+
:param description: description of the alert
|
|
104
|
+
:param summary: summary of the alert, will be sent in the generated notifications
|
|
105
|
+
:param severity: severity of the alert
|
|
106
|
+
:param trigger: the events that will trigger this alert, may be a simple trigger based on events or
|
|
107
|
+
complex trigger which is based on a prometheus alert
|
|
108
|
+
:param criteria: when the alert will be triggered based on the specified number of events within the
|
|
109
|
+
defined time period.
|
|
110
|
+
:param reset_policy: when to clear the alert. May be "manual" for manual reset of the alert, or
|
|
111
|
+
"auto" if the criteria contains a time period
|
|
112
|
+
:param notifications: list of notifications to invoke once the alert is triggered
|
|
113
|
+
:param entities: entities that the event relates to. The entity object will contain fields that uniquely
|
|
114
|
+
identify a given entity in the system
|
|
115
|
+
:param id: internal id of the alert (user should not supply it)
|
|
116
|
+
:param state: state of the alert, may be active/inactive (user should not supply it)
|
|
117
|
+
:param created: when the alert is created (user should not supply it)
|
|
118
|
+
:param count: internal counter of the alert (user should not supply it)
|
|
119
|
+
"""
|
|
57
120
|
self.project = project
|
|
58
121
|
self.name = name
|
|
59
122
|
self.description = description
|
mlrun/common/schemas/alert.py
CHANGED
|
@@ -149,7 +149,7 @@ class AlertConfig(pydantic.BaseModel):
|
|
|
149
149
|
entities: EventEntities
|
|
150
150
|
trigger: AlertTrigger
|
|
151
151
|
criteria: Optional[AlertCriteria]
|
|
152
|
-
reset_policy: ResetPolicy = ResetPolicy.
|
|
152
|
+
reset_policy: ResetPolicy = ResetPolicy.AUTO
|
|
153
153
|
notifications: pydantic.conlist(AlertNotification, min_items=1)
|
|
154
154
|
state: AlertActiveState = AlertActiveState.INACTIVE
|
|
155
155
|
count: Optional[int] = 0
|
|
@@ -185,7 +185,7 @@ class AlertTemplate(
|
|
|
185
185
|
severity: AlertSeverity
|
|
186
186
|
trigger: AlertTrigger
|
|
187
187
|
criteria: Optional[AlertCriteria]
|
|
188
|
-
reset_policy: ResetPolicy = ResetPolicy.
|
|
188
|
+
reset_policy: ResetPolicy = ResetPolicy.AUTO
|
|
189
189
|
|
|
190
190
|
# This is slightly different than __eq__ as it doesn't compare everything
|
|
191
191
|
def templates_differ(self, other):
|
|
@@ -50,15 +50,34 @@ class NotificationLimits(enum.Enum):
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
class Notification(pydantic.BaseModel):
|
|
53
|
+
"""
|
|
54
|
+
Notification object schema
|
|
55
|
+
:param kind: notification implementation kind - slack, webhook, etc.
|
|
56
|
+
:param name: for logging and identification
|
|
57
|
+
:param message: message content in the notification
|
|
58
|
+
:param severity: severity to display in the notification
|
|
59
|
+
:param when: list of statuses to trigger the notification: 'running', 'completed', 'error'
|
|
60
|
+
:param condition: optional condition to trigger the notification, a jinja2 expression that can use run data
|
|
61
|
+
to evaluate if the notification should be sent in addition to the 'when' statuses.
|
|
62
|
+
e.g.: '{{ run["status"]["results"]["accuracy"] < 0.9}}'
|
|
63
|
+
:param params: Implementation specific parameters for the notification implementation (e.g. slack webhook url,
|
|
64
|
+
git repository details, etc.)
|
|
65
|
+
:param secret_params: secret parameters for the notification implementation, same as params but will be stored
|
|
66
|
+
in a k8s secret and passed as a secret reference to the implementation.
|
|
67
|
+
:param status: notification status - pending, sent, error
|
|
68
|
+
:param sent_time: time the notification was sent
|
|
69
|
+
:param reason: failure reason if the notification failed to send
|
|
70
|
+
"""
|
|
71
|
+
|
|
53
72
|
kind: NotificationKind
|
|
54
73
|
name: str
|
|
55
74
|
message: str
|
|
56
75
|
severity: NotificationSeverity
|
|
57
76
|
when: list[str]
|
|
58
|
-
condition: str = None
|
|
59
|
-
params: dict[str, typing.Any] = None
|
|
60
|
-
status: NotificationStatus = None
|
|
61
|
-
sent_time: typing.Union[str, datetime.datetime] = None
|
|
77
|
+
condition: typing.Optional[str] = None
|
|
78
|
+
params: typing.Optional[dict[str, typing.Any]] = None
|
|
79
|
+
status: typing.Optional[NotificationStatus] = None
|
|
80
|
+
sent_time: typing.Optional[typing.Union[str, datetime.datetime]] = None
|
|
62
81
|
secret_params: typing.Optional[dict[str, typing.Any]] = None
|
|
63
82
|
reason: typing.Optional[str] = None
|
|
64
83
|
|
mlrun/datastore/s3.py
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
import time
|
|
16
16
|
|
|
17
17
|
import boto3
|
|
18
|
+
from boto3.s3.transfer import TransferConfig
|
|
18
19
|
from fsspec.registry import get_filesystem_class
|
|
19
20
|
|
|
20
21
|
import mlrun.errors
|
|
@@ -40,6 +41,12 @@ class S3Store(DataStore):
|
|
|
40
41
|
profile_name = self._get_secret_or_env("AWS_PROFILE")
|
|
41
42
|
assume_role_arn = self._get_secret_or_env("MLRUN_AWS_ROLE_ARN")
|
|
42
43
|
|
|
44
|
+
self.config = TransferConfig(
|
|
45
|
+
multipart_threshold=1024 * 1024 * 25,
|
|
46
|
+
max_concurrency=10,
|
|
47
|
+
multipart_chunksize=1024 * 1024 * 25,
|
|
48
|
+
)
|
|
49
|
+
|
|
43
50
|
# If user asks to assume a role, this needs to go through the STS client and retrieve temporary creds
|
|
44
51
|
if assume_role_arn:
|
|
45
52
|
client = boto3.client(
|
|
@@ -166,7 +173,7 @@ class S3Store(DataStore):
|
|
|
166
173
|
|
|
167
174
|
def upload(self, key, src_path):
|
|
168
175
|
bucket, key = self.get_bucket_and_key(key)
|
|
169
|
-
self.s3.
|
|
176
|
+
self.s3.Bucket(bucket).upload_file(src_path, key, Config=self.config)
|
|
170
177
|
|
|
171
178
|
def get(self, key, size=None, offset=0):
|
|
172
179
|
bucket, key = self.get_bucket_and_key(key)
|
mlrun/model_monitoring/api.py
CHANGED
|
@@ -20,6 +20,7 @@ import mlrun.common.model_monitoring.helpers
|
|
|
20
20
|
import mlrun.common.schemas.model_monitoring.constants as mm_constant
|
|
21
21
|
import mlrun.datastore
|
|
22
22
|
import mlrun.serving
|
|
23
|
+
import mlrun.utils.helpers
|
|
23
24
|
import mlrun.utils.v3io_clients
|
|
24
25
|
from mlrun.model_monitoring.helpers import get_stream_path
|
|
25
26
|
from mlrun.serving.utils import StepToDict
|
|
@@ -34,8 +35,8 @@ class _PushToMonitoringWriter(StepToDict):
|
|
|
34
35
|
|
|
35
36
|
def __init__(
|
|
36
37
|
self,
|
|
37
|
-
project:
|
|
38
|
-
writer_application_name:
|
|
38
|
+
project: str,
|
|
39
|
+
writer_application_name: str,
|
|
39
40
|
stream_uri: Optional[str] = None,
|
|
40
41
|
name: Optional[str] = None,
|
|
41
42
|
):
|
|
@@ -109,6 +110,7 @@ class _PushToMonitoringWriter(StepToDict):
|
|
|
109
110
|
f"Pushing data = {writer_event} \n to stream = {self.stream_uri}"
|
|
110
111
|
)
|
|
111
112
|
self.output_stream.push([writer_event])
|
|
113
|
+
logger.info(f"Pushed data to {self.stream_uri} successfully")
|
|
112
114
|
|
|
113
115
|
def _lazy_init(self):
|
|
114
116
|
if self.output_stream is None:
|
|
@@ -150,12 +152,15 @@ class _PrepareMonitoringEvent(StepToDict):
|
|
|
150
152
|
|
|
151
153
|
@staticmethod
|
|
152
154
|
def _create_mlrun_context(app_name: str):
|
|
155
|
+
artifact_path = mlrun.utils.helpers.template_artifact_path(
|
|
156
|
+
mlrun.mlconf.artifact_path, mlrun.mlconf.default_project
|
|
157
|
+
)
|
|
153
158
|
context = mlrun.get_or_create_ctx(
|
|
154
159
|
f"{app_name}-logger",
|
|
155
160
|
spec={
|
|
156
|
-
"metadata": {"labels": {"kind": mlrun.runtimes.RuntimeKinds.serving}}
|
|
161
|
+
"metadata": {"labels": {"kind": mlrun.runtimes.RuntimeKinds.serving}},
|
|
162
|
+
"spec": {mlrun.utils.helpers.RunKeys.output_path: artifact_path},
|
|
157
163
|
},
|
|
158
|
-
upload_artifacts=True,
|
|
159
164
|
)
|
|
160
165
|
context.__class__ = MonitoringApplicationContext
|
|
161
166
|
return context
|
|
@@ -18,6 +18,7 @@ from sqlalchemy.ext.declarative import declarative_base, declared_attr
|
|
|
18
18
|
|
|
19
19
|
from mlrun.common.schemas.model_monitoring import (
|
|
20
20
|
EventFieldType,
|
|
21
|
+
ResultData,
|
|
21
22
|
WriterEvent,
|
|
22
23
|
)
|
|
23
24
|
|
|
@@ -32,6 +33,13 @@ Base = declarative_base()
|
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
class ModelEndpointsTable(Base, ModelEndpointsBaseTable):
|
|
36
|
+
feature_stats = Column(
|
|
37
|
+
EventFieldType.FEATURE_STATS, sqlalchemy.dialects.mysql.MEDIUMTEXT
|
|
38
|
+
)
|
|
39
|
+
current_stats = Column(
|
|
40
|
+
EventFieldType.CURRENT_STATS, sqlalchemy.dialects.mysql.MEDIUMTEXT
|
|
41
|
+
)
|
|
42
|
+
metrics = Column(EventFieldType.METRICS, sqlalchemy.dialects.mysql.MEDIUMTEXT)
|
|
35
43
|
first_request = Column(
|
|
36
44
|
EventFieldType.FIRST_REQUEST,
|
|
37
45
|
# TODO: migrate to DATETIME, see ML-6921
|
|
@@ -72,7 +80,12 @@ class _ApplicationResultOrMetric:
|
|
|
72
80
|
class ApplicationResultTable(
|
|
73
81
|
Base, _ApplicationResultOrMetric, ApplicationResultBaseTable
|
|
74
82
|
):
|
|
75
|
-
|
|
83
|
+
result_extra_data = Column(
|
|
84
|
+
ResultData.RESULT_EXTRA_DATA, sqlalchemy.dialects.mysql.MEDIUMTEXT
|
|
85
|
+
)
|
|
86
|
+
current_stats = Column(
|
|
87
|
+
ResultData.CURRENT_STATS, sqlalchemy.dialects.mysql.MEDIUMTEXT
|
|
88
|
+
)
|
|
76
89
|
|
|
77
90
|
|
|
78
91
|
class ApplicationMetricsTable(
|
|
@@ -350,7 +350,7 @@ class KVStoreBase(StoreBase):
|
|
|
350
350
|
table_path = self._get_results_table_path(endpoint_id)
|
|
351
351
|
key = event.pop(mm_schemas.WriterEvent.APPLICATION_NAME)
|
|
352
352
|
metric_name = event.pop(mm_schemas.ResultData.RESULT_NAME)
|
|
353
|
-
attributes = {metric_name: json.dumps(event)}
|
|
353
|
+
attributes = {metric_name: self._encode_field(json.dumps(event))}
|
|
354
354
|
else:
|
|
355
355
|
raise ValueError(f"Invalid {kind = }")
|
|
356
356
|
|
|
@@ -17,6 +17,7 @@ from abc import ABC, abstractmethod
|
|
|
17
17
|
from datetime import datetime
|
|
18
18
|
|
|
19
19
|
import pandas as pd
|
|
20
|
+
import pydantic
|
|
20
21
|
|
|
21
22
|
import mlrun.common.schemas.model_monitoring as mm_schemas
|
|
22
23
|
import mlrun.model_monitoring.db.tsdb.helpers
|
|
@@ -289,19 +290,27 @@ class TSDBConnector(ABC):
|
|
|
289
290
|
full_name = mlrun.model_monitoring.helpers._compose_full_name(
|
|
290
291
|
project=project, app=app_name, name=name
|
|
291
292
|
)
|
|
292
|
-
|
|
293
|
-
|
|
293
|
+
try:
|
|
294
|
+
metrics_values.append(
|
|
295
|
+
mm_schemas.ModelEndpointMonitoringResultValues(
|
|
296
|
+
full_name=full_name,
|
|
297
|
+
result_kind=result_kind,
|
|
298
|
+
values=list(
|
|
299
|
+
zip(
|
|
300
|
+
sub_df.index,
|
|
301
|
+
sub_df[mm_schemas.ResultData.RESULT_VALUE],
|
|
302
|
+
sub_df[mm_schemas.ResultData.RESULT_STATUS],
|
|
303
|
+
)
|
|
304
|
+
), # pyright: ignore[reportArgumentType]
|
|
305
|
+
)
|
|
306
|
+
)
|
|
307
|
+
except pydantic.ValidationError:
|
|
308
|
+
logger.exception(
|
|
309
|
+
"Failed to convert data-frame into `ModelEndpointMonitoringResultValues`",
|
|
294
310
|
full_name=full_name,
|
|
295
|
-
|
|
296
|
-
values=list(
|
|
297
|
-
zip(
|
|
298
|
-
sub_df.index,
|
|
299
|
-
sub_df[mm_schemas.ResultData.RESULT_VALUE],
|
|
300
|
-
sub_df[mm_schemas.ResultData.RESULT_STATUS],
|
|
301
|
-
)
|
|
302
|
-
), # pyright: ignore[reportArgumentType]
|
|
311
|
+
sub_df_json=sub_df.to_json(),
|
|
303
312
|
)
|
|
304
|
-
|
|
313
|
+
raise
|
|
305
314
|
del metrics_without_data[full_name]
|
|
306
315
|
|
|
307
316
|
for metric in metrics_without_data.values():
|
|
@@ -45,8 +45,7 @@ class _BatchDict(typing.TypedDict):
|
|
|
45
45
|
|
|
46
46
|
|
|
47
47
|
def get_stream_path(
|
|
48
|
-
project: str =
|
|
49
|
-
function_name: str = mm_constants.MonitoringFunctionNames.STREAM,
|
|
48
|
+
project: str, function_name: str = mm_constants.MonitoringFunctionNames.STREAM
|
|
50
49
|
) -> str:
|
|
51
50
|
"""
|
|
52
51
|
Get stream path from the project secret. If wasn't set, take it from the system configurations
|
mlrun/model_monitoring/writer.py
CHANGED
|
@@ -130,7 +130,6 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
130
130
|
project_name: str,
|
|
131
131
|
result_kind: int,
|
|
132
132
|
) -> None:
|
|
133
|
-
logger.info("Sending an event")
|
|
134
133
|
entity = mlrun.common.schemas.alert.EventEntities(
|
|
135
134
|
kind=alert_objects.EventEntityKind.MODEL_ENDPOINT_RESULT,
|
|
136
135
|
project=project_name,
|
|
@@ -146,7 +145,9 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
146
145
|
entity=entity,
|
|
147
146
|
value_dict=event_value,
|
|
148
147
|
)
|
|
148
|
+
logger.info("Sending a drift event")
|
|
149
149
|
mlrun.get_run_db().generate_event(event_kind, event_data)
|
|
150
|
+
logger.info("Drift event sent successfully")
|
|
150
151
|
|
|
151
152
|
@staticmethod
|
|
152
153
|
def _generate_alert_event_kind(
|
|
@@ -261,3 +262,5 @@ class ModelMonitoringWriter(StepToDict):
|
|
|
261
262
|
endpoint_id=endpoint_id,
|
|
262
263
|
attributes=json.loads(event[ResultData.RESULT_EXTRA_DATA]),
|
|
263
264
|
)
|
|
265
|
+
|
|
266
|
+
logger.info("Model monitoring writer finished handling event")
|
mlrun/projects/operations.py
CHANGED
|
@@ -187,6 +187,10 @@ def run_function(
|
|
|
187
187
|
task.spec.verbose = task.spec.verbose or verbose
|
|
188
188
|
|
|
189
189
|
if engine == "kfp":
|
|
190
|
+
if schedule:
|
|
191
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
192
|
+
"Scheduling job is not supported when running a workflow with kfp engine."
|
|
193
|
+
)
|
|
190
194
|
return function.as_step(
|
|
191
195
|
name=name, runspec=task, workdir=workdir, outputs=outputs, labels=labels
|
|
192
196
|
)
|
mlrun/projects/project.py
CHANGED
|
@@ -2967,6 +2967,7 @@ class MlrunProject(ModelObj):
|
|
|
2967
2967
|
source: str = None,
|
|
2968
2968
|
cleanup_ttl: int = None,
|
|
2969
2969
|
notifications: list[mlrun.model.Notification] = None,
|
|
2970
|
+
send_start_notification: bool = True,
|
|
2970
2971
|
) -> _PipelineRunStatus:
|
|
2971
2972
|
"""Run a workflow using kubeflow pipelines
|
|
2972
2973
|
|
|
@@ -3003,6 +3004,8 @@ class MlrunProject(ModelObj):
|
|
|
3003
3004
|
workflow and all its resources are deleted)
|
|
3004
3005
|
:param notifications:
|
|
3005
3006
|
List of notifications to send for workflow completion
|
|
3007
|
+
:param send_start_notification:
|
|
3008
|
+
Send a notification when the workflow starts
|
|
3006
3009
|
|
|
3007
3010
|
:returns: ~py:class:`~mlrun.projects.pipelines._PipelineRunStatus` instance
|
|
3008
3011
|
"""
|
|
@@ -3080,6 +3083,7 @@ class MlrunProject(ModelObj):
|
|
|
3080
3083
|
namespace=namespace,
|
|
3081
3084
|
source=source,
|
|
3082
3085
|
notifications=notifications,
|
|
3086
|
+
send_start_notification=send_start_notification,
|
|
3083
3087
|
)
|
|
3084
3088
|
# run is None when scheduling
|
|
3085
3089
|
if run and run.state == mlrun_pipelines.common.models.RunStatuses.failed:
|
mlrun/runtimes/base.py
CHANGED
|
@@ -18,6 +18,7 @@ import nuclio
|
|
|
18
18
|
|
|
19
19
|
import mlrun.common.schemas as schemas
|
|
20
20
|
import mlrun.errors
|
|
21
|
+
import mlrun.run
|
|
21
22
|
from mlrun.common.runtimes.constants import NuclioIngressAddTemplatedIngressModes
|
|
22
23
|
from mlrun.runtimes import RemoteRuntime
|
|
23
24
|
from mlrun.runtimes.nuclio import min_nuclio_versions
|
|
@@ -174,6 +175,7 @@ class ApplicationStatus(NuclioStatus):
|
|
|
174
175
|
|
|
175
176
|
class ApplicationRuntime(RemoteRuntime):
|
|
176
177
|
kind = "application"
|
|
178
|
+
reverse_proxy_image = None
|
|
177
179
|
|
|
178
180
|
@min_nuclio_versions("1.13.1")
|
|
179
181
|
def __init__(self, spec=None, metadata=None):
|
|
@@ -306,10 +308,11 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
306
308
|
show_on_failure=show_on_failure,
|
|
307
309
|
)
|
|
308
310
|
|
|
309
|
-
self
|
|
311
|
+
# This is a class method that accepts a function instance, so we pass self as the function instance
|
|
312
|
+
self._ensure_reverse_proxy_configurations(self)
|
|
310
313
|
self._configure_application_sidecar()
|
|
311
314
|
|
|
312
|
-
#
|
|
315
|
+
# We only allow accessing the application via the API Gateway
|
|
313
316
|
name_tag = tag or self.metadata.tag
|
|
314
317
|
self.status.api_gateway_name = (
|
|
315
318
|
f"{self.metadata.name}-{name_tag}" if name_tag else self.metadata.name
|
|
@@ -391,8 +394,8 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
391
394
|
"main:Handler",
|
|
392
395
|
)
|
|
393
396
|
|
|
394
|
-
@
|
|
395
|
-
def get_filename_and_handler(
|
|
397
|
+
@staticmethod
|
|
398
|
+
def get_filename_and_handler() -> (str, str):
|
|
396
399
|
reverse_proxy_file_path = pathlib.Path(__file__).parent / "reverse_proxy.go"
|
|
397
400
|
return str(reverse_proxy_file_path), "Handler"
|
|
398
401
|
|
|
@@ -488,6 +491,39 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
488
491
|
**http_client_kwargs,
|
|
489
492
|
)
|
|
490
493
|
|
|
494
|
+
@classmethod
|
|
495
|
+
def deploy_reverse_proxy_image(cls):
|
|
496
|
+
"""
|
|
497
|
+
Build the reverse proxy image and save it.
|
|
498
|
+
The reverse proxy image is used to route requests to the application sidecar.
|
|
499
|
+
This is useful when you want to decrease build time by building the application image only once.
|
|
500
|
+
|
|
501
|
+
:param use_cache: Use the cache when building the image
|
|
502
|
+
"""
|
|
503
|
+
# create a function that includes only the reverse proxy, without the application
|
|
504
|
+
|
|
505
|
+
reverse_proxy_func = mlrun.run.new_function(
|
|
506
|
+
name="reverse-proxy-temp", kind="remote"
|
|
507
|
+
)
|
|
508
|
+
# default max replicas is 4, we only need one replica for the reverse proxy
|
|
509
|
+
reverse_proxy_func.spec.max_replicas = 1
|
|
510
|
+
|
|
511
|
+
# the reverse proxy image should not be based on another image
|
|
512
|
+
reverse_proxy_func.set_config("spec.build.baseImage", None)
|
|
513
|
+
reverse_proxy_func.spec.image = ""
|
|
514
|
+
reverse_proxy_func.spec.build.base_image = ""
|
|
515
|
+
|
|
516
|
+
cls._ensure_reverse_proxy_configurations(reverse_proxy_func)
|
|
517
|
+
reverse_proxy_func.deploy()
|
|
518
|
+
|
|
519
|
+
# save the created container image
|
|
520
|
+
cls.reverse_proxy_image = reverse_proxy_func.status.container_image
|
|
521
|
+
|
|
522
|
+
# delete the function to avoid cluttering the project
|
|
523
|
+
mlrun.get_run_db().delete_function(
|
|
524
|
+
reverse_proxy_func.metadata.name, reverse_proxy_func.metadata.project
|
|
525
|
+
)
|
|
526
|
+
|
|
491
527
|
def _run(self, runobj: "mlrun.RunObject", execution):
|
|
492
528
|
raise mlrun.runtimes.RunError(
|
|
493
529
|
"Application runtime .run() is not yet supported. Use .invoke() instead."
|
|
@@ -527,21 +563,22 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
527
563
|
with_mlrun=with_mlrun,
|
|
528
564
|
)
|
|
529
565
|
|
|
530
|
-
|
|
531
|
-
|
|
566
|
+
@staticmethod
|
|
567
|
+
def _ensure_reverse_proxy_configurations(function: RemoteRuntime):
|
|
568
|
+
if function.spec.build.functionSourceCode or function.status.container_image:
|
|
532
569
|
return
|
|
533
570
|
|
|
534
571
|
filename, handler = ApplicationRuntime.get_filename_and_handler()
|
|
535
572
|
name, spec, code = nuclio.build_file(
|
|
536
573
|
filename,
|
|
537
|
-
name=
|
|
574
|
+
name=function.metadata.name,
|
|
538
575
|
handler=handler,
|
|
539
576
|
)
|
|
540
|
-
|
|
541
|
-
|
|
577
|
+
function.spec.function_handler = mlrun.utils.get_in(spec, "spec.handler")
|
|
578
|
+
function.spec.build.functionSourceCode = mlrun.utils.get_in(
|
|
542
579
|
spec, "spec.build.functionSourceCode"
|
|
543
580
|
)
|
|
544
|
-
|
|
581
|
+
function.spec.nuclio_runtime = mlrun.utils.get_in(spec, "spec.runtime")
|
|
545
582
|
|
|
546
583
|
def _configure_application_sidecar(self):
|
|
547
584
|
# Save the application image in the status to allow overriding it with the reverse proxy entry point
|
|
@@ -552,8 +589,12 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
552
589
|
self.status.application_image = self.spec.image
|
|
553
590
|
self.spec.image = ""
|
|
554
591
|
|
|
555
|
-
if
|
|
556
|
-
|
|
592
|
+
# reuse the reverse proxy image if it was built before
|
|
593
|
+
if (
|
|
594
|
+
reverse_proxy_image := self.status.container_image
|
|
595
|
+
or self.reverse_proxy_image
|
|
596
|
+
):
|
|
597
|
+
self.from_image(reverse_proxy_image)
|
|
557
598
|
|
|
558
599
|
self.status.sidecar_name = f"{self.metadata.name}-sidecar"
|
|
559
600
|
self.with_sidecar(
|
|
@@ -689,7 +689,7 @@ class RemoteRuntime(KubeResource):
|
|
|
689
689
|
"State thresholds do not apply for nuclio as it has its own function pods healthiness monitoring"
|
|
690
690
|
)
|
|
691
691
|
|
|
692
|
-
@min_nuclio_versions("1.
|
|
692
|
+
@min_nuclio_versions("1.13.1")
|
|
693
693
|
def disable_default_http_trigger(
|
|
694
694
|
self,
|
|
695
695
|
):
|
|
@@ -707,6 +707,10 @@ class RemoteRuntime(KubeResource):
|
|
|
707
707
|
"""
|
|
708
708
|
self.spec.disable_default_http_trigger = False
|
|
709
709
|
|
|
710
|
+
def skip_image_enrichment(self):
|
|
711
|
+
# make sure the API does not enrich the base image if the function is not a python function
|
|
712
|
+
return self.spec.nuclio_runtime and "python" not in self.spec.nuclio_runtime
|
|
713
|
+
|
|
710
714
|
def _get_state(
|
|
711
715
|
self,
|
|
712
716
|
dashboard="",
|
|
@@ -505,13 +505,10 @@ class Spark3Runtime(KubejobRuntime):
|
|
|
505
505
|
raise NotImplementedError(
|
|
506
506
|
"Setting node name is not supported for spark runtime"
|
|
507
507
|
)
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
"Setting affinity is not supported for spark runtime"
|
|
513
|
-
)
|
|
514
|
-
super().with_node_selection(node_name, node_selector, affinity, tolerations)
|
|
508
|
+
self.with_driver_node_selection(node_name, node_selector, affinity, tolerations)
|
|
509
|
+
self.with_executor_node_selection(
|
|
510
|
+
node_name, node_selector, affinity, tolerations
|
|
511
|
+
)
|
|
515
512
|
|
|
516
513
|
def with_driver_node_selection(
|
|
517
514
|
self,
|
mlrun/serving/routers.py
CHANGED
|
@@ -32,7 +32,6 @@ from mlrun.errors import err_to_str
|
|
|
32
32
|
from mlrun.utils import logger, now_date
|
|
33
33
|
|
|
34
34
|
from ..common.helpers import parse_versioned_object_uri
|
|
35
|
-
from ..config import config
|
|
36
35
|
from .server import GraphServer
|
|
37
36
|
from .utils import RouterToDict, _extract_input_data, _update_result_body
|
|
38
37
|
from .v2_serving import _ModelLogPusher
|
|
@@ -1057,9 +1056,7 @@ def _init_endpoint_record(
|
|
|
1057
1056
|
function_uri=graph_server.function_uri,
|
|
1058
1057
|
model=versioned_model_name,
|
|
1059
1058
|
model_class=voting_ensemble.__class__.__name__,
|
|
1060
|
-
stream_path=
|
|
1061
|
-
project=project, kind="stream"
|
|
1062
|
-
),
|
|
1059
|
+
stream_path=voting_ensemble.context.stream.stream_uri,
|
|
1063
1060
|
active=True,
|
|
1064
1061
|
monitoring_mode=mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled,
|
|
1065
1062
|
),
|
mlrun/serving/server.py
CHANGED
|
@@ -38,10 +38,7 @@ from ..errors import MLRunInvalidArgumentError
|
|
|
38
38
|
from ..model import ModelObj
|
|
39
39
|
from ..utils import get_caller_globals
|
|
40
40
|
from .states import RootFlowStep, RouterStep, get_function, graph_root_setter
|
|
41
|
-
from .utils import
|
|
42
|
-
event_id_key,
|
|
43
|
-
event_path_key,
|
|
44
|
-
)
|
|
41
|
+
from .utils import event_id_key, event_path_key
|
|
45
42
|
|
|
46
43
|
|
|
47
44
|
class _StreamContext:
|
|
@@ -71,15 +68,15 @@ class _StreamContext:
|
|
|
71
68
|
function_uri, config.default_project
|
|
72
69
|
)
|
|
73
70
|
|
|
74
|
-
stream_uri = mlrun.model_monitoring.get_stream_path(project=project)
|
|
71
|
+
self.stream_uri = mlrun.model_monitoring.get_stream_path(project=project)
|
|
75
72
|
|
|
76
73
|
if log_stream:
|
|
77
74
|
# Update the stream path to the log stream value
|
|
78
|
-
stream_uri = log_stream.format(project=project)
|
|
75
|
+
self.stream_uri = log_stream.format(project=project)
|
|
79
76
|
|
|
80
77
|
stream_args = parameters.get("stream_args", {})
|
|
81
78
|
|
|
82
|
-
self.output_stream = get_stream_pusher(stream_uri, **stream_args)
|
|
79
|
+
self.output_stream = get_stream_pusher(self.stream_uri, **stream_args)
|
|
83
80
|
|
|
84
81
|
|
|
85
82
|
class GraphServer(ModelObj):
|
mlrun/serving/states.py
CHANGED
mlrun/serving/v2_serving.py
CHANGED
|
@@ -15,12 +15,11 @@
|
|
|
15
15
|
import threading
|
|
16
16
|
import time
|
|
17
17
|
import traceback
|
|
18
|
-
from typing import Union
|
|
18
|
+
from typing import Optional, Union
|
|
19
19
|
|
|
20
|
+
import mlrun.artifacts
|
|
20
21
|
import mlrun.common.model_monitoring
|
|
21
22
|
import mlrun.common.schemas.model_monitoring
|
|
22
|
-
from mlrun.artifacts import ModelArtifact # noqa: F401
|
|
23
|
-
from mlrun.config import config
|
|
24
23
|
from mlrun.errors import err_to_str
|
|
25
24
|
from mlrun.utils import logger, now_date
|
|
26
25
|
|
|
@@ -102,7 +101,7 @@ class V2ModelServer(StepToDict):
|
|
|
102
101
|
self.error = ""
|
|
103
102
|
self.protocol = protocol or "v2"
|
|
104
103
|
self.model_path = model_path
|
|
105
|
-
self.model_spec: mlrun.artifacts.ModelArtifact = None
|
|
104
|
+
self.model_spec: Optional[mlrun.artifacts.ModelArtifact] = None
|
|
106
105
|
self._input_path = input_path
|
|
107
106
|
self._result_path = result_path
|
|
108
107
|
self._kwargs = kwargs # for to_dict()
|
|
@@ -570,9 +569,7 @@ def _init_endpoint_record(
|
|
|
570
569
|
model=versioned_model_name,
|
|
571
570
|
model_class=model.__class__.__name__,
|
|
572
571
|
model_uri=model.model_path,
|
|
573
|
-
stream_path=
|
|
574
|
-
project=project, kind="stream"
|
|
575
|
-
),
|
|
572
|
+
stream_path=model.context.stream.stream_uri,
|
|
576
573
|
active=True,
|
|
577
574
|
monitoring_mode=mlrun.common.schemas.model_monitoring.ModelMonitoringMode.enabled,
|
|
578
575
|
),
|
mlrun/utils/version/version.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mlrun
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.0rc37
|
|
4
4
|
Summary: Tracking and config of machine learning runs
|
|
5
5
|
Home-page: https://github.com/mlrun/mlrun
|
|
6
6
|
Author: Yaron Haviv
|
|
@@ -28,7 +28,7 @@ Requires-Dist: aiohttp-retry ~=2.8
|
|
|
28
28
|
Requires-Dist: click ~=8.1
|
|
29
29
|
Requires-Dist: nest-asyncio ~=1.0
|
|
30
30
|
Requires-Dist: ipython ~=8.10
|
|
31
|
-
Requires-Dist: nuclio-jupyter ~=0.10.
|
|
31
|
+
Requires-Dist: nuclio-jupyter ~=0.10.4
|
|
32
32
|
Requires-Dist: numpy <1.27.0,>=1.16.5
|
|
33
33
|
Requires-Dist: pandas <2.2,>=1.2
|
|
34
34
|
Requires-Dist: pyarrow <15,>=10.0
|
|
@@ -50,8 +50,8 @@ Requires-Dist: setuptools ~=71.0
|
|
|
50
50
|
Requires-Dist: deprecated ~=1.2
|
|
51
51
|
Requires-Dist: jinja2 >=3.1.3,~=3.1
|
|
52
52
|
Requires-Dist: orjson <4,>=3.9.15
|
|
53
|
-
Requires-Dist: mlrun-pipelines-kfp-common ~=0.1.
|
|
54
|
-
Requires-Dist: mlrun-pipelines-kfp-v1-8 ~=0.1.
|
|
53
|
+
Requires-Dist: mlrun-pipelines-kfp-common ~=0.1.6
|
|
54
|
+
Requires-Dist: mlrun-pipelines-kfp-v1-8 ~=0.1.6
|
|
55
55
|
Provides-Extra: alibaba-oss
|
|
56
56
|
Requires-Dist: ossfs ==2023.12.0 ; extra == 'alibaba-oss'
|
|
57
57
|
Requires-Dist: oss2 ==2.18.1 ; extra == 'alibaba-oss'
|
|
@@ -97,7 +97,7 @@ Requires-Dist: sqlalchemy ~=1.4 ; extra == 'api'
|
|
|
97
97
|
Requires-Dist: pymysql ~=1.0 ; extra == 'api'
|
|
98
98
|
Requires-Dist: alembic ~=1.9 ; extra == 'api'
|
|
99
99
|
Requires-Dist: timelength ~=1.1 ; extra == 'api'
|
|
100
|
-
Requires-Dist: memray ~=1.12 ; extra == 'api'
|
|
100
|
+
Requires-Dist: memray ~=1.12 ; (sys_platform != "win32") and extra == 'api'
|
|
101
101
|
Provides-Extra: azure-blob-storage
|
|
102
102
|
Requires-Dist: msrest ~=0.6.21 ; extra == 'azure-blob-storage'
|
|
103
103
|
Requires-Dist: azure-core ~=1.24 ; extra == 'azure-blob-storage'
|
|
@@ -156,7 +156,6 @@ Requires-Dist: graphviz ~=0.20.0 ; extra == 'complete-api'
|
|
|
156
156
|
Requires-Dist: humanfriendly ~=10.0 ; extra == 'complete-api'
|
|
157
157
|
Requires-Dist: igz-mgmt ~=0.2.0 ; extra == 'complete-api'
|
|
158
158
|
Requires-Dist: kafka-python ~=2.0 ; extra == 'complete-api'
|
|
159
|
-
Requires-Dist: memray ~=1.12 ; extra == 'complete-api'
|
|
160
159
|
Requires-Dist: mlflow ~=2.8 ; extra == 'complete-api'
|
|
161
160
|
Requires-Dist: msrest ~=0.6.21 ; extra == 'complete-api'
|
|
162
161
|
Requires-Dist: objgraph ~=3.6 ; extra == 'complete-api'
|
|
@@ -172,6 +171,7 @@ Requires-Dist: sqlalchemy ~=1.4 ; extra == 'complete-api'
|
|
|
172
171
|
Requires-Dist: taos-ws-py ~=0.3.2 ; extra == 'complete-api'
|
|
173
172
|
Requires-Dist: timelength ~=1.1 ; extra == 'complete-api'
|
|
174
173
|
Requires-Dist: uvicorn ~=0.27.1 ; extra == 'complete-api'
|
|
174
|
+
Requires-Dist: memray ~=1.12 ; (sys_platform != "win32") and extra == 'complete-api'
|
|
175
175
|
Provides-Extra: dask
|
|
176
176
|
Requires-Dist: dask ~=2023.9.0 ; extra == 'dask'
|
|
177
177
|
Requires-Dist: distributed ~=2023.9.0 ; extra == 'dask'
|
|
@@ -11,7 +11,7 @@ mlrun/render.py,sha256=n8SeY3ogVrsV02-7-H0lt1RmpkxGpbI-11RQx61Vq9E,13267
|
|
|
11
11
|
mlrun/run.py,sha256=5Tz7OPDKkbaRLzLOmEjVBYecZR_BKd0gqtkKt_v4SbE,43524
|
|
12
12
|
mlrun/secrets.py,sha256=ibtCK79u7JVBZF6F0SP1-xXXF5MyrLEUs_TCWiJAnlc,7798
|
|
13
13
|
mlrun/alerts/__init__.py,sha256=0gtG1BG0DXxFrXegIkjbM1XEN4sP9ODo0ucXrNld1hU,601
|
|
14
|
-
mlrun/alerts/alert.py,sha256=
|
|
14
|
+
mlrun/alerts/alert.py,sha256=gLHAMJPzPs8jcSvHSqvfg22aDpk23s3VIHbZ4XeWgr0,10201
|
|
15
15
|
mlrun/api/schemas/__init__.py,sha256=fEWH4I8hr5AdRJ7yoW44RlFB6NHkYDxyomP5J6ct1z4,14248
|
|
16
16
|
mlrun/artifacts/__init__.py,sha256=daGrLqltI1nE3ES30nm-tanUnxReRzfyxyaxNRx2zbc,1168
|
|
17
17
|
mlrun/artifacts/base.py,sha256=EystjLta4XVdZP2x4nz1ZNlDUYKTIcFNfMVfBVseCHw,29168
|
|
@@ -37,7 +37,7 @@ mlrun/common/model_monitoring/__init__.py,sha256=x0EMEvxVjHsm858J1t6IEA9dtKTdFpJ
|
|
|
37
37
|
mlrun/common/model_monitoring/helpers.py,sha256=1CpxIDQPumFnpUB1eqcvCpLlyPFVeW2sL6prM-N5A1A,4405
|
|
38
38
|
mlrun/common/runtimes/constants.py,sha256=Rl0Sd8n_L7Imo-uF1LL9CJ5Szi0W1gUm36yrF8PXfSc,10989
|
|
39
39
|
mlrun/common/schemas/__init__.py,sha256=CUX4F6VeowqX5PzakB7xgGs2lJZAN42RMm1asB-kf1c,5227
|
|
40
|
-
mlrun/common/schemas/alert.py,sha256=
|
|
40
|
+
mlrun/common/schemas/alert.py,sha256=MG0yQ5am6FOKRb-86QKvS9rQtIALnduswq4OthmSgog,6570
|
|
41
41
|
mlrun/common/schemas/api_gateway.py,sha256=aEQ4rO5WyjAGIH7QJohctpftJi_SP4cTAfbmRi1ATwE,6920
|
|
42
42
|
mlrun/common/schemas/artifact.py,sha256=V3ngobnzI1v2eoOroWBEedjAZu0ntCSIQ-LzsOK1Z9k,3570
|
|
43
43
|
mlrun/common/schemas/auth.py,sha256=5c4WSn3KdX1v04ttSQblkF_gyjdjuJSHG7BTCx4_LWM,6336
|
|
@@ -55,7 +55,7 @@ mlrun/common/schemas/http.py,sha256=1PtYFhF6sqLSBRcuPMtYcUGmroBhaleqLmYidSdL9LM,
|
|
|
55
55
|
mlrun/common/schemas/hub.py,sha256=cuv_vpkO27XNCZzfytnUyi0k0ZA4wf_QRn5B0ZPoK-Y,4116
|
|
56
56
|
mlrun/common/schemas/k8s.py,sha256=nmMnhgjVMLem5jyumoG2eQKioGK9eUVhQnOSb3hG7yw,1395
|
|
57
57
|
mlrun/common/schemas/memory_reports.py,sha256=tpS3fpvxa6VcBpzCRzcZTt0fCF0h6ReUetYs7j6kdps,892
|
|
58
|
-
mlrun/common/schemas/notification.py,sha256=
|
|
58
|
+
mlrun/common/schemas/notification.py,sha256=uYVJJO7IKa4nac7TP2KBuhkI6TFtqstT2nLvve4kEWc,3080
|
|
59
59
|
mlrun/common/schemas/object.py,sha256=VleJSUmDJMl92knLgaDE8SWCi3ky0UaHcwcwOIapPQ8,1980
|
|
60
60
|
mlrun/common/schemas/pagination.py,sha256=q7nk6bipkDiE7HExIVqhy5ANl-zv0x8QC9Kg6AkLtDA,887
|
|
61
61
|
mlrun/common/schemas/pipeline.py,sha256=MhH07_fAQXNAnmf5j6oXZp8qh9cxGcZlReMdt-ZJf40,1429
|
|
@@ -88,7 +88,7 @@ mlrun/datastore/google_cloud_storage.py,sha256=Kj_2aqkFos5zoE6rGOBN27yWuuMc62mwG
|
|
|
88
88
|
mlrun/datastore/hdfs.py,sha256=TfL1zUWVRxEHF9kswZtOzrMdDmhSfiSVIAjz7fxWyVw,1876
|
|
89
89
|
mlrun/datastore/inmem.py,sha256=d2dIvHlOQylhc-i4B5Kk9e9ayXnF7DICc5yUlHcNwqs,2873
|
|
90
90
|
mlrun/datastore/redis.py,sha256=OKMkDCU3APhxfo65SyJq605u1DsfOYH0fODnCXZRqEU,5575
|
|
91
|
-
mlrun/datastore/s3.py,sha256=
|
|
91
|
+
mlrun/datastore/s3.py,sha256=FxydsakMF_c_VphBoT6p87bam1v4ZvwSPFq5M-6Z6c4,8686
|
|
92
92
|
mlrun/datastore/snowflake_utils.py,sha256=Wohvnlmq8j1d98RCaknll-iWdZZpSlCrKhUOEy0_-CA,1483
|
|
93
93
|
mlrun/datastore/sources.py,sha256=Mxn2aS42kSv7I6GrNixUHMjE8taEvs6-YQZE2L4Lsxg,46564
|
|
94
94
|
mlrun/datastore/spark_udf.py,sha256=NnnB3DZxZb-rqpRy7b-NC7QWXuuqFn3XkBDc86tU4mQ,1498
|
|
@@ -210,18 +210,18 @@ mlrun/launcher/factory.py,sha256=RW7mfzEFi8fR0M-4W1JQg1iq3_muUU6OTqT_3l4Ubrk,233
|
|
|
210
210
|
mlrun/launcher/local.py,sha256=pP9-ZrNL8OnNDEiXTAKAZQnmLpS_mCc2v-mJw329eks,11269
|
|
211
211
|
mlrun/launcher/remote.py,sha256=tGICSfWtvUHeR31mbzy6gqHejmDxjPUgjtxXTWhRubg,7699
|
|
212
212
|
mlrun/model_monitoring/__init__.py,sha256=dm5_j0_pwqrdzFwTaEtGnKfv2nVpNaM56nBI-oqLbNU,879
|
|
213
|
-
mlrun/model_monitoring/api.py,sha256=
|
|
213
|
+
mlrun/model_monitoring/api.py,sha256=grgMVJunQ0pA3dfLyaG0R7Amq_-NUUw7BNdBsedwfNw,28430
|
|
214
214
|
mlrun/model_monitoring/application.py,sha256=RJ8HeAPfGO3P2A_dEZYNg60c1wKTADh2YSv8BQ5embg,745
|
|
215
215
|
mlrun/model_monitoring/controller.py,sha256=kIwWgmUqVvh1qPWalibzIf0crYsDYYDEEYyagIEYqms,27890
|
|
216
216
|
mlrun/model_monitoring/evidently_application.py,sha256=iOc42IVjj8m6PDBmVcKIMWm46Bu0EdO9SDcH40Eqhyo,769
|
|
217
217
|
mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
|
|
218
|
-
mlrun/model_monitoring/helpers.py,sha256=
|
|
218
|
+
mlrun/model_monitoring/helpers.py,sha256=7uKQxaGcEkKCNcjXp4WsdiOS50Cy2H5BWPx6dOQbbG8,11587
|
|
219
219
|
mlrun/model_monitoring/model_endpoint.py,sha256=7VX0cBATqLsA4sSinDzouf41ndxqh2mf5bO9BW0G5Z4,4017
|
|
220
220
|
mlrun/model_monitoring/stream_processing.py,sha256=QLnqVgPWNJT_ydZU1yhwIiEl1gtNASqG4B_c5xCFbm4,37916
|
|
221
221
|
mlrun/model_monitoring/tracking_policy.py,sha256=sQq956akAQpntkrJwIgFWcEq-JpyVcg0FxgNa4h3V70,5502
|
|
222
|
-
mlrun/model_monitoring/writer.py,sha256=
|
|
222
|
+
mlrun/model_monitoring/writer.py,sha256=FsSmzF9fjb2mk-pmByOB1SZJ_NMBjCw4tGGXhkF3OJU,9954
|
|
223
223
|
mlrun/model_monitoring/applications/__init__.py,sha256=i793GqYee01mRh_KD6GShvX7UbPBgdJDO4qf9Z3BXEQ,970
|
|
224
|
-
mlrun/model_monitoring/applications/_application_steps.py,sha256=
|
|
224
|
+
mlrun/model_monitoring/applications/_application_steps.py,sha256=1e4LR2usVkGJ50uHF0-PAnXJo9HtxatrDmO1Znkb1Vc,6431
|
|
225
225
|
mlrun/model_monitoring/applications/base.py,sha256=snr3xYdqv6Po19yS0Z1VktyoLrbl88lljSFQyjnKjR0,11616
|
|
226
226
|
mlrun/model_monitoring/applications/context.py,sha256=LGRJdI1eyyssFzjE4W_rk2VAUV8KpOkUZUX3xCmnC9g,8537
|
|
227
227
|
mlrun/model_monitoring/applications/evidently_base.py,sha256=6hzfO6s0jEVHj4R_pujcn_p6LvdkKUDb9S4B6j2XEUY,8024
|
|
@@ -235,12 +235,12 @@ mlrun/model_monitoring/db/stores/sqldb/__init__.py,sha256=6CsTXAxeLbbf8yfCADTaxm
|
|
|
235
235
|
mlrun/model_monitoring/db/stores/sqldb/sql_store.py,sha256=yyrmOR34usE0ig1zVqXw6s9XWcDGtHpOVOi8fbtN4bY,25415
|
|
236
236
|
mlrun/model_monitoring/db/stores/sqldb/models/__init__.py,sha256=lCiGw9WKPtHAIgrtNS2jyvM5OZvZvogBh76iurNYblg,2453
|
|
237
237
|
mlrun/model_monitoring/db/stores/sqldb/models/base.py,sha256=V2B5WdQM0KHKq0FNDq61q7tkNJ9fNRbxfnxrholKgjk,5352
|
|
238
|
-
mlrun/model_monitoring/db/stores/sqldb/models/mysql.py,sha256=
|
|
238
|
+
mlrun/model_monitoring/db/stores/sqldb/models/mysql.py,sha256=4SfjS0Rz6hSvZwU4s_weQ1jk5IPvaCU1HLum459U5ig,3192
|
|
239
239
|
mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py,sha256=yJJZppbKj3PsOANS_DXAQFFHKX4cQcm6Pz2DoxRiXMk,1104
|
|
240
240
|
mlrun/model_monitoring/db/stores/v3io_kv/__init__.py,sha256=6CsTXAxeLbbf8yfCADTaxmiavqwrLEdYFJ-qc5kgDAY,569
|
|
241
|
-
mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py,sha256=
|
|
241
|
+
mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py,sha256=3plDwbm99J1q6QgTaPN_AaSC1q-6ckBNxxh2c4gAY8M,26318
|
|
242
242
|
mlrun/model_monitoring/db/tsdb/__init__.py,sha256=_Mfa4gguX86OS1fQCxnt_QSaNh603-zPYAK8NjYk7t8,4040
|
|
243
|
-
mlrun/model_monitoring/db/tsdb/base.py,sha256=
|
|
243
|
+
mlrun/model_monitoring/db/tsdb/base.py,sha256=GVY-G76iSptj_c7_uadBIGXCfWv5y4Q6ep79k1ysW7M,13630
|
|
244
244
|
mlrun/model_monitoring/db/tsdb/helpers.py,sha256=0oUXc4aUkYtP2SGP6jTb3uPPKImIUsVsrb9otX9a7O4,1189
|
|
245
245
|
mlrun/model_monitoring/db/tsdb/tdengine/__init__.py,sha256=vgBdsKaXUURKqIf3M0y4sRatmSVA4CQiJs7J5dcVBkQ,620
|
|
246
246
|
mlrun/model_monitoring/db/tsdb/tdengine/schemas.py,sha256=94u886UtyK40YNtdOX8WiJUImDytygdaqIzFwo_ExzI,8881
|
|
@@ -271,11 +271,11 @@ mlrun/package/utils/type_hint_utils.py,sha256=JYrek6vuN3z7e6MGUD3qBLDfQ03C4puZXN
|
|
|
271
271
|
mlrun/platforms/__init__.py,sha256=ggSGF7inITs6S-vj9u4S9X_5psgbA0G3GVqf7zu8qYc,2406
|
|
272
272
|
mlrun/platforms/iguazio.py,sha256=1h5BpdAEQJBg2vIt7ySjUADU0ip5OkaMYr0_VREi9ys,13084
|
|
273
273
|
mlrun/projects/__init__.py,sha256=Lv5rfxyXJrw6WGOWJKhBz66M6t3_zsNMCfUD6waPwx4,1153
|
|
274
|
-
mlrun/projects/operations.py,sha256=
|
|
274
|
+
mlrun/projects/operations.py,sha256=Bf1AmISGgBVcZYrLQdJzP9Oi1MWrN3vq0L0HNa_RKoU,19436
|
|
275
275
|
mlrun/projects/pipelines.py,sha256=_589S5rtZUV6cne1yPvOVhh3oB83fIwdQqNg47R2e6I,40608
|
|
276
|
-
mlrun/projects/project.py,sha256=
|
|
276
|
+
mlrun/projects/project.py,sha256=ikvso3d1OevX2mkSb7bqPQMg6LPBCk-5zzp58vTGRUg,184906
|
|
277
277
|
mlrun/runtimes/__init__.py,sha256=0-tYDkew-Cr4DM-wztvMbzDA5xq385Jjo-GrtO_84Sc,8741
|
|
278
|
-
mlrun/runtimes/base.py,sha256=
|
|
278
|
+
mlrun/runtimes/base.py,sha256=JXWmTIcm3b0klGUOHDlyFNa3bUgsNzQIgWhUQpSZoE0,37692
|
|
279
279
|
mlrun/runtimes/daskjob.py,sha256=JfK8rSPY-0SYnLJdtp_ts3oKyad0pA98th-2VntYzK0,19387
|
|
280
280
|
mlrun/runtimes/funcdoc.py,sha256=CC9cWRPgBiM2sk4NJTqusjc6O9kZ-49vGA5WRPjREKE,9796
|
|
281
281
|
mlrun/runtimes/function_reference.py,sha256=iWKRe4r2GTc5S8FOIASYUNLwwne8NqIui51PFr8Q4mg,4918
|
|
@@ -294,24 +294,24 @@ mlrun/runtimes/mpijob/abstract.py,sha256=kDWo-IY1FKLZhI30j38Xx9HMhlUvHezfd1DT2Sh
|
|
|
294
294
|
mlrun/runtimes/mpijob/v1.py,sha256=1XQZC7AIMGX_AQCbApcwpH8I7y39-v0v2O35MvxjXoo,3213
|
|
295
295
|
mlrun/runtimes/nuclio/__init__.py,sha256=gx1kizzKv8pGT5TNloN1js1hdbxqDw3rM90sLVYVffY,794
|
|
296
296
|
mlrun/runtimes/nuclio/api_gateway.py,sha256=lSqHspGhXuf53_JiEg_vBgWo-Ykkh2jUzzFqJ_Gd_lQ,25793
|
|
297
|
-
mlrun/runtimes/nuclio/function.py,sha256=
|
|
297
|
+
mlrun/runtimes/nuclio/function.py,sha256=hnJk6DR8ll50oeX9lF5Sj7fSqsLlnyNW9nhtZ04o7g8,50761
|
|
298
298
|
mlrun/runtimes/nuclio/nuclio.py,sha256=sLK8KdGO1LbftlL3HqPZlFOFTAAuxJACZCVl1c0Ha6E,2942
|
|
299
299
|
mlrun/runtimes/nuclio/serving.py,sha256=eUMqtIU6NYIVgKtxfxKN7pd9_QCo_V0aurrjUSU3s08,29754
|
|
300
300
|
mlrun/runtimes/nuclio/application/__init__.py,sha256=rRs5vasy_G9IyoTpYIjYDafGoL6ifFBKgBtsXn31Atw,614
|
|
301
|
-
mlrun/runtimes/nuclio/application/application.py,sha256=
|
|
301
|
+
mlrun/runtimes/nuclio/application/application.py,sha256=gbwR4RL95tcT-SRE_dMEv9c1LfzfDoxq9j6thuWNNu8,23420
|
|
302
302
|
mlrun/runtimes/nuclio/application/reverse_proxy.go,sha256=JIIYae6bXzCLf3jXuu49KWPQYoXr_FDQ2Rbo1OWKAd0,3150
|
|
303
303
|
mlrun/runtimes/sparkjob/__init__.py,sha256=_KPvk0qefeLtHO6lxQE_AMOGiMTG_OT48eRCE4Z2ldw,709
|
|
304
|
-
mlrun/runtimes/sparkjob/spark3job.py,sha256=
|
|
304
|
+
mlrun/runtimes/sparkjob/spark3job.py,sha256=l6leyuI49LGN8gMPbuFJltajNg6YoCFo20Q319HqvLU,40993
|
|
305
305
|
mlrun/serving/__init__.py,sha256=-SMRV3q_5cGVPDxRslXPU0zGYZIygs0cSj7WKlOJJUc,1163
|
|
306
306
|
mlrun/serving/merger.py,sha256=PXLn3A21FiLteJHaDSLm5xKNT-80eTTjfHUJnBX1gKY,6116
|
|
307
307
|
mlrun/serving/remote.py,sha256=MrFByphQWmIsKXqw-MOwl2Q1hbtWReYVRKvlcKj9pfw,17980
|
|
308
|
-
mlrun/serving/routers.py,sha256=
|
|
309
|
-
mlrun/serving/server.py,sha256=
|
|
308
|
+
mlrun/serving/routers.py,sha256=KEObS9QtFyOJlkELPHhgjwYZZyp_Z9fPH_aVptpC0y0,55351
|
|
309
|
+
mlrun/serving/server.py,sha256=HulfXvaZ3iFcf0bV1RA403B455ZLnPk9MulOBUQJJfA,21514
|
|
310
310
|
mlrun/serving/serving_wrapper.py,sha256=R670-S6PX_d5ER6jiHtRvacuPyFzQH0mEf2K0sBIIOM,836
|
|
311
|
-
mlrun/serving/states.py,sha256=
|
|
311
|
+
mlrun/serving/states.py,sha256=4bRZ9YZc-M_XcIGCtAq0Ubx7YoUgwB_0b7h4bsikmcM,59974
|
|
312
312
|
mlrun/serving/utils.py,sha256=lej7XcUPX1MmHkEOi_0KZRGSpfbmpnE0GK_Sn4zLkHY,4025
|
|
313
313
|
mlrun/serving/v1_serving.py,sha256=by4myxlnwyZ0ijQ5fURilGCK1sUpdQL2Il1VR3Xqpxg,11805
|
|
314
|
-
mlrun/serving/v2_serving.py,sha256=
|
|
314
|
+
mlrun/serving/v2_serving.py,sha256=2tTVQXVtVicOtT4ZH82_Bjq89LDC0BfQxq3QvuD5p_8,24518
|
|
315
315
|
mlrun/track/__init__.py,sha256=LWRUHJt8JyFW17FyNPOVyWd-NXTf1iptzsK9KFj5fuY,765
|
|
316
316
|
mlrun/track/tracker.py,sha256=hSi9sMxB7hhZalt6Q8GXDnK4UoCbXHzKTrpUPC9hZv4,3555
|
|
317
317
|
mlrun/track/tracker_manager.py,sha256=IYBl99I62IC6VCCmG1yt6JoHNOQXa53C4DURJ2sWgio,5726
|
|
@@ -341,11 +341,11 @@ mlrun/utils/notifications/notification/ipython.py,sha256=ZtVL30B_Ha0VGoo4LxO-voT
|
|
|
341
341
|
mlrun/utils/notifications/notification/slack.py,sha256=wqpFGr5BTvFO5KuUSzFfxsgmyU1Ohq7fbrGeNe9TXOk,7006
|
|
342
342
|
mlrun/utils/notifications/notification/webhook.py,sha256=cb9w1Mc8ENfJBdgan7iiVHK9eVls4-R3tUxmXM-P-8I,4746
|
|
343
343
|
mlrun/utils/version/__init__.py,sha256=7kkrB7hEZ3cLXoWj1kPoDwo4MaswsI2JVOBpbKgPAgc,614
|
|
344
|
-
mlrun/utils/version/version.json,sha256=
|
|
344
|
+
mlrun/utils/version/version.json,sha256=hlddDtaeIkEVdSQ-PWSqF6PX3bQRWWGTqCT7sUjJScA,89
|
|
345
345
|
mlrun/utils/version/version.py,sha256=eEW0tqIAkU9Xifxv8Z9_qsYnNhn3YH7NRAfM-pPLt1g,1878
|
|
346
|
-
mlrun-1.7.
|
|
347
|
-
mlrun-1.7.
|
|
348
|
-
mlrun-1.7.
|
|
349
|
-
mlrun-1.7.
|
|
350
|
-
mlrun-1.7.
|
|
351
|
-
mlrun-1.7.
|
|
346
|
+
mlrun-1.7.0rc37.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
347
|
+
mlrun-1.7.0rc37.dist-info/METADATA,sha256=bi7ocwF4P95Vh8fB8dA6gmE7F5z5QrT7uhz1bv4fp5A,19741
|
|
348
|
+
mlrun-1.7.0rc37.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
|
|
349
|
+
mlrun-1.7.0rc37.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
|
|
350
|
+
mlrun-1.7.0rc37.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
|
|
351
|
+
mlrun-1.7.0rc37.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|