mlrun 1.10.0rc27__py3-none-any.whl → 1.10.0rc29__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 +1 -0
- mlrun/common/schemas/hub.py +5 -0
- mlrun/config.py +2 -1
- mlrun/datastore/azure_blob.py +98 -17
- mlrun/datastore/utils.py +9 -3
- mlrun/db/base.py +1 -0
- mlrun/db/httpdb.py +4 -1
- mlrun/db/nopdb.py +1 -0
- mlrun/hub/__init__.py +15 -0
- mlrun/hub/module.py +166 -0
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +38 -7
- mlrun/model_monitoring/helpers.py +23 -0
- mlrun/projects/operations.py +6 -1
- mlrun/projects/project.py +6 -1
- mlrun/runtimes/base.py +10 -3
- mlrun/runtimes/nuclio/application/application.py +6 -0
- mlrun/runtimes/nuclio/serving.py +12 -0
- mlrun/runtimes/pod.py +1 -0
- mlrun/serving/states.py +13 -4
- mlrun/utils/helpers.py +49 -38
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.10.0rc27.dist-info → mlrun-1.10.0rc29.dist-info}/METADATA +2 -2
- {mlrun-1.10.0rc27.dist-info → mlrun-1.10.0rc29.dist-info}/RECORD +27 -25
- {mlrun-1.10.0rc27.dist-info → mlrun-1.10.0rc29.dist-info}/WHEEL +0 -0
- {mlrun-1.10.0rc27.dist-info → mlrun-1.10.0rc29.dist-info}/entry_points.txt +0 -0
- {mlrun-1.10.0rc27.dist-info → mlrun-1.10.0rc29.dist-info}/licenses/LICENSE +0 -0
- {mlrun-1.10.0rc27.dist-info → mlrun-1.10.0rc29.dist-info}/top_level.txt +0 -0
mlrun/__init__.py
CHANGED
|
@@ -37,6 +37,7 @@ from .datastore import DataItem, ModelProvider, store_manager
|
|
|
37
37
|
from .db import get_run_db
|
|
38
38
|
from .errors import MLRunInvalidArgumentError, MLRunNotFoundError
|
|
39
39
|
from .execution import MLClientCtx
|
|
40
|
+
from .hub import get_hub_module, import_module
|
|
40
41
|
from .model import RunObject, RunTemplate, new_task
|
|
41
42
|
from .package import ArtifactType, DefaultPackager, Packager, handler
|
|
42
43
|
from .projects import (
|
mlrun/common/schemas/hub.py
CHANGED
|
@@ -134,3 +134,8 @@ class HubCatalog(BaseModel):
|
|
|
134
134
|
kind: ObjectKind = Field(ObjectKind.hub_catalog, const=True)
|
|
135
135
|
channel: str
|
|
136
136
|
catalog: list[HubItem]
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class HubModuleType(mlrun.common.types.StrEnum):
|
|
140
|
+
generic = "generic"
|
|
141
|
+
monitoring_app = "monitoring-app"
|
mlrun/config.py
CHANGED
|
@@ -255,7 +255,8 @@ default_config = {
|
|
|
255
255
|
},
|
|
256
256
|
"runtimes": {
|
|
257
257
|
"dask": "600",
|
|
258
|
-
|
|
258
|
+
# cluster start might take some time in case k8s needs to spin up new nodes
|
|
259
|
+
"dask_cluster_start": "600",
|
|
259
260
|
},
|
|
260
261
|
"push_notifications": "60",
|
|
261
262
|
},
|
mlrun/datastore/azure_blob.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright
|
|
1
|
+
# Copyright 2025 Iguazio
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
import contextlib
|
|
15
16
|
import time
|
|
16
17
|
from pathlib import Path
|
|
17
18
|
from typing import Optional
|
|
@@ -30,6 +31,40 @@ from .base import DataStore, FileStats, make_datastore_schema_sanitizer
|
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
class AzureBlobStore(DataStore):
|
|
34
|
+
"""
|
|
35
|
+
Azure Blob Storage datastore implementation.
|
|
36
|
+
|
|
37
|
+
Supports multiple URL schemas: az://, wasbs://, wasb://
|
|
38
|
+
|
|
39
|
+
Supported Connection String Formats:
|
|
40
|
+
====================================
|
|
41
|
+
|
|
42
|
+
1. Account Key (Standard):
|
|
43
|
+
"DefaultEndpointsProtocol=https;AccountName=<account>;AccountKey=<key>;EndpointSuffix=core.windows.net"
|
|
44
|
+
|
|
45
|
+
2. SAS Token:
|
|
46
|
+
"BlobEndpoint=https://<account>.blob.core.windows.net/;SharedAccessSignature=<sas_token>"
|
|
47
|
+
|
|
48
|
+
3. Minimal BlobEndpoint:
|
|
49
|
+
"BlobEndpoint=https://<account>.blob.core.windows.net/;AccountName=<account>;AccountKey=<key>"
|
|
50
|
+
|
|
51
|
+
4. Custom Domain:
|
|
52
|
+
"BlobEndpoint=https://<account>.mydomain.com/;AccountName=<account>;AccountKey=<key>"
|
|
53
|
+
|
|
54
|
+
5. China/Government Cloud:
|
|
55
|
+
"DefaultEndpointsProtocol=https;AccountName=<account>;AccountKey=<key>;EndpointSuffix=core.chinacloudapi.cn"
|
|
56
|
+
|
|
57
|
+
6. Full Service Endpoints with SAS:
|
|
58
|
+
"BlobEndpoint=https://<account>.blob.core.windows.net/;QueueEndpoint=...;SharedAccessSignature=<sas>"
|
|
59
|
+
|
|
60
|
+
Authentication Methods:
|
|
61
|
+
======================
|
|
62
|
+
- Account Key (connection_string or storage_options)
|
|
63
|
+
- SAS Token (connection_string or storage_options)
|
|
64
|
+
- OAuth/Azure AD (storage_options: client_id, client_secret, tenant_id)
|
|
65
|
+
|
|
66
|
+
"""
|
|
67
|
+
|
|
33
68
|
using_bucket = True
|
|
34
69
|
max_concurrency = 100
|
|
35
70
|
max_blocksize = 1024 * 1024 * 4
|
|
@@ -40,6 +75,12 @@ class AzureBlobStore(DataStore):
|
|
|
40
75
|
def __init__(
|
|
41
76
|
self, parent, schema, name, endpoint="", secrets: Optional[dict] = None
|
|
42
77
|
):
|
|
78
|
+
# Extract container from WASBS endpoint before calling super()
|
|
79
|
+
self._container_from_endpoint = None
|
|
80
|
+
if schema in ["wasbs", "wasb"] and endpoint and "@" in endpoint:
|
|
81
|
+
# Handle container@host format
|
|
82
|
+
self._container_from_endpoint, endpoint = endpoint.split("@", 1)
|
|
83
|
+
|
|
43
84
|
super().__init__(parent, name, schema, endpoint, secrets=secrets)
|
|
44
85
|
self._service_client = None
|
|
45
86
|
self._storage_options = None
|
|
@@ -67,6 +108,34 @@ class AzureBlobStore(DataStore):
|
|
|
67
108
|
or self._get_secret_or_env("AZURE_STORAGE_SAS_TOKEN"),
|
|
68
109
|
credential=self._get_secret_or_env("credential"),
|
|
69
110
|
)
|
|
111
|
+
# Use container extracted from WASBS endpoint during initialization
|
|
112
|
+
if self._container_from_endpoint:
|
|
113
|
+
res["container"] = self._container_from_endpoint
|
|
114
|
+
|
|
115
|
+
# For az:// URLs, endpoint contains the container name
|
|
116
|
+
if not res.get("container") and self.kind in ["az"]:
|
|
117
|
+
if container := getattr(self, "endpoint", None):
|
|
118
|
+
res["container"] = container
|
|
119
|
+
|
|
120
|
+
# Last resort: For wasbs:// without container, check if connection string has BlobEndpoint with container
|
|
121
|
+
if not res.get("container") and self.kind in ["wasbs", "wasb"]:
|
|
122
|
+
connection_string = res.get("connection_string")
|
|
123
|
+
if connection_string and "BlobEndpoint=" in connection_string:
|
|
124
|
+
# Try to extract container from BlobEndpoint URL
|
|
125
|
+
for part in connection_string.split(";"):
|
|
126
|
+
if part.startswith("BlobEndpoint="):
|
|
127
|
+
blob_endpoint = part.split("=", 1)[1]
|
|
128
|
+
# Parse URL to get path component
|
|
129
|
+
from urllib.parse import urlparse
|
|
130
|
+
|
|
131
|
+
parsed = urlparse(blob_endpoint)
|
|
132
|
+
if parsed.path and parsed.path.strip("/"):
|
|
133
|
+
# Extract first path segment as container
|
|
134
|
+
path_parts = parsed.path.strip("/").split("/")
|
|
135
|
+
if path_parts[0]:
|
|
136
|
+
res["container"] = path_parts[0]
|
|
137
|
+
break
|
|
138
|
+
|
|
70
139
|
self._storage_options = self._sanitize_options(res)
|
|
71
140
|
return self._storage_options
|
|
72
141
|
|
|
@@ -243,10 +312,12 @@ class AzureBlobStore(DataStore):
|
|
|
243
312
|
|
|
244
313
|
for key in ["account_name", "account_key", "sas_token"]:
|
|
245
314
|
if parsed_value := parsed_credential.get(key):
|
|
246
|
-
if
|
|
315
|
+
# Only check for conflicts if storage options has a non-empty value for this key
|
|
316
|
+
existing_value = st.get(key)
|
|
317
|
+
if existing_value and existing_value != parsed_value:
|
|
247
318
|
if key == "account_name":
|
|
248
319
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
249
|
-
f"Storage option for '{key}' is '{
|
|
320
|
+
f"Storage option for '{key}' is '{existing_value}', "
|
|
250
321
|
f"which does not match corresponding connection string '{parsed_value}'"
|
|
251
322
|
)
|
|
252
323
|
else:
|
|
@@ -262,7 +333,8 @@ class AzureBlobStore(DataStore):
|
|
|
262
333
|
primary_url = primary_url[len("http://") :]
|
|
263
334
|
if primary_url.startswith("https://"):
|
|
264
335
|
primary_url = primary_url[len("https://") :]
|
|
265
|
-
|
|
336
|
+
# Remove any path components from the host
|
|
337
|
+
host = primary_url.split("/")[0]
|
|
266
338
|
elif account_name:
|
|
267
339
|
host = f"{account_name}.{service}.core.windows.net"
|
|
268
340
|
else:
|
|
@@ -278,7 +350,10 @@ class AzureBlobStore(DataStore):
|
|
|
278
350
|
# --- WASB + SAS (container-scoped key; no provider classes needed) ---
|
|
279
351
|
if "sas_token" in st and st["sas_token"]:
|
|
280
352
|
sas = st["sas_token"].lstrip("?")
|
|
281
|
-
|
|
353
|
+
|
|
354
|
+
container = st.get("container")
|
|
355
|
+
|
|
356
|
+
if container:
|
|
282
357
|
# fs.azure.sas.<container>.<account>.blob.core.windows.net = <sas>
|
|
283
358
|
res[f"spark.hadoop.fs.azure.sas.{container}.{host}"] = sas
|
|
284
359
|
|
|
@@ -295,11 +370,12 @@ class AzureBlobStore(DataStore):
|
|
|
295
370
|
st = self.storage_options
|
|
296
371
|
service = "blob"
|
|
297
372
|
|
|
298
|
-
container =
|
|
373
|
+
container = st.get("container")
|
|
374
|
+
|
|
299
375
|
if not container:
|
|
300
376
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
301
|
-
"Container is required to build the WASB URL "
|
|
302
|
-
"
|
|
377
|
+
"Container name is required to build the WASB URL. "
|
|
378
|
+
"Set storage_options['container'] or use datastore profile with container specified."
|
|
303
379
|
)
|
|
304
380
|
|
|
305
381
|
# Prefer host from connection string; else synthesize from account_name
|
|
@@ -308,18 +384,23 @@ class AzureBlobStore(DataStore):
|
|
|
308
384
|
connection_string = st.get("connection_string")
|
|
309
385
|
|
|
310
386
|
if connection_string:
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
387
|
+
with contextlib.suppress(Exception):
|
|
388
|
+
primary_url, _, _ = parse_connection_str(
|
|
389
|
+
connection_string, credential=None, service=service
|
|
390
|
+
)
|
|
391
|
+
if primary_url.startswith("http://"):
|
|
392
|
+
primary_url = primary_url[len("http://") :]
|
|
393
|
+
if primary_url.startswith("https://"):
|
|
394
|
+
primary_url = primary_url[len("https://") :]
|
|
395
|
+
# Remove any path components from the host
|
|
396
|
+
host = primary_url.split("/")[0].rstrip("/")
|
|
320
397
|
if not host and account_name:
|
|
321
398
|
host = f"{account_name}.{service}.core.windows.net"
|
|
322
399
|
|
|
400
|
+
# For wasbs:// URLs where endpoint is already the host
|
|
401
|
+
if not host and self.kind in ["wasbs", "wasb"] and hasattr(self, "endpoint"):
|
|
402
|
+
host = getattr(self, "endpoint", None)
|
|
403
|
+
|
|
323
404
|
if not host:
|
|
324
405
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
325
406
|
"account_name is required (or provide a connection_string) to build the WASB URL."
|
mlrun/datastore/utils.py
CHANGED
|
@@ -320,7 +320,13 @@ def parse_url(url):
|
|
|
320
320
|
parsed_url = urlparse(url)
|
|
321
321
|
schema = parsed_url.scheme.lower()
|
|
322
322
|
endpoint = parsed_url.hostname
|
|
323
|
-
|
|
323
|
+
|
|
324
|
+
# Special handling for WASBS URLs to preserve container information
|
|
325
|
+
if schema in ["wasbs", "wasb"] and parsed_url.netloc and "@" in parsed_url.netloc:
|
|
326
|
+
# For wasbs://container@host format, preserve the full netloc as endpoint
|
|
327
|
+
# This allows the datastore to extract container later
|
|
328
|
+
endpoint = parsed_url.netloc
|
|
329
|
+
elif endpoint:
|
|
324
330
|
# HACK - urlparse returns the hostname after in lower case - we want the original case:
|
|
325
331
|
# the hostname is a substring of the netloc, in which it's the original case, so we find the indexes of the
|
|
326
332
|
# hostname in the netloc and take it from there
|
|
@@ -331,8 +337,8 @@ def parse_url(url):
|
|
|
331
337
|
endpoint = netloc[
|
|
332
338
|
hostname_index_in_netloc : hostname_index_in_netloc + len(lower_hostname)
|
|
333
339
|
]
|
|
334
|
-
|
|
335
|
-
|
|
340
|
+
if parsed_url.port:
|
|
341
|
+
endpoint += f":{parsed_url.port}"
|
|
336
342
|
return schema, endpoint, parsed_url
|
|
337
343
|
|
|
338
344
|
|
mlrun/db/base.py
CHANGED
|
@@ -774,6 +774,7 @@ class RunDBInterface(ABC):
|
|
|
774
774
|
item_name: Optional[str] = None,
|
|
775
775
|
tag: Optional[str] = None,
|
|
776
776
|
version: Optional[str] = None,
|
|
777
|
+
item_type: mlrun.common.schemas.hub.HubSourceType = mlrun.common.schemas.hub.HubSourceType.functions,
|
|
777
778
|
):
|
|
778
779
|
pass
|
|
779
780
|
|
mlrun/db/httpdb.py
CHANGED
|
@@ -4310,6 +4310,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4310
4310
|
item_name: Optional[str] = None,
|
|
4311
4311
|
tag: Optional[str] = None,
|
|
4312
4312
|
version: Optional[str] = None,
|
|
4313
|
+
item_type: HubSourceType = HubSourceType.functions,
|
|
4313
4314
|
) -> list[mlrun.common.schemas.hub.IndexedHubSource]:
|
|
4314
4315
|
"""
|
|
4315
4316
|
List hub sources in the MLRun DB.
|
|
@@ -4317,6 +4318,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4317
4318
|
:param item_name: Sources contain this item will be returned, If not provided all sources will be returned.
|
|
4318
4319
|
:param tag: Item tag to filter by, supported only if item name is provided.
|
|
4319
4320
|
:param version: Item version to filter by, supported only if item name is provided and tag is not.
|
|
4321
|
+
:param item_type: Item type to filter by, supported only if item name is provided.
|
|
4320
4322
|
|
|
4321
4323
|
:returns: List of indexed hub sources.
|
|
4322
4324
|
"""
|
|
@@ -4324,6 +4326,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
4324
4326
|
params = {}
|
|
4325
4327
|
if item_name:
|
|
4326
4328
|
params["item-name"] = normalize_name(item_name)
|
|
4329
|
+
params["item-type"] = item_type
|
|
4327
4330
|
if tag:
|
|
4328
4331
|
params["tag"] = tag
|
|
4329
4332
|
if version:
|
|
@@ -5200,7 +5203,7 @@ class HTTPRunDB(RunDBInterface):
|
|
|
5200
5203
|
|
|
5201
5204
|
:return: A ModelEndpointDriftValues object containing the drift counts over time.
|
|
5202
5205
|
"""
|
|
5203
|
-
endpoint_path = f"projects/{project}/model-
|
|
5206
|
+
endpoint_path = f"projects/{project}/model-monitoring/drift-over-time"
|
|
5204
5207
|
error_message = f"Failed retrieving drift data for {project}"
|
|
5205
5208
|
response = self.api_call(
|
|
5206
5209
|
method="GET",
|
mlrun/db/nopdb.py
CHANGED
|
@@ -673,6 +673,7 @@ class NopDB(RunDBInterface):
|
|
|
673
673
|
item_name: Optional[str] = None,
|
|
674
674
|
tag: Optional[str] = None,
|
|
675
675
|
version: Optional[str] = None,
|
|
676
|
+
item_type: mlrun.common.schemas.hub.HubSourceType = mlrun.common.schemas.hub.HubSourceType.functions,
|
|
676
677
|
):
|
|
677
678
|
pass
|
|
678
679
|
|
mlrun/hub/__init__.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright 2025 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
from .module import get_hub_module, import_module
|
mlrun/hub/module.py
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Copyright 2025 Iguazio
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
import os
|
|
16
|
+
import subprocess
|
|
17
|
+
import sys
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Optional, Union
|
|
20
|
+
|
|
21
|
+
import yaml
|
|
22
|
+
|
|
23
|
+
import mlrun.common.types
|
|
24
|
+
import mlrun.utils
|
|
25
|
+
from mlrun.common.schemas.hub import HubModuleType, HubSourceType
|
|
26
|
+
from mlrun.run import function_to_module, get_object
|
|
27
|
+
from mlrun.utils import logger
|
|
28
|
+
|
|
29
|
+
from ..model import ModelObj
|
|
30
|
+
from ..utils import extend_hub_uri_if_needed
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class HubModule(ModelObj):
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
name: str,
|
|
37
|
+
kind: Union[HubModuleType, str],
|
|
38
|
+
version: Optional[str] = None,
|
|
39
|
+
description: Optional[str] = None,
|
|
40
|
+
categories: Optional[list] = None,
|
|
41
|
+
requirements: Optional[list] = None,
|
|
42
|
+
local_path: Optional[str] = None,
|
|
43
|
+
filename: Optional[str] = None,
|
|
44
|
+
example: Optional[str] = None,
|
|
45
|
+
url: Optional[str] = None,
|
|
46
|
+
**kwargs, # catch all for unused args
|
|
47
|
+
):
|
|
48
|
+
self.name: str = name
|
|
49
|
+
self.version: str = version
|
|
50
|
+
self.kind: HubModuleType = kind
|
|
51
|
+
self.description: str = description or ""
|
|
52
|
+
self.categories: list = categories or []
|
|
53
|
+
self.requirements: list = requirements or []
|
|
54
|
+
self.local_path: str = local_path or ""
|
|
55
|
+
self.filename: str = filename or name + ".py"
|
|
56
|
+
self.example: str = example or ""
|
|
57
|
+
self.url: str = url or ""
|
|
58
|
+
|
|
59
|
+
def module(self):
|
|
60
|
+
"""Import the module after downloading its fils to local_path"""
|
|
61
|
+
try:
|
|
62
|
+
return function_to_module(code=self.filename, workdir=self.local_path)
|
|
63
|
+
except FileNotFoundError:
|
|
64
|
+
searched_path = self.local_path or "./"
|
|
65
|
+
raise FileNotFoundError(
|
|
66
|
+
f"Module file {self.filename} not found in {searched_path}, try calling download_module_files() first"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def install_requirements(self) -> None:
|
|
70
|
+
"""
|
|
71
|
+
Install pip-style requirements (e.g., ["pandas>=2.0.0", "requests==2.31.0"]).
|
|
72
|
+
"""
|
|
73
|
+
for req in self.requirements:
|
|
74
|
+
logger.info(f"Installing {req} ...")
|
|
75
|
+
try:
|
|
76
|
+
subprocess.run(
|
|
77
|
+
[sys.executable, "-m", "pip", "install", req], check=True, text=True
|
|
78
|
+
)
|
|
79
|
+
logger.info(f"Installed {req}")
|
|
80
|
+
except subprocess.CalledProcessError as e:
|
|
81
|
+
logger.error(f"Failed to install {req} (exit code {e.returncode})")
|
|
82
|
+
|
|
83
|
+
def download_module_files(self, local_path=None, secrets=None):
|
|
84
|
+
"""
|
|
85
|
+
Download this hub module’s files (code file and, if available, an example notebook) to the target directory
|
|
86
|
+
specified by `local_path` (defaults to the current working directory).
|
|
87
|
+
This path will be used later to locate the code file when importing the module.
|
|
88
|
+
"""
|
|
89
|
+
self.local_path = self.verify_directory(path=local_path)
|
|
90
|
+
source_url, _ = extend_hub_uri_if_needed(
|
|
91
|
+
uri=self.url, asset_type=HubSourceType.modules, file=self.filename
|
|
92
|
+
)
|
|
93
|
+
self._download_object(
|
|
94
|
+
obj_url=source_url, target_name=self.filename, secrets=secrets
|
|
95
|
+
)
|
|
96
|
+
if self.example:
|
|
97
|
+
example_url, _ = extend_hub_uri_if_needed(
|
|
98
|
+
uri=self.url, asset_type=HubSourceType.modules, file=self.example
|
|
99
|
+
)
|
|
100
|
+
self._download_object(
|
|
101
|
+
obj_url=example_url, target_name=self.example, secrets=secrets
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
def _download_object(self, obj_url, target_name, secrets=None):
|
|
105
|
+
data = get_object(url=obj_url, secrets=secrets)
|
|
106
|
+
target_dir = self.local_path if self.local_path is not None else os.getcwd()
|
|
107
|
+
target_filepath = os.path.join(target_dir, target_name)
|
|
108
|
+
with open(target_filepath, "wb") as f:
|
|
109
|
+
f.write(data)
|
|
110
|
+
|
|
111
|
+
@staticmethod
|
|
112
|
+
def verify_directory(path: str) -> Path:
|
|
113
|
+
"""Validate that the given path is an existing directory."""
|
|
114
|
+
if path:
|
|
115
|
+
path = Path(path)
|
|
116
|
+
if not path.exists():
|
|
117
|
+
raise ValueError(f"Path does not exist: {path}")
|
|
118
|
+
if not path.is_dir():
|
|
119
|
+
raise ValueError(f"Path is not a directory: {path}")
|
|
120
|
+
return path
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def get_hub_module(
|
|
124
|
+
url="", download_files=True, secrets=None, local_path=None
|
|
125
|
+
) -> HubModule:
|
|
126
|
+
"""
|
|
127
|
+
Get a hub-module object containing metadata of the requested module.
|
|
128
|
+
:param url: Hub module url in the format "hub://[<source>/]<item-name>[:<tag>]"
|
|
129
|
+
:param download_files: When set to True, the module files (code file and example notebook) are downloaded
|
|
130
|
+
:param secrets: Optional, credentials dict for DB or URL (s3, v3io, ...)
|
|
131
|
+
:param local_path: Path to target directory for the module files. Ignored when download_files is set to False.
|
|
132
|
+
Defaults to the current working directory.
|
|
133
|
+
|
|
134
|
+
:return: HubModule object
|
|
135
|
+
"""
|
|
136
|
+
item_yaml_url, is_hub_uri = extend_hub_uri_if_needed(
|
|
137
|
+
uri=url, asset_type=HubSourceType.modules, file="item.yaml"
|
|
138
|
+
)
|
|
139
|
+
if not is_hub_uri:
|
|
140
|
+
raise mlrun.errors.MLRunInvalidArgumentError("Not a valid hub URL")
|
|
141
|
+
yaml_obj = get_object(url=item_yaml_url, secrets=secrets)
|
|
142
|
+
item_yaml = yaml.safe_load(yaml_obj)
|
|
143
|
+
spec = item_yaml.pop("spec", {})
|
|
144
|
+
hub_module = HubModule(**item_yaml, **spec, url=url)
|
|
145
|
+
if download_files:
|
|
146
|
+
hub_module.download_module_files(local_path=local_path, secrets=secrets)
|
|
147
|
+
return hub_module
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def import_module(url="", install_requirements=False, secrets=None, local_path=None):
|
|
151
|
+
"""
|
|
152
|
+
Import a module from the hub to use directly.
|
|
153
|
+
:param url: hub module url in the format "hub://[<source>/]<item-name>[:<tag>]"
|
|
154
|
+
:param install_requirements: when set to True, the module's requirements are installed.
|
|
155
|
+
:param secrets: optional, credentials dict for DB or URL (s3, v3io, ...)
|
|
156
|
+
:param local_path: Path to target directory for the module files (code and example notebook).
|
|
157
|
+
Defaults to the current working directory.
|
|
158
|
+
|
|
159
|
+
:return: the module
|
|
160
|
+
"""
|
|
161
|
+
hub_module: HubModule = get_hub_module(
|
|
162
|
+
url=url, download_files=True, secrets=secrets, local_path=local_path
|
|
163
|
+
)
|
|
164
|
+
if install_requirements:
|
|
165
|
+
hub_module.install_requirements()
|
|
166
|
+
return hub_module.module()
|
|
@@ -1499,20 +1499,51 @@ class V3IOTSDBConnector(TSDBConnector):
|
|
|
1499
1499
|
) -> mm_schemas.ModelEndpointDriftValues:
|
|
1500
1500
|
table = mm_schemas.V3IOTSDBTables.APP_RESULTS
|
|
1501
1501
|
start, end, interval = self._prepare_aligned_start_end(start, end)
|
|
1502
|
-
|
|
1503
|
-
# get per time-interval x endpoint_id combination the max result status
|
|
1504
1502
|
df = self._get_records(
|
|
1505
1503
|
table=table,
|
|
1506
1504
|
start=start,
|
|
1507
1505
|
end=end,
|
|
1508
|
-
interval=interval,
|
|
1509
|
-
sliding_window_step=interval,
|
|
1510
1506
|
columns=[mm_schemas.ResultData.RESULT_STATUS],
|
|
1511
|
-
agg_funcs=["max"],
|
|
1512
|
-
group_by=mm_schemas.WriterEvent.ENDPOINT_ID,
|
|
1513
1507
|
)
|
|
1508
|
+
df = self._aggregate_raw_drift_data(df, start, end, interval)
|
|
1514
1509
|
if df.empty:
|
|
1515
1510
|
return mm_schemas.ModelEndpointDriftValues(values=[])
|
|
1516
1511
|
df = df[df[f"max({mm_schemas.ResultData.RESULT_STATUS})"] >= 1]
|
|
1517
|
-
df = df.reset_index(names="_wstart")
|
|
1518
1512
|
return self._df_to_drift_data(df)
|
|
1513
|
+
|
|
1514
|
+
@staticmethod
|
|
1515
|
+
def _aggregate_raw_drift_data(
|
|
1516
|
+
df: pd.DataFrame, start: datetime, end: datetime, interval: str
|
|
1517
|
+
) -> pd.DataFrame:
|
|
1518
|
+
if df.empty:
|
|
1519
|
+
return df
|
|
1520
|
+
if not isinstance(df.index, pd.DatetimeIndex):
|
|
1521
|
+
raise TypeError("Expected a DatetimeIndex on the DataFrame (time index).")
|
|
1522
|
+
df[EventFieldType.ENDPOINT_ID] = (
|
|
1523
|
+
df[EventFieldType.ENDPOINT_ID].astype("string").str.strip()
|
|
1524
|
+
) # remove extra data carried by the category dtype
|
|
1525
|
+
window = df.loc[
|
|
1526
|
+
(df.index >= start) & (df.index < end),
|
|
1527
|
+
[mm_schemas.ResultData.RESULT_STATUS, EventFieldType.ENDPOINT_ID],
|
|
1528
|
+
]
|
|
1529
|
+
out = (
|
|
1530
|
+
window.groupby(
|
|
1531
|
+
[
|
|
1532
|
+
EventFieldType.ENDPOINT_ID,
|
|
1533
|
+
pd.Grouper(
|
|
1534
|
+
freq=interval, origin=start, label="left", closed="left"
|
|
1535
|
+
),
|
|
1536
|
+
]
|
|
1537
|
+
# align to start, [start, end) intervals
|
|
1538
|
+
)[mm_schemas.ResultData.RESULT_STATUS]
|
|
1539
|
+
.max()
|
|
1540
|
+
.reset_index()
|
|
1541
|
+
.rename(
|
|
1542
|
+
columns={
|
|
1543
|
+
mm_schemas.ResultData.RESULT_STATUS: f"max({mm_schemas.ResultData.RESULT_STATUS})"
|
|
1544
|
+
}
|
|
1545
|
+
)
|
|
1546
|
+
)
|
|
1547
|
+
return out.rename(
|
|
1548
|
+
columns={"time": "_wstart"}
|
|
1549
|
+
) # rename datetime column to _wstart to align with the tdengine result
|
|
@@ -659,3 +659,26 @@ def get_start_end(
|
|
|
659
659
|
)
|
|
660
660
|
|
|
661
661
|
return start, end
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
def validate_time_range(
|
|
665
|
+
start: Optional[datetime.datetime] = None, end: Optional[datetime.datetime] = None
|
|
666
|
+
) -> tuple[datetime.datetime, datetime.datetime]:
|
|
667
|
+
"""
|
|
668
|
+
validate start and end parameters and set default values if needed.
|
|
669
|
+
:param start: Either None or datetime, None is handled as datetime.now(tz=timezone.utc) - timedelta(days=1)
|
|
670
|
+
:param end: Either None or datetime, None is handled as datetime.now(tz=timezone.utc)
|
|
671
|
+
:return: start datetime, end datetime
|
|
672
|
+
"""
|
|
673
|
+
end = end or mlrun.utils.helpers.datetime_now()
|
|
674
|
+
start = start or (end - datetime.timedelta(days=1))
|
|
675
|
+
if start.tzinfo is None or end.tzinfo is None:
|
|
676
|
+
raise mlrun.errors.MLRunInvalidArgumentTypeError(
|
|
677
|
+
"Custom start and end times must contain the timezone."
|
|
678
|
+
)
|
|
679
|
+
if start > end:
|
|
680
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
681
|
+
"The start time must be before the end time. Note that if end time is not provided, "
|
|
682
|
+
"the current time is used by default."
|
|
683
|
+
)
|
|
684
|
+
return start, end
|
mlrun/projects/operations.py
CHANGED
|
@@ -177,7 +177,12 @@ def run_function(
|
|
|
177
177
|
This ensures latest code changes are executed. This argument must be used in
|
|
178
178
|
conjunction with the local=True argument.
|
|
179
179
|
:param output_path: path to store artifacts, when running in a workflow this will be set automatically
|
|
180
|
-
:param retry: Retry configuration for the run, can be a dict or an instance of
|
|
180
|
+
:param retry: Retry configuration for the run, can be a dict or an instance of
|
|
181
|
+
:py:class:`~mlrun.model.Retry`.
|
|
182
|
+
The `count` field in the `Retry` object specifies the number of retry attempts.
|
|
183
|
+
If `count=0`, the run will not be retried.
|
|
184
|
+
The `backoff` field specifies the retry backoff strategy between retry attempts.
|
|
185
|
+
If not provided, no backoff is applied.
|
|
181
186
|
:return: MLRun RunObject or PipelineNodeWrapper
|
|
182
187
|
"""
|
|
183
188
|
if artifact_path:
|
mlrun/projects/project.py
CHANGED
|
@@ -4104,7 +4104,12 @@ class MlrunProject(ModelObj):
|
|
|
4104
4104
|
This ensures latest code changes are executed. This argument must be used in
|
|
4105
4105
|
conjunction with the local=True argument.
|
|
4106
4106
|
:param output_path: path to store artifacts, when running in a workflow this will be set automatically
|
|
4107
|
-
:param retry: Retry configuration for the run, can be a dict or an instance of
|
|
4107
|
+
:param retry: Retry configuration for the run, can be a dict or an instance of
|
|
4108
|
+
:py:class:`~mlrun.model.Retry`.
|
|
4109
|
+
The `count` field in the `Retry` object specifies the number of retry attempts.
|
|
4110
|
+
If `count=0`, the run will not be retried.
|
|
4111
|
+
The `backoff` field specifies the retry backoff strategy between retry attempts.
|
|
4112
|
+
If not provided, no backoff is applied.
|
|
4108
4113
|
:return: MLRun RunObject or PipelineNodeWrapper
|
|
4109
4114
|
"""
|
|
4110
4115
|
if artifact_path:
|
mlrun/runtimes/base.py
CHANGED
|
@@ -376,7 +376,12 @@ class BaseRuntime(ModelObj):
|
|
|
376
376
|
This ensures latest code changes are executed. This argument must be used in
|
|
377
377
|
conjunction with the local=True argument.
|
|
378
378
|
:param output_path: Default artifact output path.
|
|
379
|
-
:param retry: Retry configuration for the run, can be a dict or an instance of
|
|
379
|
+
:param retry: Retry configuration for the run, can be a dict or an instance of
|
|
380
|
+
:py:class:`~mlrun.model.Retry`.
|
|
381
|
+
The `count` field in the `Retry` object specifies the number of retry attempts.
|
|
382
|
+
If `count=0`, the run will not be retried.
|
|
383
|
+
The `backoff` field specifies the retry backoff strategy between retry attempts.
|
|
384
|
+
If not provided, no backoff is applied.
|
|
380
385
|
:return: Run context object (RunObject) with run metadata, results and status
|
|
381
386
|
"""
|
|
382
387
|
if artifact_path or out_path:
|
|
@@ -443,9 +448,11 @@ class BaseRuntime(ModelObj):
|
|
|
443
448
|
:param runobj: Run context object (RunObject) with run metadata and status
|
|
444
449
|
:return: Dictionary with all the variables that could be parsed
|
|
445
450
|
"""
|
|
451
|
+
active_project = self.metadata.project or config.active_project
|
|
446
452
|
runtime_env = {
|
|
447
|
-
mlrun_constants.MLRUN_ACTIVE_PROJECT:
|
|
448
|
-
|
|
453
|
+
mlrun_constants.MLRUN_ACTIVE_PROJECT: active_project,
|
|
454
|
+
# TODO: Remove this in 1.12.0 as MLRUN_DEFAULT_PROJECT is deprecated and should not be injected anymore
|
|
455
|
+
"MLRUN_DEFAULT_PROJECT": active_project,
|
|
449
456
|
}
|
|
450
457
|
if runobj:
|
|
451
458
|
runtime_env["MLRUN_EXEC_CONFIG"] = runobj.to_json(
|
|
@@ -698,6 +698,12 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
698
698
|
"""
|
|
699
699
|
# create a function that includes only the reverse proxy, without the application
|
|
700
700
|
|
|
701
|
+
if not mlrun.get_current_project(silent=True):
|
|
702
|
+
raise mlrun.errors.MLRunMissingProjectError(
|
|
703
|
+
"An active project is required to run deploy_reverse_proxy_image(). "
|
|
704
|
+
"Use `mlrun.get_or_create_project()` or set an active project first."
|
|
705
|
+
)
|
|
706
|
+
|
|
701
707
|
reverse_proxy_func = mlrun.run.new_function(
|
|
702
708
|
name="reverse-proxy-temp", kind="remote"
|
|
703
709
|
)
|
mlrun/runtimes/nuclio/serving.py
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import json
|
|
15
15
|
import os
|
|
16
16
|
import warnings
|
|
17
|
+
from base64 import b64decode
|
|
17
18
|
from copy import deepcopy
|
|
18
19
|
from typing import Optional, Union
|
|
19
20
|
|
|
@@ -678,6 +679,17 @@ class ServingRuntime(RemoteRuntime):
|
|
|
678
679
|
f"function {function} is used in steps and is not defined, "
|
|
679
680
|
"use the .add_child_function() to specify child function attributes"
|
|
680
681
|
)
|
|
682
|
+
if isinstance(self.spec.graph, RootFlowStep) and any(
|
|
683
|
+
isinstance(step_type, mlrun.serving.states.ModelRunnerStep)
|
|
684
|
+
for step_type in self.spec.graph.steps.values()
|
|
685
|
+
):
|
|
686
|
+
# Add import for LLModel
|
|
687
|
+
decoded_code = b64decode(self.spec.build.functionSourceCode).decode("utf-8")
|
|
688
|
+
import_llmodel_code = "\nfrom mlrun.serving.states import LLModel\n"
|
|
689
|
+
if import_llmodel_code not in decoded_code:
|
|
690
|
+
decoded_code += import_llmodel_code
|
|
691
|
+
encoded_code = mlrun.utils.helpers.encode_user_code(decoded_code)
|
|
692
|
+
self.spec.build.functionSourceCode = encoded_code
|
|
681
693
|
|
|
682
694
|
# Handle secret processing before handling child functions, since secrets are transferred to them
|
|
683
695
|
if self.spec.secret_sources:
|
mlrun/runtimes/pod.py
CHANGED
mlrun/serving/states.py
CHANGED
|
@@ -1641,6 +1641,9 @@ class ModelRunnerStep(MonitoredStep):
|
|
|
1641
1641
|
model_runner_step.add_model(..., model_class=MyModel(name="my_model"))
|
|
1642
1642
|
graph.to(model_runner_step)
|
|
1643
1643
|
|
|
1644
|
+
Note when ModelRunnerStep is used in a graph, MLRun automatically imports
|
|
1645
|
+
the default language model class (LLModel) during function deployment.
|
|
1646
|
+
|
|
1644
1647
|
:param model_selector: ModelSelector instance whose select() method will be used to select models to run on each
|
|
1645
1648
|
event. Optional. If not passed, all models will be run.
|
|
1646
1649
|
:param raise_exception: If True, an error will be raised when model selection fails or if one of the models raised
|
|
@@ -1829,7 +1832,9 @@ class ModelRunnerStep(MonitoredStep):
|
|
|
1829
1832
|
Add a Model to this ModelRunner.
|
|
1830
1833
|
|
|
1831
1834
|
:param endpoint_name: str, will identify the model in the ModelRunnerStep, and assign model endpoint name
|
|
1832
|
-
:param model_class: Model class name
|
|
1835
|
+
:param model_class: Model class name. If LLModel is chosen
|
|
1836
|
+
(either by name `LLModel` or by its full path, e.g. mlrun.serving.states.LLModel),
|
|
1837
|
+
outputs will be overridden with UsageResponseKeys fields.
|
|
1833
1838
|
:param execution_mechanism: Parallel execution mechanism to be used to execute this model. Must be one of:
|
|
1834
1839
|
* "process_pool" – To run in a separate process from a process pool. This is appropriate for CPU or GPU
|
|
1835
1840
|
intensive tasks as they would otherwise block the main process by holding Python's Global Interpreter
|
|
@@ -1902,7 +1907,8 @@ class ModelRunnerStep(MonitoredStep):
|
|
|
1902
1907
|
"Cannot provide a model object as argument to `model_class` and also provide `model_parameters`."
|
|
1903
1908
|
)
|
|
1904
1909
|
if type(model_class) is LLModel or (
|
|
1905
|
-
isinstance(model_class, str)
|
|
1910
|
+
isinstance(model_class, str)
|
|
1911
|
+
and model_class.split(".")[-1] == LLModel.__name__
|
|
1906
1912
|
):
|
|
1907
1913
|
if outputs:
|
|
1908
1914
|
warnings.warn(
|
|
@@ -2848,7 +2854,9 @@ class RootFlowStep(FlowStep):
|
|
|
2848
2854
|
"""
|
|
2849
2855
|
Add a shared model to the graph, this model will be available to all the ModelRunners in the graph
|
|
2850
2856
|
:param name: Name of the shared model (should be unique in the graph)
|
|
2851
|
-
:param model_class: Model class name
|
|
2857
|
+
:param model_class: Model class name. If LLModel is chosen
|
|
2858
|
+
(either by name `LLModel` or by its full path, e.g. mlrun.serving.states.LLModel),
|
|
2859
|
+
outputs will be overridden with UsageResponseKeys fields.
|
|
2852
2860
|
:param execution_mechanism: Parallel execution mechanism to be used to execute this model. Must be one of:
|
|
2853
2861
|
* "process_pool" – To run in a separate process from a process pool. This is appropriate for CPU or GPU
|
|
2854
2862
|
intensive tasks as they would otherwise block the main process by holding Python's Global Interpreter
|
|
@@ -2892,7 +2900,8 @@ class RootFlowStep(FlowStep):
|
|
|
2892
2900
|
"Cannot provide a model object as argument to `model_class` and also provide `model_parameters`."
|
|
2893
2901
|
)
|
|
2894
2902
|
if type(model_class) is LLModel or (
|
|
2895
|
-
isinstance(model_class, str)
|
|
2903
|
+
isinstance(model_class, str)
|
|
2904
|
+
and model_class.split(".")[-1] == LLModel.__name__
|
|
2896
2905
|
):
|
|
2897
2906
|
if outputs:
|
|
2898
2907
|
warnings.warn(
|
mlrun/utils/helpers.py
CHANGED
|
@@ -45,6 +45,7 @@ import pytz
|
|
|
45
45
|
import semver
|
|
46
46
|
import yaml
|
|
47
47
|
from dateutil import parser
|
|
48
|
+
from orjson import orjson
|
|
48
49
|
from pandas import Timedelta, Timestamp
|
|
49
50
|
from yaml.representer import RepresenterError
|
|
50
51
|
|
|
@@ -61,6 +62,7 @@ import mlrun_pipelines.models
|
|
|
61
62
|
import mlrun_pipelines.utils
|
|
62
63
|
from mlrun.common.constants import MYSQL_MEDIUMBLOB_SIZE_BYTES
|
|
63
64
|
from mlrun.common.schemas import ArtifactCategories
|
|
65
|
+
from mlrun.common.schemas.hub import HubSourceType
|
|
64
66
|
from mlrun.config import config
|
|
65
67
|
from mlrun_pipelines.models import PipelineRun
|
|
66
68
|
|
|
@@ -801,11 +803,17 @@ def remove_tag_from_artifact_uri(uri: str) -> Optional[str]:
|
|
|
801
803
|
return uri if not add_store else DB_SCHEMA + "://" + uri
|
|
802
804
|
|
|
803
805
|
|
|
804
|
-
def extend_hub_uri_if_needed(
|
|
806
|
+
def extend_hub_uri_if_needed(
|
|
807
|
+
uri: str,
|
|
808
|
+
asset_type: HubSourceType = HubSourceType.functions,
|
|
809
|
+
file: str = "function.yaml",
|
|
810
|
+
) -> tuple[str, bool]:
|
|
805
811
|
"""
|
|
806
|
-
Retrieve the full uri of
|
|
812
|
+
Retrieve the full uri of an object in the hub.
|
|
807
813
|
|
|
808
814
|
:param uri: structure: "hub://[<source>/]<item-name>[:<tag>]"
|
|
815
|
+
:param asset_type: The type of the hub item (functions, modules, etc.)
|
|
816
|
+
:param file: The file name inside the hub item directory (default: function.yaml)
|
|
809
817
|
|
|
810
818
|
:return: A tuple of:
|
|
811
819
|
[0] = Extended URI of item
|
|
@@ -831,7 +839,7 @@ def extend_hub_uri_if_needed(uri) -> tuple[str, bool]:
|
|
|
831
839
|
name = normalize_name(name=name)
|
|
832
840
|
if not source_name:
|
|
833
841
|
# Searching item in all sources
|
|
834
|
-
sources = db.list_hub_sources(item_name=name, tag=tag)
|
|
842
|
+
sources = db.list_hub_sources(item_name=name, tag=tag, item_type=asset_type)
|
|
835
843
|
if not sources:
|
|
836
844
|
raise mlrun.errors.MLRunNotFoundError(
|
|
837
845
|
f"Item={name}, tag={tag} not found in any hub source"
|
|
@@ -841,13 +849,10 @@ def extend_hub_uri_if_needed(uri) -> tuple[str, bool]:
|
|
|
841
849
|
else:
|
|
842
850
|
# Specific source is given
|
|
843
851
|
indexed_source = db.get_hub_source(source_name)
|
|
844
|
-
# hub
|
|
852
|
+
# hub directories name are with underscores instead of hyphens
|
|
845
853
|
name = name.replace("-", "_")
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
return indexed_source.source.get_full_uri(
|
|
849
|
-
function_suffix, function_type
|
|
850
|
-
), is_hub_uri
|
|
854
|
+
suffix = f"{name}/{tag}/src/{file}"
|
|
855
|
+
return indexed_source.source.get_full_uri(suffix, asset_type), is_hub_uri
|
|
851
856
|
|
|
852
857
|
|
|
853
858
|
def gen_md_table(header, rows=None):
|
|
@@ -1214,52 +1219,58 @@ def get_workflow_url(
|
|
|
1214
1219
|
|
|
1215
1220
|
|
|
1216
1221
|
def get_kfp_list_runs_filter(
|
|
1217
|
-
project_name: Optional[str] = None,
|
|
1218
|
-
end_date: Optional[str] = None,
|
|
1219
1222
|
start_date: Optional[str] = None,
|
|
1223
|
+
end_date: Optional[str] = None,
|
|
1224
|
+
filter_: Optional[str] = None,
|
|
1225
|
+
experiment_ids: Optional[list[str]] = None,
|
|
1220
1226
|
) -> str:
|
|
1221
1227
|
"""
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
:param project_name: The name of the project. If "*", it won't filter by project.
|
|
1225
|
-
:param end_date: The latest creation date for filtering runs (ISO 8601 format).
|
|
1226
|
-
:param start_date: The earliest creation date for filtering runs (ISO 8601 format).
|
|
1227
|
-
:return: A JSON-formatted filter string for KFP.
|
|
1228
|
+
Generate a filter for KFP runs based on start and end dates, and experiment IDs.
|
|
1228
1229
|
"""
|
|
1230
|
+
existing_filter_object = json.loads(filter_) if filter_ else {"predicates": []}
|
|
1231
|
+
preserved_predicates = [
|
|
1232
|
+
predicate
|
|
1233
|
+
for predicate in existing_filter_object.get("predicates", [])
|
|
1234
|
+
if predicate.get("key") != "name"
|
|
1235
|
+
]
|
|
1229
1236
|
|
|
1230
|
-
|
|
1231
|
-
kfp_less_than_or_equal_op = 7 # '<='
|
|
1232
|
-
kfp_greater_than_or_equal_op = 5 # '>='
|
|
1233
|
-
kfp_substring_op = 9 # Substring match
|
|
1234
|
-
|
|
1235
|
-
filters = {"predicates": []}
|
|
1236
|
-
|
|
1237
|
+
new_predicates = []
|
|
1237
1238
|
if end_date:
|
|
1238
|
-
|
|
1239
|
+
new_predicates.append(
|
|
1239
1240
|
{
|
|
1240
|
-
"key":
|
|
1241
|
-
"op":
|
|
1241
|
+
"key": mlrun_pipelines.models.FilterFields.CREATED_AT,
|
|
1242
|
+
"op": mlrun_pipelines.models.FilterOperations.LESS_THAN_EQUALS.value,
|
|
1242
1243
|
"timestamp_value": end_date,
|
|
1243
1244
|
}
|
|
1244
1245
|
)
|
|
1245
1246
|
|
|
1246
|
-
if
|
|
1247
|
-
|
|
1247
|
+
if start_date:
|
|
1248
|
+
new_predicates.append(
|
|
1248
1249
|
{
|
|
1249
|
-
"key":
|
|
1250
|
-
"op":
|
|
1251
|
-
"
|
|
1250
|
+
"key": mlrun_pipelines.models.FilterFields.CREATED_AT,
|
|
1251
|
+
"op": mlrun_pipelines.models.FilterOperations.GREATER_THAN_EQUALS.value,
|
|
1252
|
+
"timestamp_value": start_date,
|
|
1252
1253
|
}
|
|
1253
1254
|
)
|
|
1254
|
-
|
|
1255
|
-
|
|
1255
|
+
|
|
1256
|
+
if experiment_ids and all(experiment_ids):
|
|
1257
|
+
new_predicates.append(
|
|
1256
1258
|
{
|
|
1257
|
-
"key":
|
|
1258
|
-
"op":
|
|
1259
|
-
"
|
|
1259
|
+
"key": mlrun_pipelines.models.FilterFields.EXPERIMENT_ID,
|
|
1260
|
+
"op": mlrun_pipelines.models.FilterOperations.IN.value,
|
|
1261
|
+
"string_values": {"values": experiment_ids},
|
|
1260
1262
|
}
|
|
1261
1263
|
)
|
|
1262
|
-
|
|
1264
|
+
|
|
1265
|
+
final_filter_object = {"predicates": preserved_predicates + new_predicates}
|
|
1266
|
+
if not final_filter_object["predicates"]:
|
|
1267
|
+
return ""
|
|
1268
|
+
|
|
1269
|
+
logger.debug(
|
|
1270
|
+
"Generated KFP runs filter",
|
|
1271
|
+
filter_object_with_predicates=final_filter_object,
|
|
1272
|
+
)
|
|
1273
|
+
return orjson.dumps(final_filter_object).decode()
|
|
1263
1274
|
|
|
1264
1275
|
|
|
1265
1276
|
def validate_and_convert_date(date_input: str) -> str:
|
mlrun/utils/version/version.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mlrun
|
|
3
|
-
Version: 1.10.
|
|
3
|
+
Version: 1.10.0rc29
|
|
4
4
|
Summary: Tracking and config of machine learning runs
|
|
5
5
|
Home-page: https://github.com/mlrun/mlrun
|
|
6
6
|
Author: Yaron Haviv
|
|
@@ -22,7 +22,7 @@ Requires-Python: >=3.9, <3.12
|
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
24
|
Requires-Dist: urllib3>=1.26.20
|
|
25
|
-
Requires-Dist: v3io-frames>=0.10.
|
|
25
|
+
Requires-Dist: v3io-frames>=0.10.16
|
|
26
26
|
Requires-Dist: GitPython>=3.1.41,~=3.1
|
|
27
27
|
Requires-Dist: aiohttp~=3.11
|
|
28
28
|
Requires-Dist: aiohttp-retry~=2.9
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
mlrun/__init__.py,sha256=
|
|
1
|
+
mlrun/__init__.py,sha256=acM2jRv7RCvBROwucuC01Rf_HdvV3xUPtJlQtX_01MY,8076
|
|
2
2
|
mlrun/__main__.py,sha256=wQNaxW7QsqFBtWffnPkw-497fnpsrQzUnscBQQAP_UM,48364
|
|
3
|
-
mlrun/config.py,sha256=
|
|
3
|
+
mlrun/config.py,sha256=F1PDI88t2cFujGnDr4YslEBzG6SckBKjUSdkxFX3zUE,73149
|
|
4
4
|
mlrun/errors.py,sha256=bAk0t_qmCxQSPNK0TugOAfA5R6f0G6OYvEvXUWSJ_5U,9062
|
|
5
5
|
mlrun/execution.py,sha256=wkmT1k0QROgGJFMBIsYUsJaqEF2bkqaYVzp_ZQb527Q,58814
|
|
6
6
|
mlrun/features.py,sha256=jMEXo6NB36A6iaxNEJWzdtYwUmglYD90OIKTIEeWhE8,15841
|
|
@@ -56,7 +56,7 @@ mlrun/common/schemas/feature_store.py,sha256=Kz7AWQ1RCPA8sTL9cGRZnfUBhWf4MX_5yyY
|
|
|
56
56
|
mlrun/common/schemas/frontend_spec.py,sha256=tR8k78cppYK-X8kCWe0mz1gk8yqpsn2IxM3QmBdTJs8,2622
|
|
57
57
|
mlrun/common/schemas/function.py,sha256=BUHenAK6r_mWtDrBWE42xPJU8zh8ng5Usj7GmB_SAcU,5108
|
|
58
58
|
mlrun/common/schemas/http.py,sha256=KozLgGV1vpNXQ8Qptr_Zm6BEbc2VcU42hSphe_ffe_A,704
|
|
59
|
-
mlrun/common/schemas/hub.py,sha256=
|
|
59
|
+
mlrun/common/schemas/hub.py,sha256=K_9AyyYF-qnwjvkGWYFEke-jG58pS3Klv1IKAkdWOxA,4267
|
|
60
60
|
mlrun/common/schemas/k8s.py,sha256=YgyDK7KNt29GHCOxd1vw-jnl_757cIPLzViCTNT1Zcc,1403
|
|
61
61
|
mlrun/common/schemas/memory_reports.py,sha256=Q6w7xofQlMD-iqjE8uK9yU5ijLPkht_EsXJCMad_TQo,899
|
|
62
62
|
mlrun/common/schemas/notification.py,sha256=Q-tBaU_V7YZiuj3ankuACf3_-hb874_osxq0eaW90Ww,5549
|
|
@@ -85,7 +85,7 @@ mlrun/data_types/spark.py,sha256=I5JC887dT9RGs5Tqz5zaRxlCMyhMeFmwuNbExQoyW0E,962
|
|
|
85
85
|
mlrun/data_types/to_pandas.py,sha256=KOy0FLXPJirsgH6szcC5BI6t70yVDCjuo6LmuYHNTuI,11429
|
|
86
86
|
mlrun/datastore/__init__.py,sha256=LAAqChT1ydUpQ9f8PpAMXb20xjpr1kMMx74ZvtyiTp4,6097
|
|
87
87
|
mlrun/datastore/alibaba_oss.py,sha256=E0t0-e9Me2t2Mux2LWdC9riOG921TgNjhoy897JJX7o,4932
|
|
88
|
-
mlrun/datastore/azure_blob.py,sha256=
|
|
88
|
+
mlrun/datastore/azure_blob.py,sha256=G1NNAyJMPWB_ziHASrcxIx72ueCTK6E7qsq1Vig5xEM,17328
|
|
89
89
|
mlrun/datastore/base.py,sha256=yLdnFCL2k_rcasdbxXjnQr7Lwm-A79LnW9AITtn9-p4,25450
|
|
90
90
|
mlrun/datastore/datastore.py,sha256=F9NdQFwyAHgjKFSQ1mcLZBuxNqXXesNMjtIVj03L5Gk,13422
|
|
91
91
|
mlrun/datastore/datastore_profile.py,sha256=K2MrA0KjznkoWci5ua6L_k1rjMGBfCsQFAql-Iwok0M,24680
|
|
@@ -104,7 +104,7 @@ mlrun/datastore/spark_utils.py,sha256=dn0RWpYzee-M8UZw-NVuHAdqlNAZ7VO-fNtI8ZiDky
|
|
|
104
104
|
mlrun/datastore/store_resources.py,sha256=s2794zqkzy_mjRMvRedDNs_tycTLoF8wxTqsWRQphCE,6839
|
|
105
105
|
mlrun/datastore/storeytargets.py,sha256=c1NRT_dfwlwjY8O8KnD_8PKaRRng5YctlAZS4U4xpZs,6454
|
|
106
106
|
mlrun/datastore/targets.py,sha256=8dRnLy1wBYJbVyommYkpGeztdT1CsfFHZY6Zh7o8X-Q,79165
|
|
107
|
-
mlrun/datastore/utils.py,sha256=
|
|
107
|
+
mlrun/datastore/utils.py,sha256=0EMNZpRHOi8zQBsE3rAe_7JmPojVc3-mIY_1n5SBkJI,12288
|
|
108
108
|
mlrun/datastore/v3io.py,sha256=sMn5473k_bXyIJovNf0rahbVHRmO0YPdOwIhbs06clg,8201
|
|
109
109
|
mlrun/datastore/vectorstore.py,sha256=k-yom5gfw20hnVG0Rg7aBEehuXwvAloZwn0cx0VGals,11708
|
|
110
110
|
mlrun/datastore/model_provider/__init__.py,sha256=kXGBqhLN0rlAx0kTXhozGzFsIdSqW0uTSKMmsLgq_is,569
|
|
@@ -116,10 +116,10 @@ mlrun/datastore/wasbfs/__init__.py,sha256=s5Ul-0kAhYqFjKDR2X0O2vDGDbLQQduElb32Ev
|
|
|
116
116
|
mlrun/datastore/wasbfs/fs.py,sha256=ge8NK__5vTcFT-krI155_8RDUywQw4SIRX6BWATXy9Q,6299
|
|
117
117
|
mlrun/db/__init__.py,sha256=WqJ4x8lqJ7ZoKbhEyFqkYADd9P6E3citckx9e9ZLcIU,1163
|
|
118
118
|
mlrun/db/auth_utils.py,sha256=hpg8D2r82oN0BWabuWN04BTNZ7jYMAF242YSUpK7LFM,5211
|
|
119
|
-
mlrun/db/base.py,sha256=
|
|
119
|
+
mlrun/db/base.py,sha256=QNqL29xYs2yL4JKHfvljpf-UsIoUeMxun-eL33msJmc,32405
|
|
120
120
|
mlrun/db/factory.py,sha256=yP2vVmveUE7LYTCHbS6lQIxP9rW--zdISWuPd_I3d_4,2111
|
|
121
|
-
mlrun/db/httpdb.py,sha256
|
|
122
|
-
mlrun/db/nopdb.py,sha256=
|
|
121
|
+
mlrun/db/httpdb.py,sha256=1XEWpfZm2wW3d6eUqsE-13Nk4Zm2lLKg18J53E5vE10,238986
|
|
122
|
+
mlrun/db/nopdb.py,sha256=iClAugTqMPPQRkXb3uzf_vFhmnfuIKCLpK5M6QKHT4Y,28771
|
|
123
123
|
mlrun/feature_store/__init__.py,sha256=SlI845bWt6xX34SXunHHqhmFAR9-5v2ak8N-qpcAPGo,1328
|
|
124
124
|
mlrun/feature_store/api.py,sha256=qKj5Tk6prTab6XWatWhBuPRVp0eJEctoxRMN2wz48vA,32168
|
|
125
125
|
mlrun/feature_store/common.py,sha256=JlQA7XWkg9fLuw7cXFmWpUneQqM3NBhwv7DU_xlenWI,12819
|
|
@@ -219,6 +219,8 @@ mlrun/frameworks/xgboost/__init__.py,sha256=NyFRxu5v5z8oegbJP05PFUmfJL3I3JeN1PYH
|
|
|
219
219
|
mlrun/frameworks/xgboost/mlrun_interface.py,sha256=KINOf0udbY75raTewjEFGNlIRyE0evpoJAWQrSVu17Y,877
|
|
220
220
|
mlrun/frameworks/xgboost/model_handler.py,sha256=bJq4D1VK3rzhALovqIV5mS0LvGiTlsgAkHanD25pU2c,11663
|
|
221
221
|
mlrun/frameworks/xgboost/utils.py,sha256=4rShiFChzDbWJ4HoTo4qV_lj-Z89pHBAp6Z1yHmU8wA,1068
|
|
222
|
+
mlrun/hub/__init__.py,sha256=50cXcEk8i5G8KQ-nzF6iZDkMbXd-zMNd8nQZ7y7KTVI,620
|
|
223
|
+
mlrun/hub/module.py,sha256=EDdQ2nFfH-i_S1WAHgtxh8CYK-P1ByD95Eow74tdzOY,6726
|
|
222
224
|
mlrun/launcher/__init__.py,sha256=JL8qkT1lLr1YvW6iP0hmwDTaSR2RfrMDx0-1gWRhTOE,571
|
|
223
225
|
mlrun/launcher/base.py,sha256=IgBE-ZS1ZiGzucg5SElGtO4qOB0cqYQfGtZTcRc2S3Y,17378
|
|
224
226
|
mlrun/launcher/client.py,sha256=cl40ZdF2fU1QbUKdl4Xnucb1u2h-8_dn095qIUyxbuM,6402
|
|
@@ -229,7 +231,7 @@ mlrun/model_monitoring/__init__.py,sha256=qDQnncjya9XPTlfvGyfWsZWiXc-glGZrrNja-5
|
|
|
229
231
|
mlrun/model_monitoring/api.py,sha256=k0eOm-vW8z2u05PwMK2PI2mSAplK0xGIrUe_XWk7mRM,27000
|
|
230
232
|
mlrun/model_monitoring/controller.py,sha256=2XOkOZRB03K9ph6TH-ICspHga-GQOURL0C8-0GTHaTY,43961
|
|
231
233
|
mlrun/model_monitoring/features_drift_table.py,sha256=c6GpKtpOJbuT1u5uMWDL_S-6N4YPOmlktWMqPme3KFY,25308
|
|
232
|
-
mlrun/model_monitoring/helpers.py,sha256=
|
|
234
|
+
mlrun/model_monitoring/helpers.py,sha256=50oFqgIc5xFHYPIVgq3M-Gbr7epqAI5NgHmvOeMy52U,24667
|
|
233
235
|
mlrun/model_monitoring/stream_processing.py,sha256=bryYO3D0cC10MAQ-liHxUZ79MrL-VFXCb7KNyj6bl-8,34655
|
|
234
236
|
mlrun/model_monitoring/writer.py,sha256=rGRFzSOkqZWvD3Y6sVk2H1Gepfnkzkp9ce00PsApTLo,8288
|
|
235
237
|
mlrun/model_monitoring/applications/__init__.py,sha256=BwlmRELlFJf2b2YMyv5kUSHNe8--OyqWhDgRlT8a_8g,779
|
|
@@ -253,7 +255,7 @@ mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connection.py,sha256=dtkaHaWKWE
|
|
|
253
255
|
mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py,sha256=Vj8eWZ6jxXs9nTlo5Du1jJjYutwSNp4ZtztvKsnrr4M,51333
|
|
254
256
|
mlrun/model_monitoring/db/tsdb/v3io/__init__.py,sha256=aL3bfmQsUQ-sbvKGdNihFj8gLCK3mSys0qDcXtYOwgc,616
|
|
255
257
|
mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py,sha256=sNQFj6qyJx5eSBKRC3gyTc1cfh1l2IkRpPtuZwtzCW0,6844
|
|
256
|
-
mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=
|
|
258
|
+
mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py,sha256=3GNMudOpedhu_OId4Gp-r9nj1gtqh_353yn2gWta-BY,61459
|
|
257
259
|
mlrun/model_monitoring/metrics/__init__.py,sha256=6CsTXAxeLbbf8yfCADTaxmiavqwrLEdYFJ-qc5kgDAY,569
|
|
258
260
|
mlrun/model_monitoring/metrics/histogram_distance.py,sha256=E9_WIl2vd6qNvoHVHoFcnuQk3ekbFWOdi8aU7sHrfk4,4724
|
|
259
261
|
mlrun/package/__init__.py,sha256=v7VDyK9kDOOuDvFo4oiGV2fx-vM1KL7fdN9pGLakhUQ,7008
|
|
@@ -276,11 +278,11 @@ mlrun/package/utils/type_hint_utils.py,sha256=Ic3A7C9KnbfdLe-nUgzGoefBnsvOJJP9ip
|
|
|
276
278
|
mlrun/platforms/__init__.py,sha256=QgtpAt1lpfTKk0mLtesB1P8szK9cpNDPeYzu2qDbPCM,3580
|
|
277
279
|
mlrun/platforms/iguazio.py,sha256=32_o95Ntx9z3ciowt2NcnX7tAiLBwX3VB0mbTQ-KrIQ,13848
|
|
278
280
|
mlrun/projects/__init__.py,sha256=hdCOA6_fp8X4qGGGT7Bj7sPbkM1PayWuaVZL0DkpuZw,1240
|
|
279
|
-
mlrun/projects/operations.py,sha256=
|
|
281
|
+
mlrun/projects/operations.py,sha256=dax9HGvs3S7FzZ2Hok1ixFoToIZI2mkUo0EhNUtsHGk,21020
|
|
280
282
|
mlrun/projects/pipelines.py,sha256=ZOfuIEHOXfuc4qAkuWvbWhCjP6kqpLkv-yBBaY9RXhg,52219
|
|
281
|
-
mlrun/projects/project.py,sha256=
|
|
283
|
+
mlrun/projects/project.py,sha256=Q70Fpxwghuxggdbcizj9pIQ0XsJYMGbmca6arcyrBog,256830
|
|
282
284
|
mlrun/runtimes/__init__.py,sha256=8cqrYKy1a0_87XG7V_p96untQ4t8RocadM4LVEEN1JM,9029
|
|
283
|
-
mlrun/runtimes/base.py,sha256=
|
|
285
|
+
mlrun/runtimes/base.py,sha256=pagMAvF0nEElptqLnBiGx9fpFenEq052B80GaLzR8Y8,38895
|
|
284
286
|
mlrun/runtimes/daskjob.py,sha256=IN6gKKrmCIjWooj5FgFm-pAb2i7ra1ERRzClfu_rYGI,20102
|
|
285
287
|
mlrun/runtimes/funcdoc.py,sha256=zRFHrJsV8rhDLJwoUhcfZ7Cs0j-tQ76DxwUqdXV_Wyc,9810
|
|
286
288
|
mlrun/runtimes/function_reference.py,sha256=fnMKUEieKgy4JyVLhFpDtr6JvKgOaQP8F_K2H3-Pk9U,5030
|
|
@@ -288,7 +290,7 @@ mlrun/runtimes/generators.py,sha256=X8NDlCEPveDDPOHtOGcSpbl3pAVM3DP7fuPj5xVhxEY,
|
|
|
288
290
|
mlrun/runtimes/kubejob.py,sha256=wadCzmSgjv9OU_Ax8CQNHfXLo0v-ev9ZGHUFGcNc9Qw,8577
|
|
289
291
|
mlrun/runtimes/local.py,sha256=R72VdrXnFdAhLsKJiWPOcfsi4jS-W5E1FnkT2Xllt8M,22150
|
|
290
292
|
mlrun/runtimes/mounts.py,sha256=Q6oN1ilVcsFaVM1DAS-mfCD7vGWa7Wa9aEhRrctJPyk,19292
|
|
291
|
-
mlrun/runtimes/pod.py,sha256=
|
|
293
|
+
mlrun/runtimes/pod.py,sha256=HtSnhdfaT_rvYwybXjLowl3eOZSrRSyWqW7HYXuUT40,58252
|
|
292
294
|
mlrun/runtimes/remotesparkjob.py,sha256=BalAea66GleaKeoYTw6ZL1Qr4wf1yRxfgk1-Fkc9Pqg,7864
|
|
293
295
|
mlrun/runtimes/utils.py,sha256=iRL0U0L56RW26hfjo2n_pRof5XgCAtWSO3YYxPt_2NI,16982
|
|
294
296
|
mlrun/runtimes/databricks_job/__init__.py,sha256=kXGBqhLN0rlAx0kTXhozGzFsIdSqW0uTSKMmsLgq_is,569
|
|
@@ -302,9 +304,9 @@ mlrun/runtimes/nuclio/__init__.py,sha256=osOVMN9paIOuUoOTizmkxMb_OXRP-SlPwXHJSSY
|
|
|
302
304
|
mlrun/runtimes/nuclio/api_gateway.py,sha256=vH9ClKVP4Mb24rvA67xPuAvAhX-gAv6vVtjVxyplhdc,26969
|
|
303
305
|
mlrun/runtimes/nuclio/function.py,sha256=jNlBbtdIoQdd2ZKljqDgKUTHuM4iE_JiO_ANzQyssZE,55168
|
|
304
306
|
mlrun/runtimes/nuclio/nuclio.py,sha256=sLK8KdGO1LbftlL3HqPZlFOFTAAuxJACZCVl1c0Ha6E,2942
|
|
305
|
-
mlrun/runtimes/nuclio/serving.py,sha256=
|
|
307
|
+
mlrun/runtimes/nuclio/serving.py,sha256=NF0f7a6KV8GIb4QBUKiJa_L_5oqCsG7UHPs8Uo3K_Eo,36330
|
|
306
308
|
mlrun/runtimes/nuclio/application/__init__.py,sha256=rRs5vasy_G9IyoTpYIjYDafGoL6ifFBKgBtsXn31Atw,614
|
|
307
|
-
mlrun/runtimes/nuclio/application/application.py,sha256=
|
|
309
|
+
mlrun/runtimes/nuclio/application/application.py,sha256=5bwGgB_isThhbk9BqAsgJYdd0rKCwcil-LyMPR0dVwQ,33210
|
|
308
310
|
mlrun/runtimes/nuclio/application/reverse_proxy.go,sha256=lEHH74vr2PridIHp1Jkc_NjkrWb5b6zawRrNxHQhwGU,2913
|
|
309
311
|
mlrun/runtimes/sparkjob/__init__.py,sha256=GPP_ekItxiU9Ydn3mJa4Obph02Bg6DO-JYs791_MV58,607
|
|
310
312
|
mlrun/runtimes/sparkjob/spark3job.py,sha256=3dW7RG2T58F2dsUw0TsRvE3SIFcekx3CerLdcaG1f50,41458
|
|
@@ -314,7 +316,7 @@ mlrun/serving/remote.py,sha256=Igha2FipK3-6rV_PZ1K464kTbiTu8rhc6SMm-HiEJ6o,18817
|
|
|
314
316
|
mlrun/serving/routers.py,sha256=pu5jlSLI4Ml68YP_FMFDhhwPfLcT6lRu5yL5QDgXPHQ,52889
|
|
315
317
|
mlrun/serving/server.py,sha256=WvAQtkNhAcd2vGuMR04OdxfynMNWvtz6LpKEYPhK3z0,40959
|
|
316
318
|
mlrun/serving/serving_wrapper.py,sha256=UL9hhWCfMPcTJO_XrkvNaFvck1U1E7oS8trTZyak0cA,835
|
|
317
|
-
mlrun/serving/states.py,sha256=
|
|
319
|
+
mlrun/serving/states.py,sha256=urq7v4lWwaFP_ZheEqEO1IiX9gkVW3GkuiEbbrBoz90,139012
|
|
318
320
|
mlrun/serving/system_steps.py,sha256=ZvGkUqiiYOrUlsDnsvzf9u9554mzyFwlKVrybqB7xao,20200
|
|
319
321
|
mlrun/serving/utils.py,sha256=Zbfqm8TKNcTE8zRBezVBzpvR2WKeKeIRN7otNIaiYEc,4170
|
|
320
322
|
mlrun/serving/v1_serving.py,sha256=c6J_MtpE-Tqu00-6r4eJOCO6rUasHDal9W2eBIcrl50,11853
|
|
@@ -329,7 +331,7 @@ mlrun/utils/async_http.py,sha256=8Olx8TNNeXB07nEGwlqhEgFgnFAD71vBU_bqaA9JW-w,122
|
|
|
329
331
|
mlrun/utils/azure_vault.py,sha256=IEFizrDGDbAaoWwDr1WoA88S_EZ0T--vjYtY-i0cvYQ,3450
|
|
330
332
|
mlrun/utils/clones.py,sha256=qbAGyEbSvlewn3Tw_DpQZP9z6MGzFhSaZfI1CblX8Fg,7515
|
|
331
333
|
mlrun/utils/condition_evaluator.py,sha256=-nGfRmZzivn01rHTroiGY4rqEv8T1irMyhzxEei-sKc,1897
|
|
332
|
-
mlrun/utils/helpers.py,sha256=
|
|
334
|
+
mlrun/utils/helpers.py,sha256=wiFZ8E6Ony4eV4N_pGDPfLtDZNAuyIYL_zv6bEqTSk8,83666
|
|
333
335
|
mlrun/utils/http.py,sha256=5ZU2VpokaUM_DT3HBSqTm8xjUqTPjZN5fKkSIvKlTl0,8704
|
|
334
336
|
mlrun/utils/logger.py,sha256=uaCgI_ezzaXf7nJDCy-1Nrjds8vSXqDbzmjmb3IyCQo,14864
|
|
335
337
|
mlrun/utils/regex.py,sha256=FcRwWD8x9X3HLhCCU2F0AVKTFah784Pr7ZAe3a02jw8,5199
|
|
@@ -348,11 +350,11 @@ mlrun/utils/notifications/notification/mail.py,sha256=ZyJ3eqd8simxffQmXzqd3bgbAq
|
|
|
348
350
|
mlrun/utils/notifications/notification/slack.py,sha256=wSu_7W0EnGLBNwIgWCYEeTP8j9SPAMPDBnfUcPnVZYA,7299
|
|
349
351
|
mlrun/utils/notifications/notification/webhook.py,sha256=FM5-LQAKAVJKp37MRzR3SsejalcnpM6r_9Oe7znxZEA,5313
|
|
350
352
|
mlrun/utils/version/__init__.py,sha256=YnzE6tlf24uOQ8y7Z7l96QLAI6-QEii7-77g8ynmzy0,613
|
|
351
|
-
mlrun/utils/version/version.json,sha256=
|
|
353
|
+
mlrun/utils/version/version.json,sha256=kPvnUtOTEKIy1wj05q50LE2z2MgUlEGLKrG5080-GnY,90
|
|
352
354
|
mlrun/utils/version/version.py,sha256=M2hVhRrgkN3SxacZHs3ZqaOsqAA7B6a22ne324IQ1HE,1877
|
|
353
|
-
mlrun-1.10.
|
|
354
|
-
mlrun-1.10.
|
|
355
|
-
mlrun-1.10.
|
|
356
|
-
mlrun-1.10.
|
|
357
|
-
mlrun-1.10.
|
|
358
|
-
mlrun-1.10.
|
|
355
|
+
mlrun-1.10.0rc29.dist-info/licenses/LICENSE,sha256=zTiv1CxWNkOk1q8eJS1G_8oD4gWpWLwWxj_Agcsi8Os,11337
|
|
356
|
+
mlrun-1.10.0rc29.dist-info/METADATA,sha256=SPTX_rI17peKzA0BjCzu9p6HAng5ROV94En25oMs2_Y,26017
|
|
357
|
+
mlrun-1.10.0rc29.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
358
|
+
mlrun-1.10.0rc29.dist-info/entry_points.txt,sha256=1Owd16eAclD5pfRCoJpYC2ZJSyGNTtUr0nCELMioMmU,46
|
|
359
|
+
mlrun-1.10.0rc29.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
|
|
360
|
+
mlrun-1.10.0rc29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|