ob-metaflow 2.12.26.1__py2.py3-none-any.whl → 2.12.30.1__py2.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 ob-metaflow might be problematic. Click here for more details.
- metaflow/__init__.py +2 -3
- metaflow/cli.py +31 -4
- metaflow/client/core.py +78 -40
- metaflow/clone_util.py +1 -1
- metaflow/cmd/develop/stub_generator.py +623 -233
- metaflow/datastore/task_datastore.py +1 -1
- metaflow/extension_support/plugins.py +1 -0
- metaflow/flowspec.py +2 -2
- metaflow/includefile.py +8 -14
- metaflow/{metadata → metadata_provider}/metadata.py +6 -0
- metaflow/metaflow_config.py +4 -7
- metaflow/metaflow_current.py +1 -1
- metaflow/parameters.py +3 -0
- metaflow/plugins/__init__.py +12 -8
- metaflow/plugins/airflow/airflow_cli.py +5 -0
- metaflow/plugins/airflow/airflow_decorator.py +1 -1
- metaflow/plugins/argo/argo_workflows_cli.py +3 -3
- metaflow/plugins/argo/argo_workflows_decorator.py +1 -1
- metaflow/plugins/argo/argo_workflows_deployer.py +77 -363
- metaflow/plugins/argo/argo_workflows_deployer_objects.py +381 -0
- metaflow/plugins/aws/batch/batch_cli.py +1 -1
- metaflow/plugins/aws/batch/batch_decorator.py +2 -2
- metaflow/plugins/aws/step_functions/step_functions_cli.py +9 -2
- metaflow/plugins/aws/step_functions/step_functions_decorator.py +1 -1
- metaflow/plugins/aws/step_functions/step_functions_deployer.py +65 -224
- metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +236 -0
- metaflow/plugins/azure/includefile_support.py +2 -0
- metaflow/plugins/cards/card_cli.py +3 -2
- metaflow/plugins/cards/card_modules/components.py +9 -9
- metaflow/plugins/cards/card_server.py +39 -14
- metaflow/plugins/datatools/local.py +2 -0
- metaflow/plugins/datatools/s3/s3.py +2 -0
- metaflow/plugins/env_escape/__init__.py +3 -3
- metaflow/plugins/gcp/includefile_support.py +3 -0
- metaflow/plugins/kubernetes/kubernetes_cli.py +1 -1
- metaflow/plugins/kubernetes/kubernetes_decorator.py +5 -4
- metaflow/plugins/kubernetes/kubernetes_jobsets.py +1 -4
- metaflow/plugins/{metadata → metadata_providers}/local.py +2 -2
- metaflow/plugins/{metadata → metadata_providers}/service.py +2 -2
- metaflow/plugins/parallel_decorator.py +1 -1
- metaflow/plugins/pypi/conda_decorator.py +1 -1
- metaflow/plugins/resources_decorator.py +2 -2
- metaflow/plugins/tag_cli.py +1 -4
- metaflow/plugins/test_unbounded_foreach_decorator.py +1 -1
- metaflow/runner/click_api.py +4 -0
- metaflow/runner/deployer.py +134 -303
- metaflow/runner/deployer_impl.py +167 -0
- metaflow/runner/metaflow_runner.py +14 -12
- metaflow/runner/nbdeploy.py +12 -13
- metaflow/runner/nbrun.py +3 -3
- metaflow/runner/utils.py +55 -8
- metaflow/runtime.py +1 -1
- metaflow/system/system_logger.py +1 -19
- metaflow/system/system_monitor.py +0 -24
- metaflow/task.py +32 -26
- metaflow/version.py +1 -1
- {ob_metaflow-2.12.26.1.dist-info → ob_metaflow-2.12.30.1.dist-info}/METADATA +2 -2
- {ob_metaflow-2.12.26.1.dist-info → ob_metaflow-2.12.30.1.dist-info}/RECORD +66 -63
- {ob_metaflow-2.12.26.1.dist-info → ob_metaflow-2.12.30.1.dist-info}/WHEEL +1 -1
- /metaflow/{metadata → metadata_provider}/__init__.py +0 -0
- /metaflow/{metadata → metadata_provider}/heartbeat.py +0 -0
- /metaflow/{metadata → metadata_provider}/util.py +0 -0
- /metaflow/plugins/{metadata → metadata_providers}/__init__.py +0 -0
- {ob_metaflow-2.12.26.1.dist-info → ob_metaflow-2.12.30.1.dist-info}/LICENSE +0 -0
- {ob_metaflow-2.12.26.1.dist-info → ob_metaflow-2.12.30.1.dist-info}/entry_points.txt +0 -0
- {ob_metaflow-2.12.26.1.dist-info → ob_metaflow-2.12.30.1.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@ import tempfile
|
|
|
6
6
|
|
|
7
7
|
from typing import Dict, Iterator, Optional, Tuple
|
|
8
8
|
|
|
9
|
-
from metaflow import Run
|
|
9
|
+
from metaflow import Run
|
|
10
10
|
|
|
11
11
|
from .utils import handle_timeout
|
|
12
12
|
from .subprocess_manager import CommandManager, SubprocessManager
|
|
@@ -67,10 +67,11 @@ class ExecutingRun(object):
|
|
|
67
67
|
|
|
68
68
|
Parameters
|
|
69
69
|
----------
|
|
70
|
-
timeout :
|
|
71
|
-
The maximum time to wait for the run to finish.
|
|
72
|
-
If the timeout is reached, the run is terminated
|
|
73
|
-
|
|
70
|
+
timeout : float, optional, default None
|
|
71
|
+
The maximum time, in seconds, to wait for the run to finish.
|
|
72
|
+
If the timeout is reached, the run is terminated. If not specified, wait
|
|
73
|
+
forever.
|
|
74
|
+
stream : str, optional, default None
|
|
74
75
|
If specified, the specified stream is printed to stdout. `stream` can
|
|
75
76
|
be one of `stdout` or `stderr`.
|
|
76
77
|
|
|
@@ -167,7 +168,7 @@ class ExecutingRun(object):
|
|
|
167
168
|
----------
|
|
168
169
|
stream : str
|
|
169
170
|
The stream to stream logs from. Can be one of `stdout` or `stderr`.
|
|
170
|
-
position :
|
|
171
|
+
position : int, optional, default None
|
|
171
172
|
The position in the log file to start streaming from. If None, it starts
|
|
172
173
|
from the beginning of the log file. This allows resuming streaming from
|
|
173
174
|
a previously known position
|
|
@@ -207,13 +208,13 @@ class Runner(object):
|
|
|
207
208
|
show_output : bool, default True
|
|
208
209
|
Show the 'stdout' and 'stderr' to the console by default,
|
|
209
210
|
Only applicable for synchronous 'run' and 'resume' functions.
|
|
210
|
-
profile :
|
|
211
|
+
profile : str, optional, default None
|
|
211
212
|
Metaflow profile to use to run this run. If not specified, the default
|
|
212
213
|
profile is used (or the one already set using `METAFLOW_PROFILE`)
|
|
213
|
-
env :
|
|
214
|
+
env : Dict[str, str], optional, default None
|
|
214
215
|
Additional environment variables to set for the Run. This overrides the
|
|
215
216
|
environment set for this process.
|
|
216
|
-
cwd :
|
|
217
|
+
cwd : str, optional, default None
|
|
217
218
|
The directory to run the subprocess in; if not specified, the current
|
|
218
219
|
directory is used.
|
|
219
220
|
file_read_timeout : int, default 3600
|
|
@@ -228,7 +229,7 @@ class Runner(object):
|
|
|
228
229
|
flow_file: str,
|
|
229
230
|
show_output: bool = True,
|
|
230
231
|
profile: Optional[str] = None,
|
|
231
|
-
env: Optional[Dict] = None,
|
|
232
|
+
env: Optional[Dict[str, str]] = None,
|
|
232
233
|
cwd: Optional[str] = None,
|
|
233
234
|
file_read_timeout: int = 3600,
|
|
234
235
|
**kwargs
|
|
@@ -275,9 +276,10 @@ class Runner(object):
|
|
|
275
276
|
|
|
276
277
|
# Set the correct metadata from the runner_attribute file corresponding to this run.
|
|
277
278
|
metadata_for_flow = content.get("metadata")
|
|
278
|
-
metadata(metadata_for_flow)
|
|
279
279
|
|
|
280
|
-
run_object = Run(
|
|
280
|
+
run_object = Run(
|
|
281
|
+
pathspec, _namespace_check=False, _current_metadata=metadata_for_flow
|
|
282
|
+
)
|
|
281
283
|
return ExecutingRun(self, command_obj, run_object)
|
|
282
284
|
|
|
283
285
|
def run(self, **kwargs) -> ExecutingRun:
|
metaflow/runner/nbdeploy.py
CHANGED
|
@@ -37,13 +37,13 @@ class NBDeployer(object):
|
|
|
37
37
|
Flow defined in the same cell
|
|
38
38
|
show_output : bool, default True
|
|
39
39
|
Show the 'stdout' and 'stderr' to the console by default,
|
|
40
|
-
profile :
|
|
40
|
+
profile : str, optional, default None
|
|
41
41
|
Metaflow profile to use to deploy this run. If not specified, the default
|
|
42
42
|
profile is used (or the one already set using `METAFLOW_PROFILE`)
|
|
43
|
-
env :
|
|
43
|
+
env : Dict[str, str], optional, default None
|
|
44
44
|
Additional environment variables to set. This overrides the
|
|
45
45
|
environment set for this process.
|
|
46
|
-
base_dir :
|
|
46
|
+
base_dir : str, optional, default None
|
|
47
47
|
The directory to run the subprocess in; if not specified, the current
|
|
48
48
|
working directory is used.
|
|
49
49
|
**kwargs : Any
|
|
@@ -66,10 +66,11 @@ class NBDeployer(object):
|
|
|
66
66
|
from IPython import get_ipython
|
|
67
67
|
|
|
68
68
|
ipython = get_ipython()
|
|
69
|
-
except ModuleNotFoundError:
|
|
69
|
+
except ModuleNotFoundError as e:
|
|
70
70
|
raise NBDeployerInitializationError(
|
|
71
|
-
"'NBDeployer' requires an interactive Python environment
|
|
72
|
-
|
|
71
|
+
"'NBDeployer' requires an interactive Python environment "
|
|
72
|
+
"(such as Jupyter)"
|
|
73
|
+
) from e
|
|
73
74
|
|
|
74
75
|
self.cell = get_current_cell(ipython)
|
|
75
76
|
self.flow = flow
|
|
@@ -116,13 +117,11 @@ class NBDeployer(object):
|
|
|
116
117
|
**kwargs,
|
|
117
118
|
)
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
NBDeployer, method_name, self.deployer.__make_function(provider_class)
|
|
125
|
-
)
|
|
120
|
+
def __getattr__(self, name):
|
|
121
|
+
"""
|
|
122
|
+
Forward all attribute access to the underlying `Deployer` instance.
|
|
123
|
+
"""
|
|
124
|
+
return getattr(self.deployer, name)
|
|
126
125
|
|
|
127
126
|
def cleanup(self):
|
|
128
127
|
"""
|
metaflow/runner/nbrun.py
CHANGED
|
@@ -34,13 +34,13 @@ class NBRunner(object):
|
|
|
34
34
|
show_output : bool, default True
|
|
35
35
|
Show the 'stdout' and 'stderr' to the console by default,
|
|
36
36
|
Only applicable for synchronous 'run' and 'resume' functions.
|
|
37
|
-
profile :
|
|
37
|
+
profile : str, optional, default None
|
|
38
38
|
Metaflow profile to use to run this run. If not specified, the default
|
|
39
39
|
profile is used (or the one already set using `METAFLOW_PROFILE`)
|
|
40
|
-
env :
|
|
40
|
+
env : Dict[str, str], optional, default None
|
|
41
41
|
Additional environment variables to set for the Run. This overrides the
|
|
42
42
|
environment set for this process.
|
|
43
|
-
base_dir :
|
|
43
|
+
base_dir : str, optional, default None
|
|
44
44
|
The directory to run the subprocess in; if not specified, the current
|
|
45
45
|
working directory is used.
|
|
46
46
|
file_read_timeout : int, default 3600
|
metaflow/runner/utils.py
CHANGED
|
@@ -4,10 +4,12 @@ import time
|
|
|
4
4
|
import asyncio
|
|
5
5
|
|
|
6
6
|
from subprocess import CalledProcessError
|
|
7
|
-
from typing import Dict, TYPE_CHECKING
|
|
7
|
+
from typing import Any, Dict, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
if TYPE_CHECKING:
|
|
10
|
-
|
|
10
|
+
import tempfile
|
|
11
|
+
import metaflow.runner.subprocess_manager
|
|
12
|
+
import metaflow.runner.click_api
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
def get_current_cell(ipython):
|
|
@@ -18,7 +20,8 @@ def get_current_cell(ipython):
|
|
|
18
20
|
|
|
19
21
|
def format_flowfile(cell):
|
|
20
22
|
"""
|
|
21
|
-
Formats the given cell content to create a valid Python script that can be
|
|
23
|
+
Formats the given cell content to create a valid Python script that can be
|
|
24
|
+
executed as a Metaflow flow.
|
|
22
25
|
"""
|
|
23
26
|
flowspec = [
|
|
24
27
|
x
|
|
@@ -36,7 +39,9 @@ def format_flowfile(cell):
|
|
|
36
39
|
return "\n".join(lines)
|
|
37
40
|
|
|
38
41
|
|
|
39
|
-
def check_process_status(
|
|
42
|
+
def check_process_status(
|
|
43
|
+
command_obj: "metaflow.runner.subprocess_manager.CommandManager",
|
|
44
|
+
):
|
|
40
45
|
if isinstance(command_obj.process, asyncio.subprocess.Process):
|
|
41
46
|
return command_obj.process.returncode is not None
|
|
42
47
|
else:
|
|
@@ -44,7 +49,9 @@ def check_process_status(command_obj: "CommandManager"):
|
|
|
44
49
|
|
|
45
50
|
|
|
46
51
|
def read_from_file_when_ready(
|
|
47
|
-
file_path: str,
|
|
52
|
+
file_path: str,
|
|
53
|
+
command_obj: "metaflow.runner.subprocess_manager.CommandManager",
|
|
54
|
+
timeout: float = 5,
|
|
48
55
|
):
|
|
49
56
|
start_time = time.time()
|
|
50
57
|
with open(file_path, "r", encoding="utf-8") as file_pointer:
|
|
@@ -70,7 +77,9 @@ def read_from_file_when_ready(
|
|
|
70
77
|
|
|
71
78
|
|
|
72
79
|
def handle_timeout(
|
|
73
|
-
tfp_runner_attribute
|
|
80
|
+
tfp_runner_attribute: "tempfile._TemporaryFileWrapper[str]",
|
|
81
|
+
command_obj: "metaflow.runner.subprocess_manager.CommandManager",
|
|
82
|
+
file_read_timeout: int,
|
|
74
83
|
):
|
|
75
84
|
"""
|
|
76
85
|
Handle the timeout for a running subprocess command that reads a file
|
|
@@ -102,8 +111,8 @@ def handle_timeout(
|
|
|
102
111
|
)
|
|
103
112
|
return content
|
|
104
113
|
except (CalledProcessError, TimeoutError) as e:
|
|
105
|
-
stdout_log = open(command_obj.log_files["stdout"]).read()
|
|
106
|
-
stderr_log = open(command_obj.log_files["stderr"]).read()
|
|
114
|
+
stdout_log = open(command_obj.log_files["stdout"], encoding="utf-8").read()
|
|
115
|
+
stderr_log = open(command_obj.log_files["stderr"], encoding="utf-8").read()
|
|
107
116
|
command = " ".join(command_obj.command)
|
|
108
117
|
error_message = "Error executing: '%s':\n" % command
|
|
109
118
|
if stdout_log.strip():
|
|
@@ -111,3 +120,41 @@ def handle_timeout(
|
|
|
111
120
|
if stderr_log.strip():
|
|
112
121
|
error_message += "\nStderr:\n%s\n" % stderr_log
|
|
113
122
|
raise RuntimeError(error_message) from e
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def get_lower_level_group(
|
|
126
|
+
api: "metaflow.runner.click_api.MetaflowAPI",
|
|
127
|
+
top_level_kwargs: Dict[str, Any],
|
|
128
|
+
sub_command: str,
|
|
129
|
+
sub_command_kwargs: Dict[str, Any],
|
|
130
|
+
) -> "metaflow.runner.click_api.MetaflowAPI":
|
|
131
|
+
"""
|
|
132
|
+
Retrieve a lower-level group from the API based on the type and provided arguments.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
api : MetaflowAPI
|
|
137
|
+
Metaflow API instance.
|
|
138
|
+
top_level_kwargs : Dict[str, Any]
|
|
139
|
+
Top-level keyword arguments to pass to the API.
|
|
140
|
+
sub_command : str
|
|
141
|
+
Sub-command of API to get the API for
|
|
142
|
+
sub_command_kwargs : Dict[str, Any]
|
|
143
|
+
Sub-command arguments
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
MetaflowAPI
|
|
148
|
+
The lower-level group object retrieved from the API.
|
|
149
|
+
|
|
150
|
+
Raises
|
|
151
|
+
------
|
|
152
|
+
ValueError
|
|
153
|
+
If the `_type` is None.
|
|
154
|
+
"""
|
|
155
|
+
sub_command_obj = getattr(api(**top_level_kwargs), sub_command)
|
|
156
|
+
|
|
157
|
+
if sub_command_obj is None:
|
|
158
|
+
raise ValueError(f"Sub-command '{sub_command}' not found in API '{api.name}'")
|
|
159
|
+
|
|
160
|
+
return sub_command_obj(**sub_command_kwargs)
|
metaflow/runtime.py
CHANGED
|
@@ -20,7 +20,7 @@ from metaflow.datastore.exceptions import DataException
|
|
|
20
20
|
from contextlib import contextmanager
|
|
21
21
|
|
|
22
22
|
from . import get_namespace
|
|
23
|
-
from .
|
|
23
|
+
from .metadata_provider import MetaDatum
|
|
24
24
|
from .metaflow_config import MAX_ATTEMPTS, UI_URL
|
|
25
25
|
from .exception import (
|
|
26
26
|
MetaflowException,
|
metaflow/system/system_logger.py
CHANGED
|
@@ -7,26 +7,11 @@ class SystemLogger(object):
|
|
|
7
7
|
def __init__(self):
|
|
8
8
|
self._logger = None
|
|
9
9
|
self._flow_name = None
|
|
10
|
-
self._context = {}
|
|
11
|
-
self._is_context_updated = False
|
|
12
10
|
|
|
13
11
|
def __del__(self):
|
|
14
12
|
if self._flow_name == "not_a_real_flow":
|
|
15
13
|
self.logger.terminate()
|
|
16
14
|
|
|
17
|
-
def update_context(self, context: Dict[str, Any]):
|
|
18
|
-
"""
|
|
19
|
-
Update the global context maintained by the system logger.
|
|
20
|
-
|
|
21
|
-
Parameters
|
|
22
|
-
----------
|
|
23
|
-
context : Dict[str, Any]
|
|
24
|
-
A dictionary containing the context to update.
|
|
25
|
-
|
|
26
|
-
"""
|
|
27
|
-
self._is_context_updated = True
|
|
28
|
-
self._context.update(context)
|
|
29
|
-
|
|
30
15
|
def init_system_logger(
|
|
31
16
|
self, flow_name: str, logger: "metaflow.event_logger.NullEventLogger"
|
|
32
17
|
):
|
|
@@ -71,7 +56,7 @@ class SystemLogger(object):
|
|
|
71
56
|
"false",
|
|
72
57
|
"",
|
|
73
58
|
):
|
|
74
|
-
print("system
|
|
59
|
+
print("system logger: %s" % msg, file=sys.stderr)
|
|
75
60
|
|
|
76
61
|
def log_event(
|
|
77
62
|
self, level: str, module: str, name: str, payload: Optional[Any] = None
|
|
@@ -96,8 +81,5 @@ class SystemLogger(object):
|
|
|
96
81
|
"module": module,
|
|
97
82
|
"name": name,
|
|
98
83
|
"payload": payload if payload is not None else {},
|
|
99
|
-
"context": self._context,
|
|
100
|
-
"is_context_updated": self._is_context_updated,
|
|
101
84
|
}
|
|
102
85
|
)
|
|
103
|
-
self._is_context_updated = False
|
|
@@ -9,35 +9,11 @@ class SystemMonitor(object):
|
|
|
9
9
|
def __init__(self):
|
|
10
10
|
self._monitor = None
|
|
11
11
|
self._flow_name = None
|
|
12
|
-
self._context = {}
|
|
13
12
|
|
|
14
13
|
def __del__(self):
|
|
15
14
|
if self._flow_name == "not_a_real_flow":
|
|
16
15
|
self.monitor.terminate()
|
|
17
16
|
|
|
18
|
-
def update_context(self, context: Dict[str, Any]):
|
|
19
|
-
"""
|
|
20
|
-
Update the global context maintained by the system monitor.
|
|
21
|
-
|
|
22
|
-
Parameters
|
|
23
|
-
----------
|
|
24
|
-
context : Dict[str, Any]
|
|
25
|
-
A dictionary containing the context to update.
|
|
26
|
-
|
|
27
|
-
"""
|
|
28
|
-
from metaflow.sidecar import Message, MessageTypes
|
|
29
|
-
|
|
30
|
-
self._context.update(context)
|
|
31
|
-
self.monitor.send(
|
|
32
|
-
Message(
|
|
33
|
-
MessageTypes.MUST_SEND,
|
|
34
|
-
{
|
|
35
|
-
"is_context_updated": True,
|
|
36
|
-
**self._context,
|
|
37
|
-
},
|
|
38
|
-
)
|
|
39
|
-
)
|
|
40
|
-
|
|
41
17
|
def init_system_monitor(
|
|
42
18
|
self, flow_name: str, monitor: "metaflow.monitor.NullMonitor"
|
|
43
19
|
):
|
metaflow/task.py
CHANGED
|
@@ -12,7 +12,7 @@ from metaflow.sidecar import Message, MessageTypes
|
|
|
12
12
|
from metaflow.datastore.exceptions import DataException
|
|
13
13
|
|
|
14
14
|
from .metaflow_config import MAX_ATTEMPTS
|
|
15
|
-
from .
|
|
15
|
+
from .metadata_provider import MetaDatum
|
|
16
16
|
from .mflog import TASK_LOG_SOURCE
|
|
17
17
|
from .datastore import Inputs, TaskDataStoreSet
|
|
18
18
|
from .exception import (
|
|
@@ -306,8 +306,6 @@ class MetaflowTask(object):
|
|
|
306
306
|
"origin_run_id": origin_run_id,
|
|
307
307
|
"origin_task_id": origin_task_id,
|
|
308
308
|
}
|
|
309
|
-
_system_logger.update_context(task_payload)
|
|
310
|
-
_system_monitor.update_context(task_payload)
|
|
311
309
|
|
|
312
310
|
msg = "Cloning task from {}/{}/{}/{} to {}/{}/{}/{}".format(
|
|
313
311
|
self.flow.name,
|
|
@@ -512,8 +510,7 @@ class MetaflowTask(object):
|
|
|
512
510
|
origin_run_id=origin_run_id,
|
|
513
511
|
namespace=resolve_identity(),
|
|
514
512
|
username=get_username(),
|
|
515
|
-
metadata_str=
|
|
516
|
-
% (self.metadata.__class__.TYPE, self.metadata.__class__.INFO),
|
|
513
|
+
metadata_str=self.metadata.metadata_str(),
|
|
517
514
|
is_running=True,
|
|
518
515
|
tags=self.metadata.sticky_tags,
|
|
519
516
|
)
|
|
@@ -546,9 +543,6 @@ class MetaflowTask(object):
|
|
|
546
543
|
"project_flow_name": current.get("project_flow_name"),
|
|
547
544
|
"trace_id": trace_id or None,
|
|
548
545
|
}
|
|
549
|
-
|
|
550
|
-
_system_logger.update_context(task_payload)
|
|
551
|
-
_system_monitor.update_context(task_payload)
|
|
552
546
|
start = time.time()
|
|
553
547
|
self.metadata.start_task_heartbeat(self.flow.name, run_id, step_name, task_id)
|
|
554
548
|
with self.monitor.measure("metaflow.task.duration"):
|
|
@@ -593,7 +587,8 @@ class MetaflowTask(object):
|
|
|
593
587
|
{
|
|
594
588
|
"parameter_names": self._init_parameters(
|
|
595
589
|
inputs[0], passdown=True
|
|
596
|
-
)
|
|
590
|
+
),
|
|
591
|
+
"graph_info": self.flow._graph_info,
|
|
597
592
|
}
|
|
598
593
|
)
|
|
599
594
|
else:
|
|
@@ -617,7 +612,8 @@ class MetaflowTask(object):
|
|
|
617
612
|
{
|
|
618
613
|
"parameter_names": self._init_parameters(
|
|
619
614
|
inputs[0], passdown=False
|
|
620
|
-
)
|
|
615
|
+
),
|
|
616
|
+
"graph_info": self.flow._graph_info,
|
|
621
617
|
}
|
|
622
618
|
)
|
|
623
619
|
|
|
@@ -709,24 +705,34 @@ class MetaflowTask(object):
|
|
|
709
705
|
name="end",
|
|
710
706
|
payload={**task_payload, "msg": "Task ended"},
|
|
711
707
|
)
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
708
|
+
try:
|
|
709
|
+
# persisting might fail due to unpicklable artifacts.
|
|
710
|
+
output.persist(self.flow)
|
|
711
|
+
except Exception as ex:
|
|
712
|
+
self.flow._task_ok = False
|
|
713
|
+
raise ex
|
|
714
|
+
finally:
|
|
715
|
+
# The attempt_ok metadata is used to determine task status so it is important
|
|
716
|
+
# we ensure that it is written even in case of preceding failures.
|
|
717
|
+
# f.ex. failing to serialize artifacts leads to a non-zero exit code for the process,
|
|
718
|
+
# even if user code finishes successfully. Flow execution will not continue due to the exit,
|
|
719
|
+
# so arguably we should mark the task as failed.
|
|
720
|
+
attempt_ok = str(bool(self.flow._task_ok))
|
|
721
|
+
self.metadata.register_metadata(
|
|
722
|
+
run_id,
|
|
723
|
+
step_name,
|
|
724
|
+
task_id,
|
|
725
|
+
[
|
|
726
|
+
MetaDatum(
|
|
727
|
+
field="attempt_ok",
|
|
728
|
+
value=attempt_ok,
|
|
729
|
+
type="internal_attempt_status",
|
|
730
|
+
tags=["attempt_id:{0}".format(retry_count)],
|
|
731
|
+
)
|
|
732
|
+
],
|
|
733
|
+
)
|
|
727
734
|
|
|
728
735
|
output.save_metadata({"task_end": {}})
|
|
729
|
-
output.persist(self.flow)
|
|
730
736
|
|
|
731
737
|
# this writes a success marker indicating that the
|
|
732
738
|
# "transaction" is done
|
metaflow/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
metaflow_version = "2.12.
|
|
1
|
+
metaflow_version = "2.12.30.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ob-metaflow
|
|
3
|
-
Version: 2.12.
|
|
3
|
+
Version: 2.12.30.1
|
|
4
4
|
Summary: Metaflow: More Data Science, Less Engineering
|
|
5
5
|
Author: Netflix, Outerbounds & the Metaflow Community
|
|
6
6
|
Author-email: help@outerbounds.co
|
|
@@ -12,7 +12,7 @@ Requires-Dist: boto3
|
|
|
12
12
|
Requires-Dist: pylint
|
|
13
13
|
Requires-Dist: kubernetes
|
|
14
14
|
Provides-Extra: stubs
|
|
15
|
-
Requires-Dist: metaflow-stubs==2.12.
|
|
15
|
+
Requires-Dist: metaflow-stubs==2.12.30.1; extra == "stubs"
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
|