mlrun 1.7.0rc18__py3-none-any.whl → 1.7.0rc19__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mlrun might be problematic. Click here for more details.
- mlrun/__main__.py +5 -2
- mlrun/common/constants.py +64 -3
- mlrun/common/formatters/__init__.py +16 -0
- mlrun/common/formatters/base.py +59 -0
- mlrun/common/formatters/function.py +41 -0
- mlrun/common/runtimes/constants.py +29 -4
- mlrun/common/schemas/__init__.py +0 -1
- mlrun/common/schemas/api_gateway.py +52 -0
- mlrun/common/schemas/frontend_spec.py +1 -0
- mlrun/common/schemas/model_monitoring/__init__.py +6 -3
- mlrun/common/schemas/model_monitoring/constants.py +2 -7
- mlrun/config.py +7 -2
- mlrun/datastore/sources.py +16 -22
- mlrun/datastore/store_resources.py +5 -1
- mlrun/datastore/targets.py +3 -2
- mlrun/datastore/utils.py +42 -0
- mlrun/execution.py +16 -6
- mlrun/feature_store/ingestion.py +7 -6
- mlrun/feature_store/retrieval/job.py +4 -1
- mlrun/frameworks/parallel_coordinates.py +2 -1
- mlrun/frameworks/tf_keras/__init__.py +4 -1
- mlrun/launcher/client.py +4 -2
- mlrun/launcher/local.py +8 -2
- mlrun/launcher/remote.py +8 -2
- mlrun/model.py +5 -1
- mlrun/model_monitoring/db/stores/__init__.py +0 -2
- mlrun/model_monitoring/db/stores/base/store.py +1 -2
- mlrun/model_monitoring/db/stores/sqldb/models/__init__.py +43 -21
- mlrun/model_monitoring/db/stores/sqldb/models/base.py +32 -2
- mlrun/model_monitoring/db/stores/sqldb/models/mysql.py +25 -5
- mlrun/model_monitoring/db/stores/sqldb/models/sqlite.py +5 -0
- mlrun/model_monitoring/db/stores/sqldb/sql_store.py +207 -139
- mlrun/model_monitoring/db/tsdb/__init__.py +1 -1
- mlrun/model_monitoring/db/tsdb/base.py +225 -38
- mlrun/model_monitoring/db/tsdb/helpers.py +30 -0
- mlrun/model_monitoring/db/tsdb/tdengine/schemas.py +48 -15
- mlrun/model_monitoring/db/tsdb/tdengine/tdengine_connector.py +182 -16
- mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +229 -42
- mlrun/model_monitoring/helpers.py +13 -0
- mlrun/model_monitoring/writer.py +36 -11
- mlrun/projects/operations.py +8 -5
- mlrun/projects/pipelines.py +42 -15
- mlrun/projects/project.py +22 -6
- mlrun/runtimes/base.py +2 -1
- mlrun/runtimes/local.py +4 -1
- mlrun/runtimes/nuclio/api_gateway.py +32 -8
- mlrun/runtimes/nuclio/application/application.py +3 -3
- mlrun/runtimes/nuclio/function.py +1 -4
- mlrun/runtimes/utils.py +5 -6
- mlrun/serving/server.py +2 -1
- mlrun/utils/helpers.py +8 -6
- mlrun/utils/logger.py +28 -1
- mlrun/utils/notifications/notification/__init__.py +14 -9
- mlrun/utils/notifications/notification_pusher.py +10 -3
- mlrun/utils/v3io_clients.py +0 -1
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.7.0rc18.dist-info → mlrun-1.7.0rc19.dist-info}/METADATA +3 -3
- {mlrun-1.7.0rc18.dist-info → mlrun-1.7.0rc19.dist-info}/RECORD +62 -59
- mlrun/model_monitoring/db/v3io_tsdb_reader.py +0 -335
- {mlrun-1.7.0rc18.dist-info → mlrun-1.7.0rc19.dist-info}/LICENSE +0 -0
- {mlrun-1.7.0rc18.dist-info → mlrun-1.7.0rc19.dist-info}/WHEEL +0 -0
- {mlrun-1.7.0rc18.dist-info → mlrun-1.7.0rc19.dist-info}/entry_points.txt +0 -0
- {mlrun-1.7.0rc18.dist-info → mlrun-1.7.0rc19.dist-info}/top_level.txt +0 -0
mlrun/projects/project.py
CHANGED
|
@@ -78,7 +78,10 @@ from ..utils.clones import (
|
|
|
78
78
|
clone_zip,
|
|
79
79
|
get_repo_url,
|
|
80
80
|
)
|
|
81
|
-
from ..utils.helpers import
|
|
81
|
+
from ..utils.helpers import (
|
|
82
|
+
ensure_git_branch,
|
|
83
|
+
resolve_git_reference_from_source,
|
|
84
|
+
)
|
|
82
85
|
from ..utils.notifications import CustomNotificationPusher, NotificationTypes
|
|
83
86
|
from .operations import (
|
|
84
87
|
BuildStatus,
|
|
@@ -1272,6 +1275,14 @@ class MlrunProject(ModelObj):
|
|
|
1272
1275
|
def description(self, description):
|
|
1273
1276
|
self.spec.description = description
|
|
1274
1277
|
|
|
1278
|
+
@property
|
|
1279
|
+
def default_function_node_selector(self) -> dict:
|
|
1280
|
+
return self.spec.default_function_node_selector
|
|
1281
|
+
|
|
1282
|
+
@default_function_node_selector.setter
|
|
1283
|
+
def default_function_node_selector(self, default_function_node_selector):
|
|
1284
|
+
self.spec.default_function_node_selector = default_function_node_selector
|
|
1285
|
+
|
|
1275
1286
|
@property
|
|
1276
1287
|
def default_image(self) -> str:
|
|
1277
1288
|
return self.spec.default_image
|
|
@@ -2992,14 +3003,17 @@ class MlrunProject(ModelObj):
|
|
|
2992
3003
|
)
|
|
2993
3004
|
workflow_spec.clear_tmp()
|
|
2994
3005
|
if (timeout or watch) and not workflow_spec.schedule:
|
|
3006
|
+
run_status_kwargs = {}
|
|
2995
3007
|
status_engine = run._engine
|
|
2996
3008
|
# run's engine gets replaced with inner engine if engine is remote,
|
|
2997
3009
|
# so in that case we need to get the status from the remote engine manually
|
|
2998
|
-
|
|
2999
|
-
if workflow_engine.engine == "remote" and status_engine.engine != "local":
|
|
3010
|
+
if workflow_engine.engine == "remote":
|
|
3000
3011
|
status_engine = _RemoteRunner
|
|
3012
|
+
run_status_kwargs["inner_engine"] = run._engine
|
|
3001
3013
|
|
|
3002
|
-
status_engine.get_run_status(
|
|
3014
|
+
status_engine.get_run_status(
|
|
3015
|
+
project=self, run=run, timeout=timeout, **run_status_kwargs
|
|
3016
|
+
)
|
|
3003
3017
|
return run
|
|
3004
3018
|
|
|
3005
3019
|
def save_workflow(self, name, target, artifact_path=None, ttl=None):
|
|
@@ -4017,8 +4031,8 @@ class MlrunProject(ModelObj):
|
|
|
4017
4031
|
self,
|
|
4018
4032
|
action: Callable,
|
|
4019
4033
|
remote: str,
|
|
4020
|
-
args: list =
|
|
4021
|
-
kwargs: dict =
|
|
4034
|
+
args: list = None,
|
|
4035
|
+
kwargs: dict = None,
|
|
4022
4036
|
secrets: Union[SecretsStore, dict] = None,
|
|
4023
4037
|
):
|
|
4024
4038
|
"""Run an arbitrary Git routine while the remote is enriched with secrets
|
|
@@ -4038,6 +4052,8 @@ class MlrunProject(ModelObj):
|
|
|
4038
4052
|
try:
|
|
4039
4053
|
if is_remote_enriched:
|
|
4040
4054
|
self.spec.repo.remotes[remote].set_url(enriched_remote, clean_remote)
|
|
4055
|
+
args = args or []
|
|
4056
|
+
kwargs = kwargs or {}
|
|
4041
4057
|
action(*args, **kwargs)
|
|
4042
4058
|
except RuntimeError as e:
|
|
4043
4059
|
raise mlrun.errors.MLRunRuntimeError(
|
mlrun/runtimes/base.py
CHANGED
|
@@ -25,6 +25,7 @@ from mlrun_pipelines.common.ops import mlrun_op
|
|
|
25
25
|
from nuclio.build import mlrun_footer
|
|
26
26
|
|
|
27
27
|
import mlrun.common.constants
|
|
28
|
+
import mlrun.common.constants as mlrun_constants
|
|
28
29
|
import mlrun.common.schemas
|
|
29
30
|
import mlrun.common.schemas.model_monitoring.constants as mm_constants
|
|
30
31
|
import mlrun.db
|
|
@@ -473,7 +474,7 @@ class BaseRuntime(ModelObj):
|
|
|
473
474
|
)
|
|
474
475
|
if runspec.spec.output_path:
|
|
475
476
|
runspec.spec.output_path = runspec.spec.output_path.replace(
|
|
476
|
-
"{{run.user}}", meta.labels[
|
|
477
|
+
"{{run.user}}", meta.labels[mlrun_constants.MLRunInternalLabels.owner]
|
|
477
478
|
)
|
|
478
479
|
|
|
479
480
|
if db and self.kind != "handler":
|
mlrun/runtimes/local.py
CHANGED
|
@@ -33,6 +33,7 @@ from sys import executable
|
|
|
33
33
|
from nuclio import Event
|
|
34
34
|
|
|
35
35
|
import mlrun
|
|
36
|
+
import mlrun.common.constants as mlrun_constants
|
|
36
37
|
from mlrun.lists import RunList
|
|
37
38
|
|
|
38
39
|
from ..errors import err_to_str
|
|
@@ -257,7 +258,8 @@ class LocalRuntime(BaseRuntime, ParallelRunner):
|
|
|
257
258
|
set_paths(os.path.realpath("."))
|
|
258
259
|
|
|
259
260
|
if (
|
|
260
|
-
runobj.metadata.labels.get(
|
|
261
|
+
runobj.metadata.labels.get(mlrun_constants.MLRunInternalLabels.kind)
|
|
262
|
+
== RemoteSparkRuntime.kind
|
|
261
263
|
and environ["MLRUN_SPARK_CLIENT_IGZ_SPARK"] == "true"
|
|
262
264
|
):
|
|
263
265
|
from mlrun.runtimes.remotesparkjob import igz_spark_pre_hook
|
|
@@ -382,6 +384,7 @@ def load_module(file_name, handler, context):
|
|
|
382
384
|
if spec is None:
|
|
383
385
|
raise RunError(f"Cannot import from {file_name!r}")
|
|
384
386
|
module = imputil.module_from_spec(spec)
|
|
387
|
+
sys.modules[mod_name] = module
|
|
385
388
|
spec.loader.exec_module(module)
|
|
386
389
|
|
|
387
390
|
class_args = {}
|
|
@@ -21,18 +21,17 @@ from nuclio.auth import AuthInfo as NuclioAuthInfo
|
|
|
21
21
|
from nuclio.auth import AuthKinds as NuclioAuthKinds
|
|
22
22
|
|
|
23
23
|
import mlrun
|
|
24
|
+
import mlrun.common.constants as mlrun_constants
|
|
24
25
|
import mlrun.common.schemas as schemas
|
|
25
26
|
import mlrun.common.types
|
|
26
27
|
from mlrun.model import ModelObj
|
|
27
28
|
from mlrun.platforms.iguazio import min_iguazio_versions
|
|
28
29
|
from mlrun.utils import logger
|
|
29
30
|
|
|
30
|
-
from .function import
|
|
31
|
+
from .function import min_nuclio_versions
|
|
31
32
|
|
|
32
|
-
PROJECT_NAME_LABEL = "nuclio.io/project-name"
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
class APIGatewayAuthenticator(typing.Protocol):
|
|
34
|
+
class Authenticator(typing.Protocol):
|
|
36
35
|
@property
|
|
37
36
|
def authentication_mode(self) -> str:
|
|
38
37
|
return schemas.APIGatewayAuthenticationMode.none.value
|
|
@@ -64,6 +63,10 @@ class APIGatewayAuthenticator(typing.Protocol):
|
|
|
64
63
|
return None
|
|
65
64
|
|
|
66
65
|
|
|
66
|
+
class APIGatewayAuthenticator(Authenticator, ModelObj):
|
|
67
|
+
_dict_fields = ["authentication_mode"]
|
|
68
|
+
|
|
69
|
+
|
|
67
70
|
class NoneAuth(APIGatewayAuthenticator):
|
|
68
71
|
"""
|
|
69
72
|
An API gateway authenticator with no authentication.
|
|
@@ -284,7 +287,21 @@ class APIGatewaySpec(ModelObj):
|
|
|
284
287
|
function_names = []
|
|
285
288
|
for func in functions:
|
|
286
289
|
if isinstance(func, str):
|
|
287
|
-
|
|
290
|
+
# check whether the function was passed as a URI or just a name
|
|
291
|
+
parsed_project, function_name, _, _ = (
|
|
292
|
+
mlrun.common.helpers.parse_versioned_object_uri(func)
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
if parsed_project and function_name:
|
|
296
|
+
# check that parsed project and passed project are the same
|
|
297
|
+
if parsed_project != project:
|
|
298
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
299
|
+
"Function doesn't belong to passed project"
|
|
300
|
+
)
|
|
301
|
+
function_uri = func
|
|
302
|
+
else:
|
|
303
|
+
function_uri = mlrun.utils.generate_object_uri(project, func)
|
|
304
|
+
function_names.append(function_uri)
|
|
288
305
|
continue
|
|
289
306
|
|
|
290
307
|
function_name = (
|
|
@@ -299,8 +316,13 @@ class APIGatewaySpec(ModelObj):
|
|
|
299
316
|
f"input function {function_name} "
|
|
300
317
|
f"does not belong to this project"
|
|
301
318
|
)
|
|
302
|
-
|
|
303
|
-
|
|
319
|
+
function_uri = mlrun.utils.generate_object_uri(
|
|
320
|
+
project,
|
|
321
|
+
function_name,
|
|
322
|
+
func.metadata.tag,
|
|
323
|
+
func.metadata.hash,
|
|
324
|
+
)
|
|
325
|
+
function_names.append(function_uri)
|
|
304
326
|
return function_names
|
|
305
327
|
|
|
306
328
|
|
|
@@ -526,7 +548,9 @@ class APIGateway(ModelObj):
|
|
|
526
548
|
|
|
527
549
|
@classmethod
|
|
528
550
|
def from_scheme(cls, api_gateway: schemas.APIGateway):
|
|
529
|
-
project = api_gateway.metadata.labels.get(
|
|
551
|
+
project = api_gateway.metadata.labels.get(
|
|
552
|
+
mlrun_constants.MLRunInternalLabels.nuclio_project_name
|
|
553
|
+
)
|
|
530
554
|
functions, canary = cls._resolve_canary(api_gateway.spec.upstreams)
|
|
531
555
|
state = (
|
|
532
556
|
api_gateway.status.state
|
|
@@ -172,7 +172,7 @@ class ApplicationStatus(NuclioStatus):
|
|
|
172
172
|
class ApplicationRuntime(RemoteRuntime):
|
|
173
173
|
kind = "application"
|
|
174
174
|
|
|
175
|
-
@min_nuclio_versions("1.
|
|
175
|
+
@min_nuclio_versions("1.13.1")
|
|
176
176
|
def __init__(self, spec=None, metadata=None):
|
|
177
177
|
super().__init__(spec=spec, metadata=metadata)
|
|
178
178
|
|
|
@@ -387,7 +387,7 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
387
387
|
elif authentication_mode == schemas.APIGatewayAuthenticationMode.basic:
|
|
388
388
|
api_gateway.with_basic_auth(*authentication_creds)
|
|
389
389
|
|
|
390
|
-
db =
|
|
390
|
+
db = self._get_db()
|
|
391
391
|
api_gateway_scheme = db.store_api_gateway(
|
|
392
392
|
api_gateway=api_gateway.to_scheme(), project=self.metadata.project
|
|
393
393
|
)
|
|
@@ -505,7 +505,7 @@ class ApplicationRuntime(RemoteRuntime):
|
|
|
505
505
|
if not self.status.api_gateway_name:
|
|
506
506
|
return
|
|
507
507
|
|
|
508
|
-
db =
|
|
508
|
+
db = self._get_db()
|
|
509
509
|
api_gateway_scheme = db.get_api_gateway(
|
|
510
510
|
name=self.status.api_gateway_name, project=self.metadata.project
|
|
511
511
|
)
|
|
@@ -65,10 +65,7 @@ def min_nuclio_versions(*versions):
|
|
|
65
65
|
if validate_nuclio_version_compatibility(*versions):
|
|
66
66
|
return function(*args, **kwargs)
|
|
67
67
|
|
|
68
|
-
message = (
|
|
69
|
-
f"{function.__name__} is supported since nuclio {' or '.join(versions)}, currently using "
|
|
70
|
-
f"nuclio {mlconf.nuclio_version}, please upgrade."
|
|
71
|
-
)
|
|
68
|
+
message = f"'{function.__qualname__}' function requires Nuclio v{' or v'.join(versions)} or higher"
|
|
72
69
|
raise mlrun.errors.MLRunIncompatibleVersionError(message)
|
|
73
70
|
|
|
74
71
|
return wrapper
|
mlrun/runtimes/utils.py
CHANGED
|
@@ -23,6 +23,7 @@ import pandas as pd
|
|
|
23
23
|
|
|
24
24
|
import mlrun
|
|
25
25
|
import mlrun.common.constants
|
|
26
|
+
import mlrun.common.constants as mlrun_constants
|
|
26
27
|
import mlrun.common.schemas
|
|
27
28
|
import mlrun.utils.regex
|
|
28
29
|
from mlrun.artifacts import TableArtifact
|
|
@@ -38,9 +39,6 @@ class RunError(Exception):
|
|
|
38
39
|
pass
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
mlrun_key = "mlrun/"
|
|
42
|
-
|
|
43
|
-
|
|
44
42
|
class _ContextStore:
|
|
45
43
|
def __init__(self):
|
|
46
44
|
self._context = None
|
|
@@ -372,10 +370,10 @@ def generate_resources(mem=None, cpu=None, gpus=None, gpu_type="nvidia.com/gpu")
|
|
|
372
370
|
|
|
373
371
|
|
|
374
372
|
def get_func_selector(project, name=None, tag=None):
|
|
375
|
-
s = [f"{
|
|
373
|
+
s = [f"{mlrun_constants.MLRunInternalLabels.project}={project}"]
|
|
376
374
|
if name:
|
|
377
|
-
s.append(f"{
|
|
378
|
-
s.append(f"{
|
|
375
|
+
s.append(f"{mlrun_constants.MLRunInternalLabels.function}={name}")
|
|
376
|
+
s.append(f"{mlrun_constants.MLRunInternalLabels.tag}={tag or 'latest'}")
|
|
379
377
|
return s
|
|
380
378
|
|
|
381
379
|
|
|
@@ -438,6 +436,7 @@ def enrich_run_labels(
|
|
|
438
436
|
):
|
|
439
437
|
labels_enrichment = {
|
|
440
438
|
RunLabels.owner: os.environ.get("V3IO_USERNAME") or getpass.getuser(),
|
|
439
|
+
# TODO: remove this in 1.9.0
|
|
441
440
|
RunLabels.v3io_user: os.environ.get("V3IO_USERNAME"),
|
|
442
441
|
}
|
|
443
442
|
labels_to_enrich = labels_to_enrich or RunLabels.all()
|
mlrun/serving/server.py
CHANGED
|
@@ -387,7 +387,7 @@ def v2_serving_handler(context, event, get_body=False):
|
|
|
387
387
|
|
|
388
388
|
|
|
389
389
|
def create_graph_server(
|
|
390
|
-
parameters=
|
|
390
|
+
parameters=None,
|
|
391
391
|
load_mode=None,
|
|
392
392
|
graph=None,
|
|
393
393
|
verbose=False,
|
|
@@ -403,6 +403,7 @@ def create_graph_server(
|
|
|
403
403
|
server.graph.add_route("my", class_name=MyModelClass, model_path="{path}", z=100)
|
|
404
404
|
print(server.test("/v2/models/my/infer", testdata))
|
|
405
405
|
"""
|
|
406
|
+
parameters = parameters or {}
|
|
406
407
|
server = GraphServer(graph, parameters, load_mode, verbose=verbose, **kwargs)
|
|
407
408
|
server.set_current_function(
|
|
408
409
|
current_function or os.environ.get("SERVING_CURRENT_FUNCTION", "")
|
mlrun/utils/helpers.py
CHANGED
|
@@ -1106,7 +1106,7 @@ def get_function(function, namespace):
|
|
|
1106
1106
|
|
|
1107
1107
|
|
|
1108
1108
|
def get_handler_extended(
|
|
1109
|
-
handler_path: str, context=None, class_args: dict =
|
|
1109
|
+
handler_path: str, context=None, class_args: dict = None, namespaces=None
|
|
1110
1110
|
):
|
|
1111
1111
|
"""get function handler from [class_name::]handler string
|
|
1112
1112
|
|
|
@@ -1116,6 +1116,7 @@ def get_handler_extended(
|
|
|
1116
1116
|
:param namespaces: one or list of namespaces/modules to search the handler in
|
|
1117
1117
|
:return: function handler (callable)
|
|
1118
1118
|
"""
|
|
1119
|
+
class_args = class_args or {}
|
|
1119
1120
|
if "::" not in handler_path:
|
|
1120
1121
|
return get_function(handler_path, namespaces)
|
|
1121
1122
|
|
|
@@ -1585,11 +1586,12 @@ def validate_component_version_compatibility(
|
|
|
1585
1586
|
component_current_version = mlrun.mlconf.igz_version
|
|
1586
1587
|
parsed_current_version = mlrun.mlconf.get_parsed_igz_version()
|
|
1587
1588
|
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1589
|
+
if parsed_current_version:
|
|
1590
|
+
# ignore pre-release and build metadata, as iguazio version always has them, and we only care about the
|
|
1591
|
+
# major, minor, and patch versions
|
|
1592
|
+
parsed_current_version = semver.VersionInfo.parse(
|
|
1593
|
+
f"{parsed_current_version.major}.{parsed_current_version.minor}.{parsed_current_version.patch}"
|
|
1594
|
+
)
|
|
1593
1595
|
if component_name == "nuclio":
|
|
1594
1596
|
component_current_version = mlrun.mlconf.nuclio_version
|
|
1595
1597
|
parsed_current_version = semver.VersionInfo.parse(
|
mlrun/utils/logger.py
CHANGED
|
@@ -93,7 +93,25 @@ class HumanReadableFormatter(_BaseFormatter):
|
|
|
93
93
|
|
|
94
94
|
class HumanReadableExtendedFormatter(HumanReadableFormatter):
|
|
95
95
|
def format(self, record) -> str:
|
|
96
|
-
more =
|
|
96
|
+
more = ""
|
|
97
|
+
record_with = self._record_with(record)
|
|
98
|
+
if record_with:
|
|
99
|
+
|
|
100
|
+
def _format_value(val):
|
|
101
|
+
formatted_val = (
|
|
102
|
+
val
|
|
103
|
+
if isinstance(val, str)
|
|
104
|
+
else str(orjson.loads(self._json_dump(val)))
|
|
105
|
+
)
|
|
106
|
+
return (
|
|
107
|
+
formatted_val.replace("\n", "\n\t\t")
|
|
108
|
+
if len(formatted_val) < 4096
|
|
109
|
+
else repr(formatted_val)
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
more = "\n\t" + "\n\t".join(
|
|
113
|
+
[f"{key}: {_format_value(val)}" for key, val in record_with.items()]
|
|
114
|
+
)
|
|
97
115
|
return (
|
|
98
116
|
"> "
|
|
99
117
|
f"{self.formatTime(record, self.datefmt)} "
|
|
@@ -234,6 +252,15 @@ def resolve_formatter_by_kind(
|
|
|
234
252
|
}[formatter_kind]
|
|
235
253
|
|
|
236
254
|
|
|
255
|
+
def create_test_logger(name: str = "mlrun", stream: IO[str] = stdout) -> Logger:
|
|
256
|
+
return create_logger(
|
|
257
|
+
level="debug",
|
|
258
|
+
formatter_kind=FormatterKinds.HUMAN_EXTENDED.name,
|
|
259
|
+
name=name,
|
|
260
|
+
stream=stream,
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
|
|
237
264
|
def create_logger(
|
|
238
265
|
level: Optional[str] = None,
|
|
239
266
|
formatter_kind: str = FormatterKinds.HUMAN.name,
|
|
@@ -51,14 +51,19 @@ class NotificationTypes(str, enum.Enum):
|
|
|
51
51
|
self.console: [self.ipython],
|
|
52
52
|
}.get(self, [])
|
|
53
53
|
|
|
54
|
+
@classmethod
|
|
55
|
+
def local(cls) -> list[str]:
|
|
56
|
+
return [
|
|
57
|
+
cls.console,
|
|
58
|
+
cls.ipython,
|
|
59
|
+
]
|
|
60
|
+
|
|
54
61
|
@classmethod
|
|
55
62
|
def all(cls) -> list[str]:
|
|
56
|
-
return
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
]
|
|
64
|
-
)
|
|
63
|
+
return [
|
|
64
|
+
cls.console,
|
|
65
|
+
cls.git,
|
|
66
|
+
cls.ipython,
|
|
67
|
+
cls.slack,
|
|
68
|
+
cls.webhook,
|
|
69
|
+
]
|
|
@@ -24,6 +24,7 @@ import kfp
|
|
|
24
24
|
import mlrun_pipelines.common.ops
|
|
25
25
|
import mlrun_pipelines.models
|
|
26
26
|
|
|
27
|
+
import mlrun.common.constants as mlrun_constants
|
|
27
28
|
import mlrun.common.runtimes.constants
|
|
28
29
|
import mlrun.common.schemas
|
|
29
30
|
import mlrun.config
|
|
@@ -239,8 +240,8 @@ class NotificationPusher(_NotificationPusherBase):
|
|
|
239
240
|
resource = "Run"
|
|
240
241
|
runs = [run.to_dict()]
|
|
241
242
|
|
|
242
|
-
if
|
|
243
|
-
resource =
|
|
243
|
+
if mlrun_constants.MLRunInternalLabels.workflow in run.metadata.labels:
|
|
244
|
+
resource = mlrun_constants.MLRunInternalLabels.workflow
|
|
244
245
|
custom_message = (
|
|
245
246
|
f" (workflow: {run.metadata.labels['workflow']}){custom_message}"
|
|
246
247
|
)
|
|
@@ -396,7 +397,7 @@ class NotificationPusher(_NotificationPusherBase):
|
|
|
396
397
|
try:
|
|
397
398
|
_run = db.list_runs(
|
|
398
399
|
project=run.metadata.project,
|
|
399
|
-
labels=f"
|
|
400
|
+
labels=f"mlrun_constants.MLRunInternalLabels.runner_pod={_step.node_name}",
|
|
400
401
|
)[0]
|
|
401
402
|
except IndexError:
|
|
402
403
|
_run = {
|
|
@@ -537,6 +538,12 @@ class CustomNotificationPusher(_NotificationPusherBase):
|
|
|
537
538
|
if notification.is_async
|
|
538
539
|
}
|
|
539
540
|
|
|
541
|
+
@property
|
|
542
|
+
def notifications(self):
|
|
543
|
+
notifications = self._sync_notifications.copy()
|
|
544
|
+
notifications.update(self._async_notifications)
|
|
545
|
+
return notifications
|
|
546
|
+
|
|
540
547
|
def push(
|
|
541
548
|
self,
|
|
542
549
|
message: str,
|
mlrun/utils/v3io_clients.py
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
#
|
|
15
14
|
|
|
16
15
|
from v3io.dataplane import Client as V3IOClient
|
|
17
16
|
from v3io_frames import Client as get_client
|
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.0rc19
|
|
4
4
|
Summary: Tracking and config of machine learning runs
|
|
5
5
|
Home-page: https://github.com/mlrun/mlrun
|
|
6
6
|
Author: Yaron Haviv
|
|
@@ -50,8 +50,8 @@ Requires-Dist: setuptools ~=69.1
|
|
|
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
|
|
54
|
-
Requires-Dist: mlrun-pipelines-kfp-v1-8
|
|
53
|
+
Requires-Dist: mlrun-pipelines-kfp-common ~=0.1.0
|
|
54
|
+
Requires-Dist: mlrun-pipelines-kfp-v1-8 ~=0.1.0
|
|
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'
|