mlrun 1.3.1rc3__py3-none-any.whl → 1.3.1rc5__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/api/api/endpoints/healthz.py +18 -5
- mlrun/config.py +3 -0
- mlrun/datastore/spark_udf.py +8 -5
- mlrun/datastore/store_resources.py +1 -1
- mlrun/datastore/targets.py +2 -2
- mlrun/errors.py +5 -0
- mlrun/feature_store/api.py +9 -0
- mlrun/feature_store/feature_set.py +4 -0
- mlrun/platforms/iguazio.py +2 -0
- mlrun/serving/__init__.py +2 -1
- mlrun/serving/states.py +148 -21
- mlrun/utils/version/version.json +2 -2
- {mlrun-1.3.1rc3.dist-info → mlrun-1.3.1rc5.dist-info}/METADATA +2 -2
- {mlrun-1.3.1rc3.dist-info → mlrun-1.3.1rc5.dist-info}/RECORD +18 -18
- {mlrun-1.3.1rc3.dist-info → mlrun-1.3.1rc5.dist-info}/LICENSE +0 -0
- {mlrun-1.3.1rc3.dist-info → mlrun-1.3.1rc5.dist-info}/WHEEL +0 -0
- {mlrun-1.3.1rc3.dist-info → mlrun-1.3.1rc5.dist-info}/entry_points.txt +0 -0
- {mlrun-1.3.1rc3.dist-info → mlrun-1.3.1rc5.dist-info}/top_level.txt +0 -0
|
@@ -12,20 +12,33 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
#
|
|
15
|
+
import http
|
|
16
|
+
|
|
15
17
|
from fastapi import APIRouter
|
|
16
18
|
|
|
17
|
-
import mlrun.api.crud
|
|
18
19
|
import mlrun.api.schemas
|
|
20
|
+
from mlrun.config import config as mlconfig
|
|
19
21
|
|
|
20
22
|
router = APIRouter()
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
@router.get(
|
|
24
26
|
"/healthz",
|
|
25
|
-
|
|
27
|
+
status_code=http.HTTPStatus.OK.value,
|
|
26
28
|
)
|
|
27
29
|
def health():
|
|
28
30
|
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
|
|
31
|
+
# offline is the initial state
|
|
32
|
+
# waiting for chief is set for workers waiting for chief to be ready and then clusterize against it
|
|
33
|
+
if mlconfig.httpdb.state in [
|
|
34
|
+
mlrun.api.schemas.APIStates.offline,
|
|
35
|
+
mlrun.api.schemas.APIStates.waiting_for_chief,
|
|
36
|
+
]:
|
|
37
|
+
raise mlrun.errors.MLRunServiceUnavailableError()
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
# for old `align_mlrun.sh` scripts expecting `version` in the response
|
|
41
|
+
# TODO: remove on mlrun >= 1.6.0
|
|
42
|
+
"version": mlconfig.version,
|
|
43
|
+
"status": "ok",
|
|
44
|
+
}
|
mlrun/config.py
CHANGED
|
@@ -1049,15 +1049,18 @@ def read_env(env=None, prefix=env_prefix):
|
|
|
1049
1049
|
cfg[path[0]] = value
|
|
1050
1050
|
|
|
1051
1051
|
env_dbpath = env.get("MLRUN_DBPATH", "")
|
|
1052
|
+
# expected format: https://mlrun-api.tenant.default-tenant.app.some-system.some-namespace.com
|
|
1052
1053
|
is_remote_mlrun = (
|
|
1053
1054
|
env_dbpath.startswith("https://mlrun-api.") and "tenant." in env_dbpath
|
|
1054
1055
|
)
|
|
1056
|
+
|
|
1055
1057
|
# It's already a standard to set this env var to configure the v3io api, so we're supporting it (instead
|
|
1056
1058
|
# of MLRUN_V3IO_API), in remote usage this can be auto detected from the DBPATH
|
|
1057
1059
|
v3io_api = env.get("V3IO_API")
|
|
1058
1060
|
if v3io_api:
|
|
1059
1061
|
config["v3io_api"] = v3io_api
|
|
1060
1062
|
elif is_remote_mlrun:
|
|
1063
|
+
# in remote mlrun we can't use http, so we'll use https
|
|
1061
1064
|
config["v3io_api"] = env_dbpath.replace("https://mlrun-api.", "https://webapi.")
|
|
1062
1065
|
|
|
1063
1066
|
# It's already a standard to set this env var to configure the v3io framesd, so we're supporting it (instead
|
mlrun/datastore/spark_udf.py
CHANGED
|
@@ -26,11 +26,14 @@ def _hash_list(*list_to_hash):
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def _redis_stringify_key(key_list):
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
try:
|
|
30
|
+
if len(key_list) >= 2:
|
|
31
|
+
return str(key_list[0]) + "." + _hash_list(key_list[1:]) + "}:static"
|
|
32
|
+
if len(key_list) == 2:
|
|
33
|
+
return str(key_list[0]) + "." + str(key_list[1]) + "}:static"
|
|
34
|
+
return str(key_list[0]) + "}:static"
|
|
35
|
+
except TypeError:
|
|
36
|
+
return str(key_list) + "}:static"
|
|
34
37
|
|
|
35
38
|
|
|
36
39
|
hash_and_concat_v3io_udf = udf(_hash_list, StringType())
|
|
@@ -81,7 +81,7 @@ class ResourceCache:
|
|
|
81
81
|
endpoint, uri = parse_path(uri)
|
|
82
82
|
self._tabels[uri] = Table(
|
|
83
83
|
uri,
|
|
84
|
-
V3ioDriver(webapi=endpoint),
|
|
84
|
+
V3ioDriver(webapi=endpoint or mlrun.mlconf.v3io_api),
|
|
85
85
|
flush_interval_secs=mlrun.mlconf.feature_store.flush_interval,
|
|
86
86
|
)
|
|
87
87
|
return self._tabels[uri]
|
mlrun/datastore/targets.py
CHANGED
|
@@ -1102,7 +1102,7 @@ class NoSqlTarget(NoSqlBaseTarget):
|
|
|
1102
1102
|
endpoint, uri = parse_path(self.get_target_path())
|
|
1103
1103
|
return Table(
|
|
1104
1104
|
uri,
|
|
1105
|
-
V3ioDriver(webapi=endpoint),
|
|
1105
|
+
V3ioDriver(webapi=endpoint or mlrun.mlconf.v3io_api),
|
|
1106
1106
|
flush_interval_secs=mlrun.mlconf.feature_store.flush_interval,
|
|
1107
1107
|
)
|
|
1108
1108
|
|
|
@@ -1257,7 +1257,7 @@ class StreamTarget(BaseStoreTarget):
|
|
|
1257
1257
|
graph_shape="cylinder",
|
|
1258
1258
|
class_name="storey.StreamTarget",
|
|
1259
1259
|
columns=column_list,
|
|
1260
|
-
storage=V3ioDriver(webapi=endpoint),
|
|
1260
|
+
storage=V3ioDriver(webapi=endpoint or mlrun.mlconf.v3io_api),
|
|
1261
1261
|
stream_path=uri,
|
|
1262
1262
|
**self.attributes,
|
|
1263
1263
|
)
|
mlrun/errors.py
CHANGED
|
@@ -179,6 +179,10 @@ class MLRunInternalServerError(MLRunHTTPStatusError):
|
|
|
179
179
|
error_status_code = HTTPStatus.INTERNAL_SERVER_ERROR.value
|
|
180
180
|
|
|
181
181
|
|
|
182
|
+
class MLRunServiceUnavailableError(MLRunHTTPStatusError):
|
|
183
|
+
error_status_code = HTTPStatus.SERVICE_UNAVAILABLE.value
|
|
184
|
+
|
|
185
|
+
|
|
182
186
|
class MLRunRuntimeError(MLRunHTTPStatusError, RuntimeError):
|
|
183
187
|
error_status_code = HTTPStatus.INTERNAL_SERVER_ERROR.value
|
|
184
188
|
|
|
@@ -213,4 +217,5 @@ STATUS_ERRORS = {
|
|
|
213
217
|
HTTPStatus.CONFLICT.value: MLRunConflictError,
|
|
214
218
|
HTTPStatus.PRECONDITION_FAILED.value: MLRunPreconditionFailedError,
|
|
215
219
|
HTTPStatus.INTERNAL_SERVER_ERROR.value: MLRunInternalServerError,
|
|
220
|
+
HTTPStatus.SERVICE_UNAVAILABLE.value: MLRunServiceUnavailableError,
|
|
216
221
|
}
|
mlrun/feature_store/api.py
CHANGED
|
@@ -410,6 +410,15 @@ def ingest(
|
|
|
410
410
|
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
411
411
|
"feature set and source must be specified"
|
|
412
412
|
)
|
|
413
|
+
if (
|
|
414
|
+
not mlrun_context
|
|
415
|
+
and not targets
|
|
416
|
+
and not (featureset.spec.targets or featureset.spec.with_default_targets)
|
|
417
|
+
):
|
|
418
|
+
raise mlrun.errors.MLRunInvalidArgumentError(
|
|
419
|
+
f"No targets provided to feature set {featureset.metadata.name} ingest, aborting.\n"
|
|
420
|
+
"(preview can be used as an alternative to local ingest when targets are not needed)"
|
|
421
|
+
)
|
|
413
422
|
|
|
414
423
|
if featureset is not None:
|
|
415
424
|
featureset.validate_steps(namespace=namespace)
|
|
@@ -131,6 +131,7 @@ class FeatureSetSpec(ModelObj):
|
|
|
131
131
|
self.engine = engine
|
|
132
132
|
self.output_path = output_path or mlconf.artifact_path
|
|
133
133
|
self.passthrough = passthrough
|
|
134
|
+
self.with_default_targets = True
|
|
134
135
|
|
|
135
136
|
@property
|
|
136
137
|
def entities(self) -> List[Entity]:
|
|
@@ -473,7 +474,10 @@ class FeatureSet(ModelObj):
|
|
|
473
474
|
)
|
|
474
475
|
targets = targets or []
|
|
475
476
|
if with_defaults:
|
|
477
|
+
self.spec.with_default_targets = True
|
|
476
478
|
targets.extend(get_default_targets())
|
|
479
|
+
else:
|
|
480
|
+
self.spec.with_default_targets = False
|
|
477
481
|
|
|
478
482
|
validate_target_list(targets=targets)
|
|
479
483
|
|
mlrun/platforms/iguazio.py
CHANGED
|
@@ -650,6 +650,8 @@ def parse_path(url, suffix="/"):
|
|
|
650
650
|
)
|
|
651
651
|
endpoint = f"{prefix}://{parsed_url.netloc}"
|
|
652
652
|
else:
|
|
653
|
+
# no netloc is mainly when using v3io (v3io:///) and expecting the url to be resolved automatically from env or
|
|
654
|
+
# config
|
|
653
655
|
endpoint = None
|
|
654
656
|
return endpoint, parsed_url.path.strip("/") + suffix
|
|
655
657
|
|
mlrun/serving/__init__.py
CHANGED
|
@@ -21,10 +21,11 @@ __all__ = [
|
|
|
21
21
|
"TaskStep",
|
|
22
22
|
"RouterStep",
|
|
23
23
|
"QueueStep",
|
|
24
|
+
"ErrorStep",
|
|
24
25
|
]
|
|
25
26
|
|
|
26
27
|
from .routers import ModelRouter, VotingEnsemble # noqa
|
|
27
28
|
from .server import GraphContext, GraphServer, create_graph_server # noqa
|
|
28
|
-
from .states import QueueStep, RouterStep, TaskStep # noqa
|
|
29
|
+
from .states import ErrorStep, QueueStep, RouterStep, TaskStep # noqa
|
|
29
30
|
from .v1_serving import MLModelServer, new_v1_model_server # noqa
|
|
30
31
|
from .v2_serving import V2ModelServer # noqa
|
mlrun/serving/states.py
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
-
__all__ = ["TaskStep", "RouterStep", "RootFlowStep"]
|
|
15
|
+
__all__ = ["TaskStep", "RouterStep", "RootFlowStep", "ErrorStep"]
|
|
16
16
|
|
|
17
17
|
import os
|
|
18
18
|
import pathlib
|
|
@@ -49,6 +49,7 @@ class StepKinds:
|
|
|
49
49
|
queue = "queue"
|
|
50
50
|
choice = "choice"
|
|
51
51
|
root = "root"
|
|
52
|
+
error_step = "error_step"
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
_task_step_fields = [
|
|
@@ -134,11 +135,82 @@ class BaseStep(ModelObj):
|
|
|
134
135
|
self.after.append(name)
|
|
135
136
|
return self
|
|
136
137
|
|
|
137
|
-
def error_handler(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
def error_handler(
|
|
139
|
+
self,
|
|
140
|
+
name: str = None,
|
|
141
|
+
class_name=None,
|
|
142
|
+
handler=None,
|
|
143
|
+
before=None,
|
|
144
|
+
function=None,
|
|
145
|
+
full_event: bool = None,
|
|
146
|
+
input_path: str = None,
|
|
147
|
+
result_path: str = None,
|
|
148
|
+
**class_args,
|
|
149
|
+
):
|
|
150
|
+
"""set error handler on a step or the entire graph (to be executed on failure/raise)
|
|
151
|
+
|
|
152
|
+
When setting the error_handler on the graph object, the graph completes after the error handler execution.
|
|
153
|
+
|
|
154
|
+
example:
|
|
155
|
+
in the below example, an 'error_catcher' step is set as the error_handler of the 'raise' step:
|
|
156
|
+
in case of error/raise in 'raise' step, the handle_error will be run. after that,
|
|
157
|
+
the 'echo' step will be run.
|
|
158
|
+
graph = function.set_topology('flow', engine='async')
|
|
159
|
+
graph.to(name='raise', handler='raising_step')\
|
|
160
|
+
.error_handler(name='error_catcher', handler='handle_error', full_event=True, before='echo')
|
|
161
|
+
graph.add_step(name="echo", handler='echo', after="raise").respond()
|
|
162
|
+
|
|
163
|
+
:param name: unique name (and path) for the error handler step, default is class name
|
|
164
|
+
:param class_name: class name or step object to build the step from
|
|
165
|
+
the error handler step is derived from task step (ie no router/queue functionally)
|
|
166
|
+
:param handler: class/function handler to invoke on run/event
|
|
167
|
+
:param before: string or list of next step(s) names that will run after this step.
|
|
168
|
+
the `before` param must not specify upstream steps as it will cause a loop.
|
|
169
|
+
if `before` is not specified, the graph will complete after the error handler execution.
|
|
170
|
+
:param function: function this step should run in
|
|
171
|
+
:param full_event: this step accepts the full event (not just the body)
|
|
172
|
+
:param input_path: selects the key/path in the event to use as input to the step
|
|
173
|
+
this requires that the event body will behave like a dict, for example:
|
|
174
|
+
event: {"data": {"a": 5, "b": 7}}, input_path="data.b" means the step will
|
|
175
|
+
receive 7 as input
|
|
176
|
+
:param result_path: selects the key/path in the event to write the results to
|
|
177
|
+
this requires that the event body will behave like a dict, for example:
|
|
178
|
+
event: {"x": 5} , result_path="y" means the output of the step will be written
|
|
179
|
+
to event["y"] resulting in {"x": 5, "y": <result>}
|
|
180
|
+
:param class_args: class init arguments
|
|
181
|
+
|
|
182
|
+
"""
|
|
183
|
+
if not (class_name or handler):
|
|
184
|
+
raise MLRunInvalidArgumentError("class_name or handler must be provided")
|
|
185
|
+
if isinstance(self, RootFlowStep) and before:
|
|
186
|
+
raise MLRunInvalidArgumentError(
|
|
187
|
+
"`before` arg can't be specified for graph error handler"
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
name = get_name(name, class_name)
|
|
191
|
+
step = ErrorStep(
|
|
192
|
+
class_name,
|
|
193
|
+
class_args,
|
|
194
|
+
handler,
|
|
195
|
+
name=name,
|
|
196
|
+
function=function,
|
|
197
|
+
full_event=full_event,
|
|
198
|
+
input_path=input_path,
|
|
199
|
+
result_path=result_path,
|
|
200
|
+
)
|
|
201
|
+
self.on_error = name
|
|
202
|
+
before = [before] if isinstance(before, str) else before
|
|
203
|
+
step.before = before or []
|
|
204
|
+
step.base_step = self.name
|
|
205
|
+
if hasattr(self, "_parent") and self._parent:
|
|
206
|
+
# when self is a step
|
|
207
|
+
step = self._parent._steps.update(name, step)
|
|
208
|
+
step.set_parent(self._parent)
|
|
209
|
+
else:
|
|
210
|
+
# when self is the graph
|
|
211
|
+
step = self._steps.update(name, step)
|
|
212
|
+
step.set_parent(self)
|
|
213
|
+
|
|
142
214
|
return self
|
|
143
215
|
|
|
144
216
|
def init_object(self, context, namespace, mode="sync", reset=False, **extra_kwargs):
|
|
@@ -186,10 +258,11 @@ class BaseStep(ModelObj):
|
|
|
186
258
|
|
|
187
259
|
def _call_error_handler(self, event, err, **kwargs):
|
|
188
260
|
"""call the error handler if exist"""
|
|
189
|
-
if
|
|
190
|
-
event.error =
|
|
191
|
-
|
|
192
|
-
|
|
261
|
+
if not event.error:
|
|
262
|
+
event.error = {}
|
|
263
|
+
event.error[self.name] = err_to_str(err)
|
|
264
|
+
event.origin_state = self.fullname
|
|
265
|
+
return self._on_error_handler(event)
|
|
193
266
|
|
|
194
267
|
def path_to_step(self, path: str):
|
|
195
268
|
"""return step object from step relative/fullname"""
|
|
@@ -327,6 +400,7 @@ class TaskStep(BaseStep):
|
|
|
327
400
|
args = signature(self._handler).parameters
|
|
328
401
|
if args and "context" in list(args.keys()):
|
|
329
402
|
self._inject_context = True
|
|
403
|
+
self._set_error_handler()
|
|
330
404
|
return
|
|
331
405
|
|
|
332
406
|
self._class_object, self.class_name = self.get_step_class_object(
|
|
@@ -464,14 +538,23 @@ class TaskStep(BaseStep):
|
|
|
464
538
|
)
|
|
465
539
|
event.body = _update_result_body(self.result_path, event.body, result)
|
|
466
540
|
except Exception as exc:
|
|
467
|
-
self.
|
|
468
|
-
|
|
469
|
-
|
|
541
|
+
if self._on_error_handler:
|
|
542
|
+
self._log_error(event, exc)
|
|
543
|
+
result = self._call_error_handler(event, exc)
|
|
544
|
+
event.body = _update_result_body(self.result_path, event.body, result)
|
|
545
|
+
else:
|
|
470
546
|
raise exc
|
|
471
|
-
event.terminated = True
|
|
472
547
|
return event
|
|
473
548
|
|
|
474
549
|
|
|
550
|
+
class ErrorStep(TaskStep):
|
|
551
|
+
"""error execution step, runs a class or handler"""
|
|
552
|
+
|
|
553
|
+
kind = "error_step"
|
|
554
|
+
_dict_fields = _task_step_fields + ["before", "base_step"]
|
|
555
|
+
_default_class = ""
|
|
556
|
+
|
|
557
|
+
|
|
475
558
|
class RouterStep(TaskStep):
|
|
476
559
|
"""router step, implement routing logic for running child routes"""
|
|
477
560
|
|
|
@@ -824,6 +907,7 @@ class FlowStep(BaseStep):
|
|
|
824
907
|
def init_object(self, context, namespace, mode="sync", reset=False, **extra_kwargs):
|
|
825
908
|
"""initialize graph objects and classes"""
|
|
826
909
|
self.context = context
|
|
910
|
+
self._insert_all_error_handlers()
|
|
827
911
|
self.check_and_process_graph()
|
|
828
912
|
|
|
829
913
|
for step in self._steps.values():
|
|
@@ -866,7 +950,11 @@ class FlowStep(BaseStep):
|
|
|
866
950
|
|
|
867
951
|
responders = []
|
|
868
952
|
for step in self._steps.values():
|
|
869
|
-
if
|
|
953
|
+
if (
|
|
954
|
+
hasattr(step, "responder")
|
|
955
|
+
and step.responder
|
|
956
|
+
and step.kind != "error_step"
|
|
957
|
+
):
|
|
870
958
|
responders.append(step.name)
|
|
871
959
|
if step.on_error and step.on_error in start_steps:
|
|
872
960
|
start_steps.remove(step.on_error)
|
|
@@ -979,6 +1067,10 @@ class FlowStep(BaseStep):
|
|
|
979
1067
|
# never set a step as its own error handler
|
|
980
1068
|
if step != error_step:
|
|
981
1069
|
step.async_object.set_recovery_step(error_step.async_object)
|
|
1070
|
+
for next_step in error_step.next or []:
|
|
1071
|
+
next_state = self[next_step]
|
|
1072
|
+
if next_state.async_object and error_step.async_object:
|
|
1073
|
+
error_step.async_object.to(next_state.async_object)
|
|
982
1074
|
|
|
983
1075
|
self._controller = source.run()
|
|
984
1076
|
|
|
@@ -1059,15 +1151,22 @@ class FlowStep(BaseStep):
|
|
|
1059
1151
|
try:
|
|
1060
1152
|
event = next_obj.run(event, *args, **kwargs)
|
|
1061
1153
|
except Exception as exc:
|
|
1062
|
-
self.
|
|
1063
|
-
|
|
1064
|
-
|
|
1154
|
+
if self._on_error_handler:
|
|
1155
|
+
self._log_error(event, exc, failed_step=next_obj.name)
|
|
1156
|
+
event.body = self._call_error_handler(event, exc)
|
|
1157
|
+
event.terminated = True
|
|
1158
|
+
return event
|
|
1159
|
+
else:
|
|
1065
1160
|
raise exc
|
|
1066
|
-
event.terminated = True
|
|
1067
|
-
return event
|
|
1068
1161
|
|
|
1069
1162
|
if hasattr(event, "terminated") and event.terminated:
|
|
1070
1163
|
return event
|
|
1164
|
+
if (
|
|
1165
|
+
hasattr(event, "error")
|
|
1166
|
+
and isinstance(event.error, dict)
|
|
1167
|
+
and next_obj.name in event.error
|
|
1168
|
+
):
|
|
1169
|
+
next_obj = self._steps[next_obj.on_error]
|
|
1071
1170
|
next = next_obj.next
|
|
1072
1171
|
if next and len(next) > 1:
|
|
1073
1172
|
raise GraphError(
|
|
@@ -1103,6 +1202,33 @@ class FlowStep(BaseStep):
|
|
|
1103
1202
|
**kw,
|
|
1104
1203
|
)
|
|
1105
1204
|
|
|
1205
|
+
def _insert_all_error_handlers(self):
|
|
1206
|
+
"""
|
|
1207
|
+
insert all error steps to the graph
|
|
1208
|
+
run after deployment
|
|
1209
|
+
"""
|
|
1210
|
+
for name, step in self._steps.items():
|
|
1211
|
+
if step.kind == "error_step":
|
|
1212
|
+
self._insert_error_step(name, step)
|
|
1213
|
+
|
|
1214
|
+
def _insert_error_step(self, name, step):
|
|
1215
|
+
"""
|
|
1216
|
+
insert error step to the graph
|
|
1217
|
+
run after deployment
|
|
1218
|
+
"""
|
|
1219
|
+
if not step.before and not any(
|
|
1220
|
+
[step.name in other_step.after for other_step in self._steps.values()]
|
|
1221
|
+
):
|
|
1222
|
+
step.responder = True
|
|
1223
|
+
return
|
|
1224
|
+
|
|
1225
|
+
for step_name in step.before:
|
|
1226
|
+
if step_name not in self._steps.keys():
|
|
1227
|
+
raise MLRunInvalidArgumentError(
|
|
1228
|
+
f"cant set before, there is no step named {step_name}"
|
|
1229
|
+
)
|
|
1230
|
+
self[step_name].after_step(name)
|
|
1231
|
+
|
|
1106
1232
|
|
|
1107
1233
|
class RootFlowStep(FlowStep):
|
|
1108
1234
|
"""root flow step"""
|
|
@@ -1116,6 +1242,7 @@ classes_map = {
|
|
|
1116
1242
|
"router": RouterStep,
|
|
1117
1243
|
"flow": FlowStep,
|
|
1118
1244
|
"queue": QueueStep,
|
|
1245
|
+
"error_step": ErrorStep,
|
|
1119
1246
|
}
|
|
1120
1247
|
|
|
1121
1248
|
|
|
@@ -1355,7 +1482,7 @@ def _init_async_objects(context, steps):
|
|
|
1355
1482
|
endpoint, stream_path = parse_path(step.path)
|
|
1356
1483
|
stream_path = stream_path.strip("/")
|
|
1357
1484
|
step._async_object = storey.StreamTarget(
|
|
1358
|
-
storey.V3ioDriver(endpoint),
|
|
1485
|
+
storey.V3ioDriver(endpoint or config.v3io_api),
|
|
1359
1486
|
stream_path,
|
|
1360
1487
|
context=context,
|
|
1361
1488
|
**options,
|
mlrun/utils/version/version.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: mlrun
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.1rc5
|
|
4
4
|
Summary: Tracking and config of machine learning runs
|
|
5
5
|
Home-page: https://github.com/mlrun/mlrun
|
|
6
6
|
Author: Yaron Haviv
|
|
@@ -53,7 +53,7 @@ Requires-Dist: humanfriendly (~=8.2)
|
|
|
53
53
|
Requires-Dist: fastapi (~=0.92.0)
|
|
54
54
|
Requires-Dist: fsspec (~=2021.8.1)
|
|
55
55
|
Requires-Dist: v3iofs (~=0.1.15)
|
|
56
|
-
Requires-Dist: storey (~=1.3.
|
|
56
|
+
Requires-Dist: storey (~=1.3.18)
|
|
57
57
|
Requires-Dist: deepdiff (~=5.0)
|
|
58
58
|
Requires-Dist: pymysql (~=1.0)
|
|
59
59
|
Requires-Dist: inflection (~=0.5.0)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
mlrun/__init__.py,sha256=cCTbgyTFsXvEdaq1Cvwz8s8FE75YGIJKX58um-fnfFs,8727
|
|
2
2
|
mlrun/__main__.py,sha256=7rP5R0xv1YziN-yfFqy9IJM1Z16vehUNPVz_PUU0zqQ,47778
|
|
3
3
|
mlrun/builder.py,sha256=4PnePQzFy69RHgzFksdRNskExrjnmGCGPLXMHVPUdwM,24314
|
|
4
|
-
mlrun/config.py,sha256=
|
|
5
|
-
mlrun/errors.py,sha256=
|
|
4
|
+
mlrun/config.py,sha256=UbxmDWCDpIMZuPUANsmF0xl3_Ihey9s6K4gVn_SYfcM,49992
|
|
5
|
+
mlrun/errors.py,sha256=XEb1pxwy5Lzr9q0VT4z_SjP74jy37HFSmdd2hddWgvY,6780
|
|
6
6
|
mlrun/execution.py,sha256=jL7GuRPa4ZHxroW7kGLtBFeiOzDQoPv3bHZ2BGGSaUo,38928
|
|
7
7
|
mlrun/features.py,sha256=pDUvV6HlkxZnUwW3lg7oq3vBwdcJQBprvdyGPNv57X8,15624
|
|
8
8
|
mlrun/k8s_utils.py,sha256=5Ly-7Pgis6W1dHL1fOHSYkLcWEqZLdfGuDgDK-bsmIM,31384
|
|
@@ -33,7 +33,7 @@ mlrun/api/api/endpoints/files.py,sha256=w412iL7Al7VHi_jJUvThyraO5hyWLrXG85iw10PV
|
|
|
33
33
|
mlrun/api/api/endpoints/frontend_spec.py,sha256=nr4EC25MbXCIDCWQaLD93saVB8cZg3R2UOUePx8xQ7U,5690
|
|
34
34
|
mlrun/api/api/endpoints/functions.py,sha256=dOTy57CyTSqFI7mOB7utl8JUG7pR9idQn18h7P2NUkM,33894
|
|
35
35
|
mlrun/api/api/endpoints/grafana_proxy.py,sha256=NFgIpoxIXAmI_3bKXTNvC0Z0wEu7WcqsBH3zqfhbyZo,5798
|
|
36
|
-
mlrun/api/api/endpoints/healthz.py,sha256=
|
|
36
|
+
mlrun/api/api/endpoints/healthz.py,sha256=3UHtyOFBgUooSmpWGiErav3_yJh1ZrgGrtPEmBZGWrM,1335
|
|
37
37
|
mlrun/api/api/endpoints/logs.py,sha256=1a73ZwNNMDZaaYRqFbL3XZ6OrK3dKCpQI7HC-QJxI78,2429
|
|
38
38
|
mlrun/api/api/endpoints/marketplace.py,sha256=PXc5OftoSoILyHCgSgNdNBEh4JjR8PmcvTQ6uB3nYfo,8283
|
|
39
39
|
mlrun/api/api/endpoints/model_endpoints.py,sha256=vlKqhQUJZISBWujGT3BQLWQD0aVyihrMcl8Fb-W8PXo,15724
|
|
@@ -189,9 +189,9 @@ mlrun/datastore/inmem.py,sha256=o6Svv12k5PxJNT24nMgV9FBYEPCzD3OQzuuvU6OeCYY,2627
|
|
|
189
189
|
mlrun/datastore/redis.py,sha256=pywWgjGJ51pmvKuwX1MI3ILWqh6WtgDs9igOQAhmIhc,4873
|
|
190
190
|
mlrun/datastore/s3.py,sha256=fn1Yg5Rs33ugHlwTKvBfu_jMKqkSZWgHNw0ocQ5nO7A,7035
|
|
191
191
|
mlrun/datastore/sources.py,sha256=89ckC7p5wmLdKCtZjSdWog6On97k8-JfhsUPKnRsucE,34025
|
|
192
|
-
mlrun/datastore/spark_udf.py,sha256=
|
|
193
|
-
mlrun/datastore/store_resources.py,sha256=
|
|
194
|
-
mlrun/datastore/targets.py,sha256=
|
|
192
|
+
mlrun/datastore/spark_udf.py,sha256=LFICcRzj7Yx03ttgQZImodEXjOZVvkcQd0OKwHuMLCg,1402
|
|
193
|
+
mlrun/datastore/store_resources.py,sha256=u60_0LGXbagkG2UIm2o2pntWioF4kPu7FLMd0tlrR-8,6889
|
|
194
|
+
mlrun/datastore/targets.py,sha256=3pA6jyHPzEHwfoMEDK3SObDAnLakpZU2AcJ30URO0KQ,62054
|
|
195
195
|
mlrun/datastore/utils.py,sha256=WNKBhgG2w9xAviyieGCB6hTnESEYzCwzgjcjz6uaWC4,1660
|
|
196
196
|
mlrun/datastore/v3io.py,sha256=ArEYq78irv5bwlRwcLeVfFJvcwtXEamGsZ2I0sVt7Qg,8097
|
|
197
197
|
mlrun/datastore/wasbfs/__init__.py,sha256=4CK7vZeJmC4Ak9cJjG07cGnk7jlkBlpCxw-ANfbBmzk,1343
|
|
@@ -202,9 +202,9 @@ mlrun/db/filedb.py,sha256=c-mpjJL_hcx2paRPcb4XdoXGyX6Dlv17tMNdsjULVJY,28411
|
|
|
202
202
|
mlrun/db/httpdb.py,sha256=7pa5nwfwsptKakNBOFCWI7TQ-J_VoU3wv97KHzkC7b0,128262
|
|
203
203
|
mlrun/db/sqldb.py,sha256=CdiF5D2t3oQLtphKNUzBY4DJSY-ThGSxS5ks108uxIQ,24292
|
|
204
204
|
mlrun/feature_store/__init__.py,sha256=guoak0hQTMoE4YsWwyoyso0CYE9NSPoP0eUal4crfVA,1501
|
|
205
|
-
mlrun/feature_store/api.py,sha256=
|
|
205
|
+
mlrun/feature_store/api.py,sha256=2HGosxeChN_OZD04t3OX3x6pop1wPgJKcRze2mRgMRg,43335
|
|
206
206
|
mlrun/feature_store/common.py,sha256=bFpPyFgGFuh-SwTl5AMUGD1mJr3GhVsFcDu-yIP5HAc,12807
|
|
207
|
-
mlrun/feature_store/feature_set.py,sha256=
|
|
207
|
+
mlrun/feature_store/feature_set.py,sha256=SE6qCVpNCn2aImrVXRWLaE3SmD17iF49SOHj9uzltt4,47059
|
|
208
208
|
mlrun/feature_store/feature_vector.py,sha256=hLOyejUK-itqZRzbqOQEQcijJHsJlypuHD7ZWQ6B5aE,21937
|
|
209
209
|
mlrun/feature_store/ingestion.py,sha256=7qcBfNkDZsD4IXRdRN4OCSPIlpQDVo3WaO8pnAAYY6Q,11813
|
|
210
210
|
mlrun/feature_store/steps.py,sha256=sqwY_IsUUA0ATNQryExjjzRwqgRKN4Ez66OktXVSoFY,23868
|
|
@@ -320,7 +320,7 @@ mlrun/model_monitoring/stores/models/base.py,sha256=Az7Q2JZKCTqZJ2hqYaOLr2owVMag
|
|
|
320
320
|
mlrun/model_monitoring/stores/models/mysql.py,sha256=o8vaYdE1Cu2Rsd7AM6-xMHIr-qFEQ_LOvqoZlgFbnFM,3744
|
|
321
321
|
mlrun/model_monitoring/stores/models/sqlite.py,sha256=kkQvEVzJcSZcf2PkA9-3tLpkJU5KZ-J-aht4uA2qU2c,3661
|
|
322
322
|
mlrun/platforms/__init__.py,sha256=NNh9MSxgjdi7QftO3DHp4axQnBeO5IjxD8oR13_jp3A,2400
|
|
323
|
-
mlrun/platforms/iguazio.py,sha256=
|
|
323
|
+
mlrun/platforms/iguazio.py,sha256=gPOXoIRGcUCNmyMOddeHQT9DXW3835kB9AduZm_S0E0,23113
|
|
324
324
|
mlrun/platforms/other.py,sha256=DwqbdbMNlkC2nEl1yJ0jF9WZJzjVu2IVPTC3bQ_W9Y0,11852
|
|
325
325
|
mlrun/projects/__init__.py,sha256=dsXSDyqBhLi8OOfpdjLJpYOwC2fy_Q_Ki95Bk6gVSwc,1153
|
|
326
326
|
mlrun/projects/operations.py,sha256=RZAyhsi3VuqvJjA3gwknuSpWhM1BfOFsZ-lGX9fIXCQ,17302
|
|
@@ -351,13 +351,13 @@ mlrun/runtimes/sparkjob/__init__.py,sha256=cDzK8jEJvNsSSujDmEt03h1Mnlj7MUvdCEUXD
|
|
|
351
351
|
mlrun/runtimes/sparkjob/abstract.py,sha256=o5ykIx4GkwLU2QoQNQS9oNm5qebB17sOVblbh0ZDjG8,35976
|
|
352
352
|
mlrun/runtimes/sparkjob/spark2job.py,sha256=StWv5hk99pHslkIpOzz5T-szCYN2kkC20ixEdlD3yIA,2033
|
|
353
353
|
mlrun/runtimes/sparkjob/spark3job.py,sha256=JzwinNIiPXBapSC-gAsbhf81oouxhx41U5oQwoNeYhM,28722
|
|
354
|
-
mlrun/serving/__init__.py,sha256=
|
|
354
|
+
mlrun/serving/__init__.py,sha256=FOIyvEwEOH6QuJovcDrrP5VSdLeKoqummSlfhNMvFXg,1078
|
|
355
355
|
mlrun/serving/merger.py,sha256=oRX6gJ3LUVeCJcTpJ1nwh4d1tk5FrSZshkXcH-y-dd4,6116
|
|
356
356
|
mlrun/serving/remote.py,sha256=HJS9bz5_mUuaKGsNbqRKpo-eVHKbc1fIEOEsECPmnko,18038
|
|
357
357
|
mlrun/serving/routers.py,sha256=avhQ5cgogYA_TP_6kgzC_U2VQW24-yWWUXJGP449-Qg,55209
|
|
358
358
|
mlrun/serving/server.py,sha256=ePfYiefH3HkNag5qHDzDyoowaNNMbjJ9YKpPS9wX9Xw,19005
|
|
359
359
|
mlrun/serving/serving_wrapper.py,sha256=ivoSlFNuC92plPHRfMzHr-hdN-jGqxneGiufJdgoxVc,836
|
|
360
|
-
mlrun/serving/states.py,sha256=
|
|
360
|
+
mlrun/serving/states.py,sha256=b5pNgAQWW5o60acjgp5fLI24FaFVUBfdYwO1HOCbJTw,53922
|
|
361
361
|
mlrun/serving/utils.py,sha256=1fLfn07R4-RlUcdUgYYwUTFF47NozQmV9BnZVbu4-lU,3468
|
|
362
362
|
mlrun/serving/v1_serving.py,sha256=UF6Ydgyo-DuHZ4DkrEdNMQl5oopVaZqm4EfBMBSvhDY,11814
|
|
363
363
|
mlrun/serving/v2_serving.py,sha256=uIKQnTITJozqk6WrmJhO0hKfjCl8FLYc_IpCEYt5elA,21441
|
|
@@ -383,11 +383,11 @@ mlrun/utils/notifications/notification/git.py,sha256=qI5Kd4U0PX8vfIVT_yjBIrToiJY
|
|
|
383
383
|
mlrun/utils/notifications/notification/ipython.py,sha256=jsM_tTV3ZzXv5NoQN2anfZJDTYsk95NDYVQnWFc9Zow,1951
|
|
384
384
|
mlrun/utils/notifications/notification/slack.py,sha256=wt6RlqJu9QC99Ki-3HNYmizYTyAnIVimFQ7bf-fYX2E,3650
|
|
385
385
|
mlrun/utils/version/__init__.py,sha256=hwfJgGWYGWFpepVGI1GbuCPqqEFGRbgguJg5sC0v4TU,614
|
|
386
|
-
mlrun/utils/version/version.json,sha256=
|
|
386
|
+
mlrun/utils/version/version.json,sha256=OHSLfR0bhakvVW7se9O4rFHj0j5Crr1BNTKoUB7gEl8,88
|
|
387
387
|
mlrun/utils/version/version.py,sha256=O4Q4kwtKlI73oK7oBPuz4SVkUI8BC11E9DJIKHT91kU,1970
|
|
388
|
-
mlrun-1.3.
|
|
389
|
-
mlrun-1.3.
|
|
390
|
-
mlrun-1.3.
|
|
391
|
-
mlrun-1.3.
|
|
392
|
-
mlrun-1.3.
|
|
393
|
-
mlrun-1.3.
|
|
388
|
+
mlrun-1.3.1rc5.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
389
|
+
mlrun-1.3.1rc5.dist-info/METADATA,sha256=gT36rvjdaIDRiVCXykY5DEACEaeNxECuyqjoFBuOBwo,16975
|
|
390
|
+
mlrun-1.3.1rc5.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
|
|
391
|
+
mlrun-1.3.1rc5.dist-info/entry_points.txt,sha256=ZbXmb36B9JmK7EaleP8MIAbZSOQXQV0iwKR6si0HUWk,47
|
|
392
|
+
mlrun-1.3.1rc5.dist-info/top_level.txt,sha256=NObLzw3maSF9wVrgSeYBv-fgnHkAJ1kEkh12DLdd5KM,6
|
|
393
|
+
mlrun-1.3.1rc5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|