mlrun 1.10.0rc13__py3-none-any.whl → 1.10.0rc42__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 +22 -2
- mlrun/artifacts/base.py +0 -31
- mlrun/artifacts/document.py +6 -1
- mlrun/artifacts/llm_prompt.py +123 -25
- mlrun/artifacts/manager.py +0 -5
- mlrun/artifacts/model.py +3 -3
- mlrun/common/constants.py +10 -1
- mlrun/common/formatters/artifact.py +1 -0
- mlrun/common/model_monitoring/helpers.py +86 -0
- mlrun/common/schemas/__init__.py +3 -0
- mlrun/common/schemas/auth.py +2 -0
- mlrun/common/schemas/function.py +10 -0
- mlrun/common/schemas/hub.py +30 -18
- mlrun/common/schemas/model_monitoring/__init__.py +3 -0
- mlrun/common/schemas/model_monitoring/constants.py +30 -6
- mlrun/common/schemas/model_monitoring/functions.py +14 -5
- mlrun/common/schemas/model_monitoring/model_endpoints.py +21 -0
- mlrun/common/schemas/pipeline.py +1 -1
- mlrun/common/schemas/serving.py +3 -0
- mlrun/common/schemas/workflow.py +3 -1
- mlrun/common/secrets.py +22 -1
- mlrun/config.py +33 -11
- mlrun/datastore/__init__.py +11 -3
- mlrun/datastore/azure_blob.py +162 -47
- mlrun/datastore/datastore.py +9 -4
- mlrun/datastore/datastore_profile.py +61 -5
- mlrun/datastore/model_provider/huggingface_provider.py +363 -0
- mlrun/datastore/model_provider/mock_model_provider.py +87 -0
- mlrun/datastore/model_provider/model_provider.py +230 -65
- mlrun/datastore/model_provider/openai_provider.py +295 -42
- mlrun/datastore/s3.py +24 -2
- mlrun/datastore/storeytargets.py +2 -3
- mlrun/datastore/utils.py +15 -3
- mlrun/db/base.py +47 -19
- mlrun/db/httpdb.py +120 -56
- mlrun/db/nopdb.py +38 -10
- mlrun/execution.py +70 -19
- mlrun/hub/__init__.py +15 -0
- mlrun/hub/module.py +181 -0
- mlrun/k8s_utils.py +105 -16
- mlrun/launcher/base.py +13 -6
- mlrun/launcher/local.py +15 -0
- mlrun/model.py +24 -3
- mlrun/model_monitoring/__init__.py +1 -0
- mlrun/model_monitoring/api.py +66 -27
- mlrun/model_monitoring/applications/__init__.py +1 -1
- mlrun/model_monitoring/applications/base.py +509 -117
- mlrun/model_monitoring/applications/context.py +2 -4
- mlrun/model_monitoring/applications/results.py +4 -7
- mlrun/model_monitoring/controller.py +239 -101
- mlrun/model_monitoring/db/_schedules.py +116 -33
- mlrun/model_monitoring/db/_stats.py +4 -3
- mlrun/model_monitoring/db/tsdb/base.py +100 -9
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +11 -6
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +191 -50
- mlrun/model_monitoring/db/tsdb/tdengine/writer_graph_steps.py +51 -0
- mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +17 -4
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +259 -40
- mlrun/model_monitoring/helpers.py +54 -9
- mlrun/model_monitoring/stream_processing.py +45 -14
- mlrun/model_monitoring/writer.py +220 -1
- mlrun/platforms/__init__.py +3 -2
- mlrun/platforms/iguazio.py +7 -3
- mlrun/projects/operations.py +6 -1
- mlrun/projects/pipelines.py +46 -26
- mlrun/projects/project.py +166 -58
- mlrun/run.py +94 -17
- mlrun/runtimes/__init__.py +18 -0
- mlrun/runtimes/base.py +14 -6
- mlrun/runtimes/daskjob.py +7 -0
- mlrun/runtimes/local.py +5 -2
- mlrun/runtimes/mounts.py +20 -2
- mlrun/runtimes/mpijob/abstract.py +6 -0
- mlrun/runtimes/mpijob/v1.py +6 -0
- mlrun/runtimes/nuclio/__init__.py +1 -0
- mlrun/runtimes/nuclio/application/application.py +149 -17
- mlrun/runtimes/nuclio/function.py +76 -27
- mlrun/runtimes/nuclio/serving.py +97 -15
- mlrun/runtimes/pod.py +234 -21
- mlrun/runtimes/remotesparkjob.py +6 -0
- mlrun/runtimes/sparkjob/spark3job.py +6 -0
- mlrun/runtimes/utils.py +49 -11
- mlrun/secrets.py +54 -13
- mlrun/serving/__init__.py +2 -0
- mlrun/serving/remote.py +79 -6
- mlrun/serving/routers.py +23 -41
- mlrun/serving/server.py +320 -80
- mlrun/serving/states.py +725 -157
- mlrun/serving/steps.py +62 -0
- mlrun/serving/system_steps.py +200 -119
- mlrun/serving/v2_serving.py +9 -10
- mlrun/utils/helpers.py +288 -88
- mlrun/utils/logger.py +3 -1
- mlrun/utils/notifications/notification/base.py +18 -0
- mlrun/utils/notifications/notification/git.py +2 -4
- mlrun/utils/notifications/notification/slack.py +2 -4
- mlrun/utils/notifications/notification/webhook.py +2 -5
- mlrun/utils/notifications/notification_pusher.py +1 -1
- mlrun/utils/retryer.py +15 -2
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.10.0rc13.dist-info → mlrun-1.10.0rc42.dist-info}/METADATA +45 -51
- {mlrun-1.10.0rc13.dist-info → mlrun-1.10.0rc42.dist-info}/RECORD +106 -101
- mlrun/api/schemas/__init__.py +0 -259
- {mlrun-1.10.0rc13.dist-info → mlrun-1.10.0rc42.dist-info}/WHEEL +0 -0
- {mlrun-1.10.0rc13.dist-info → mlrun-1.10.0rc42.dist-info}/entry_points.txt +0 -0
- {mlrun-1.10.0rc13.dist-info → mlrun-1.10.0rc42.dist-info}/licenses/LICENSE +0 -0
- {mlrun-1.10.0rc13.dist-info → mlrun-1.10.0rc42.dist-info}/top_level.txt +0 -0
mlrun/serving/remote.py
CHANGED
|
@@ -23,10 +23,14 @@ import storey
|
|
|
23
23
|
from storey.flow import _ConcurrentJobExecution
|
|
24
24
|
|
|
25
25
|
import mlrun
|
|
26
|
+
import mlrun.common.schemas
|
|
26
27
|
import mlrun.config
|
|
28
|
+
import mlrun.platforms
|
|
29
|
+
import mlrun.utils.async_http
|
|
27
30
|
from mlrun.errors import err_to_str
|
|
28
|
-
from mlrun.utils import logger
|
|
31
|
+
from mlrun.utils import dict_to_json, logger
|
|
29
32
|
|
|
33
|
+
from ..config import config
|
|
30
34
|
from .utils import (
|
|
31
35
|
_extract_input_data,
|
|
32
36
|
_update_result_body,
|
|
@@ -73,7 +77,9 @@ class RemoteStep(storey.SendToHttp):
|
|
|
73
77
|
|
|
74
78
|
:param url: http(s) url or function [project/]name to call
|
|
75
79
|
:param subpath: path (which follows the url), use `$path` to use the event.path
|
|
76
|
-
:param method: HTTP method (GET, POST,
|
|
80
|
+
:param method: The HTTP method to use for the request (e.g., "GET", "POST", "PUT", "DELETE").
|
|
81
|
+
If not provided, the step will try to use `event.method` at runtime, and if that
|
|
82
|
+
is also missing, it defaults to `"POST"`.
|
|
77
83
|
:param headers: dictionary with http header values
|
|
78
84
|
:param url_expression: an expression for getting the url from the event, e.g. "event['url']"
|
|
79
85
|
:param body_expression: an expression for getting the request body from the event, e.g. "event['data']"
|
|
@@ -150,8 +156,8 @@ class RemoteStep(storey.SendToHttp):
|
|
|
150
156
|
async def _process_event(self, event):
|
|
151
157
|
# async implementation (with storey)
|
|
152
158
|
body = self._get_event_or_body(event)
|
|
153
|
-
method, url, headers, body = self._generate_request(event, body)
|
|
154
|
-
kwargs = {}
|
|
159
|
+
method, url, headers, body, kwargs = self._generate_request(event, body)
|
|
160
|
+
kwargs = kwargs or {}
|
|
155
161
|
if self.timeout:
|
|
156
162
|
kwargs["timeout"] = aiohttp.ClientTimeout(total=self.timeout)
|
|
157
163
|
try:
|
|
@@ -191,7 +197,7 @@ class RemoteStep(storey.SendToHttp):
|
|
|
191
197
|
)
|
|
192
198
|
|
|
193
199
|
body = _extract_input_data(self._input_path, event.body)
|
|
194
|
-
method, url, headers, body = self._generate_request(event, body)
|
|
200
|
+
method, url, headers, body, kwargs = self._generate_request(event, body)
|
|
195
201
|
try:
|
|
196
202
|
resp = self._session.request(
|
|
197
203
|
method,
|
|
@@ -200,6 +206,7 @@ class RemoteStep(storey.SendToHttp):
|
|
|
200
206
|
headers=headers,
|
|
201
207
|
data=body,
|
|
202
208
|
timeout=self.timeout,
|
|
209
|
+
**kwargs,
|
|
203
210
|
)
|
|
204
211
|
except requests.exceptions.ReadTimeout as err:
|
|
205
212
|
raise requests.exceptions.ReadTimeout(
|
|
@@ -240,7 +247,7 @@ class RemoteStep(storey.SendToHttp):
|
|
|
240
247
|
body = json.dumps(body)
|
|
241
248
|
headers["Content-Type"] = "application/json"
|
|
242
249
|
|
|
243
|
-
return method, url, headers, body
|
|
250
|
+
return method, url, headers, body, {}
|
|
244
251
|
|
|
245
252
|
def _get_data(self, data, headers):
|
|
246
253
|
if (
|
|
@@ -454,3 +461,69 @@ class BatchHttpRequests(_ConcurrentJobExecution):
|
|
|
454
461
|
) and isinstance(data, (str, bytes)):
|
|
455
462
|
data = json.loads(data)
|
|
456
463
|
return data
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class MLRunAPIRemoteStep(RemoteStep):
|
|
467
|
+
def __init__(
|
|
468
|
+
self, method: str, path: str, fill_placeholders: Optional[bool] = None, **kwargs
|
|
469
|
+
):
|
|
470
|
+
"""
|
|
471
|
+
Graph step implementation for calling MLRun API endpoints
|
|
472
|
+
|
|
473
|
+
:param method: The HTTP method to use for the request (e.g., "GET", "POST", "PUT", "DELETE").
|
|
474
|
+
If not provided, the step will try to use `event.method` at runtime, and if that
|
|
475
|
+
is also missing, it defaults to `"POST"`.
|
|
476
|
+
:param path: API path (e.g. /api/projects)
|
|
477
|
+
:param fill_placeholders: if True, fill placeholders in the path using event fields (default to False)
|
|
478
|
+
:param kwargs: other arguments passed to RemoteStep
|
|
479
|
+
"""
|
|
480
|
+
super().__init__(url="", method=method, **kwargs)
|
|
481
|
+
self.rundb = None
|
|
482
|
+
self.path = path
|
|
483
|
+
self.fill_placeholders = fill_placeholders
|
|
484
|
+
|
|
485
|
+
def _generate_request(self, event, body):
|
|
486
|
+
method = self.method or event.method or "POST"
|
|
487
|
+
kw = {
|
|
488
|
+
key: value
|
|
489
|
+
for key, value in (
|
|
490
|
+
("params", body.get("params")),
|
|
491
|
+
("json", body.get("json")),
|
|
492
|
+
)
|
|
493
|
+
if value is not None
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
headers = self.headers or {}
|
|
497
|
+
headers.update(body.get("headers", {}))
|
|
498
|
+
|
|
499
|
+
if self.rundb.user:
|
|
500
|
+
kw["auth"] = (self.rundb.user, self.rundb.password)
|
|
501
|
+
elif self.rundb.token_provider:
|
|
502
|
+
token = self.rundb.token_provider.get_token()
|
|
503
|
+
if token:
|
|
504
|
+
# Iguazio auth doesn't support passing token through bearer, so use cookie instead
|
|
505
|
+
if self.rundb.token_provider.is_iguazio_session():
|
|
506
|
+
session_cookie = f'session=j:{{"sid": "{token}"}}'
|
|
507
|
+
headers["cookie"] = session_cookie
|
|
508
|
+
else:
|
|
509
|
+
if "Authorization" not in kw.setdefault("headers", {}):
|
|
510
|
+
headers.update({"Authorization": "Bearer " + token})
|
|
511
|
+
|
|
512
|
+
if mlrun.common.schemas.HeaderNames.client_version not in headers:
|
|
513
|
+
headers.update(
|
|
514
|
+
{
|
|
515
|
+
mlrun.common.schemas.HeaderNames.client_version: self.rundb.client_version,
|
|
516
|
+
mlrun.common.schemas.HeaderNames.python_version: self.rundb.python_version,
|
|
517
|
+
"User-Agent": f"{requests.utils.default_user_agent()} mlrun/{config.version}",
|
|
518
|
+
}
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
url = self.url.format(**body) if self.fill_placeholders else self.url
|
|
522
|
+
headers["Content-Type"] = "application/json"
|
|
523
|
+
return method, url, headers, dict_to_json(body), kw
|
|
524
|
+
|
|
525
|
+
def post_init(self, mode="sync", **kwargs):
|
|
526
|
+
super().post_init(mode=mode, **kwargs)
|
|
527
|
+
self.fill_placeholders = self.fill_placeholders or False
|
|
528
|
+
self.rundb = mlrun.get_run_db()
|
|
529
|
+
self.url = self.rundb.get_base_api_url(self.path)
|
mlrun/serving/routers.py
CHANGED
|
@@ -31,6 +31,9 @@ import mlrun.common.model_monitoring
|
|
|
31
31
|
import mlrun.common.schemas.model_monitoring
|
|
32
32
|
from mlrun.utils import logger, now_date
|
|
33
33
|
|
|
34
|
+
from ..common.model_monitoring.helpers import (
|
|
35
|
+
get_model_endpoints_creation_task_status,
|
|
36
|
+
)
|
|
34
37
|
from .utils import RouterToDict, _extract_input_data, _update_result_body
|
|
35
38
|
from .v2_serving import _ModelLogPusher
|
|
36
39
|
|
|
@@ -171,46 +174,6 @@ class BaseModelRouter(RouterToDict):
|
|
|
171
174
|
"""run tasks after processing the event"""
|
|
172
175
|
return event
|
|
173
176
|
|
|
174
|
-
def _get_background_task_status(
|
|
175
|
-
self,
|
|
176
|
-
) -> mlrun.common.schemas.BackgroundTaskState:
|
|
177
|
-
self._background_task_check_timestamp = now_date()
|
|
178
|
-
server: mlrun.serving.GraphServer = getattr(
|
|
179
|
-
self.context, "_server", None
|
|
180
|
-
) or getattr(self.context, "server", None)
|
|
181
|
-
if not self.context.is_mock:
|
|
182
|
-
if server.model_endpoint_creation_task_name:
|
|
183
|
-
background_task = mlrun.get_run_db().get_project_background_task(
|
|
184
|
-
server.project, server.model_endpoint_creation_task_name
|
|
185
|
-
)
|
|
186
|
-
logger.debug(
|
|
187
|
-
"Checking model endpoint creation task status",
|
|
188
|
-
task_name=server.model_endpoint_creation_task_name,
|
|
189
|
-
)
|
|
190
|
-
if (
|
|
191
|
-
background_task.status.state
|
|
192
|
-
in mlrun.common.schemas.BackgroundTaskState.terminal_states()
|
|
193
|
-
):
|
|
194
|
-
logger.info(
|
|
195
|
-
f"Model endpoint creation task completed with state {background_task.status.state}"
|
|
196
|
-
)
|
|
197
|
-
else: # in progress
|
|
198
|
-
logger.info(
|
|
199
|
-
f"Model endpoint creation task is still in progress with the current state: "
|
|
200
|
-
f"{background_task.status.state}. Events will not be monitored for the next "
|
|
201
|
-
f"{mlrun.mlconf.model_endpoint_monitoring.model_endpoint_creation_check_period} seconds",
|
|
202
|
-
name=self.name,
|
|
203
|
-
background_task_check_timestamp=self._background_task_check_timestamp.isoformat(),
|
|
204
|
-
)
|
|
205
|
-
return background_task.status.state
|
|
206
|
-
else:
|
|
207
|
-
logger.error(
|
|
208
|
-
"Model endpoint creation task name not provided. This function is not being monitored.",
|
|
209
|
-
)
|
|
210
|
-
elif self.context.monitoring_mock:
|
|
211
|
-
return mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
212
|
-
return mlrun.common.schemas.BackgroundTaskState.failed
|
|
213
|
-
|
|
214
177
|
def _update_background_task_state(self, event):
|
|
215
178
|
if not self.background_task_reached_terminal_state and (
|
|
216
179
|
self._background_task_check_timestamp is None
|
|
@@ -219,7 +182,26 @@ class BaseModelRouter(RouterToDict):
|
|
|
219
182
|
seconds=mlrun.mlconf.model_endpoint_monitoring.model_endpoint_creation_check_period
|
|
220
183
|
)
|
|
221
184
|
):
|
|
222
|
-
|
|
185
|
+
server: mlrun.serving.GraphServer = getattr(
|
|
186
|
+
self.context, "_server", None
|
|
187
|
+
) or getattr(self.context, "server", None)
|
|
188
|
+
if not self.context.is_mock:
|
|
189
|
+
(
|
|
190
|
+
self._background_task_current_state,
|
|
191
|
+
self._background_task_check_timestamp,
|
|
192
|
+
_,
|
|
193
|
+
) = get_model_endpoints_creation_task_status(server)
|
|
194
|
+
elif self.context.monitoring_mock:
|
|
195
|
+
self._background_task_current_state = (
|
|
196
|
+
mlrun.common.schemas.BackgroundTaskState.succeeded
|
|
197
|
+
)
|
|
198
|
+
self._background_task_check_timestamp = mlrun.utils.now_date()
|
|
199
|
+
else:
|
|
200
|
+
self._background_task_current_state = (
|
|
201
|
+
mlrun.common.schemas.BackgroundTaskState.failed
|
|
202
|
+
)
|
|
203
|
+
self._background_task_check_timestamp = mlrun.utils.now_date()
|
|
204
|
+
|
|
223
205
|
if event.body:
|
|
224
206
|
event.body["background_task_state"] = (
|
|
225
207
|
self._background_task_current_state
|