ob-metaflow 2.15.13.1__py2.py3-none-any.whl → 2.19.7.1rc0__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.
- metaflow/__init__.py +10 -3
- metaflow/_vendor/imghdr/__init__.py +186 -0
- metaflow/_vendor/yaml/__init__.py +427 -0
- metaflow/_vendor/yaml/composer.py +139 -0
- metaflow/_vendor/yaml/constructor.py +748 -0
- metaflow/_vendor/yaml/cyaml.py +101 -0
- metaflow/_vendor/yaml/dumper.py +62 -0
- metaflow/_vendor/yaml/emitter.py +1137 -0
- metaflow/_vendor/yaml/error.py +75 -0
- metaflow/_vendor/yaml/events.py +86 -0
- metaflow/_vendor/yaml/loader.py +63 -0
- metaflow/_vendor/yaml/nodes.py +49 -0
- metaflow/_vendor/yaml/parser.py +589 -0
- metaflow/_vendor/yaml/reader.py +185 -0
- metaflow/_vendor/yaml/representer.py +389 -0
- metaflow/_vendor/yaml/resolver.py +227 -0
- metaflow/_vendor/yaml/scanner.py +1435 -0
- metaflow/_vendor/yaml/serializer.py +111 -0
- metaflow/_vendor/yaml/tokens.py +104 -0
- metaflow/cards.py +4 -0
- metaflow/cli.py +125 -21
- metaflow/cli_components/init_cmd.py +1 -0
- metaflow/cli_components/run_cmds.py +204 -40
- metaflow/cli_components/step_cmd.py +160 -4
- metaflow/client/__init__.py +1 -0
- metaflow/client/core.py +198 -130
- metaflow/client/filecache.py +59 -32
- metaflow/cmd/code/__init__.py +2 -1
- metaflow/cmd/develop/stub_generator.py +49 -18
- metaflow/cmd/develop/stubs.py +9 -27
- metaflow/cmd/make_wrapper.py +30 -0
- metaflow/datastore/__init__.py +1 -0
- metaflow/datastore/content_addressed_store.py +40 -9
- metaflow/datastore/datastore_set.py +10 -1
- metaflow/datastore/flow_datastore.py +124 -4
- metaflow/datastore/spin_datastore.py +91 -0
- metaflow/datastore/task_datastore.py +92 -6
- metaflow/debug.py +5 -0
- metaflow/decorators.py +331 -82
- metaflow/extension_support/__init__.py +414 -356
- metaflow/extension_support/_empty_file.py +2 -2
- metaflow/flowspec.py +322 -82
- metaflow/graph.py +178 -15
- metaflow/includefile.py +25 -3
- metaflow/lint.py +94 -3
- metaflow/meta_files.py +13 -0
- metaflow/metadata_provider/metadata.py +13 -2
- metaflow/metaflow_config.py +66 -4
- metaflow/metaflow_environment.py +91 -25
- metaflow/metaflow_profile.py +18 -0
- metaflow/metaflow_version.py +16 -1
- metaflow/package/__init__.py +673 -0
- metaflow/packaging_sys/__init__.py +880 -0
- metaflow/packaging_sys/backend.py +128 -0
- metaflow/packaging_sys/distribution_support.py +153 -0
- metaflow/packaging_sys/tar_backend.py +99 -0
- metaflow/packaging_sys/utils.py +54 -0
- metaflow/packaging_sys/v1.py +527 -0
- metaflow/parameters.py +6 -2
- metaflow/plugins/__init__.py +6 -0
- metaflow/plugins/airflow/airflow.py +11 -1
- metaflow/plugins/airflow/airflow_cli.py +16 -5
- metaflow/plugins/argo/argo_client.py +42 -20
- metaflow/plugins/argo/argo_events.py +6 -6
- metaflow/plugins/argo/argo_workflows.py +1023 -344
- metaflow/plugins/argo/argo_workflows_cli.py +396 -94
- metaflow/plugins/argo/argo_workflows_decorator.py +9 -0
- metaflow/plugins/argo/argo_workflows_deployer_objects.py +75 -49
- metaflow/plugins/argo/capture_error.py +5 -2
- metaflow/plugins/argo/conditional_input_paths.py +35 -0
- metaflow/plugins/argo/exit_hooks.py +209 -0
- metaflow/plugins/argo/param_val.py +19 -0
- metaflow/plugins/aws/aws_client.py +6 -0
- metaflow/plugins/aws/aws_utils.py +33 -1
- metaflow/plugins/aws/batch/batch.py +72 -5
- metaflow/plugins/aws/batch/batch_cli.py +24 -3
- metaflow/plugins/aws/batch/batch_decorator.py +57 -6
- metaflow/plugins/aws/step_functions/step_functions.py +28 -3
- metaflow/plugins/aws/step_functions/step_functions_cli.py +49 -4
- metaflow/plugins/aws/step_functions/step_functions_deployer.py +3 -0
- metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +30 -0
- metaflow/plugins/cards/card_cli.py +20 -1
- metaflow/plugins/cards/card_creator.py +24 -1
- metaflow/plugins/cards/card_datastore.py +21 -49
- metaflow/plugins/cards/card_decorator.py +58 -6
- metaflow/plugins/cards/card_modules/basic.py +38 -9
- metaflow/plugins/cards/card_modules/bundle.css +1 -1
- metaflow/plugins/cards/card_modules/chevron/renderer.py +1 -1
- metaflow/plugins/cards/card_modules/components.py +592 -3
- metaflow/plugins/cards/card_modules/convert_to_native_type.py +34 -5
- metaflow/plugins/cards/card_modules/json_viewer.py +232 -0
- metaflow/plugins/cards/card_modules/main.css +1 -0
- metaflow/plugins/cards/card_modules/main.js +56 -41
- metaflow/plugins/cards/card_modules/test_cards.py +22 -6
- metaflow/plugins/cards/component_serializer.py +1 -8
- metaflow/plugins/cards/metadata.py +22 -0
- metaflow/plugins/catch_decorator.py +9 -0
- metaflow/plugins/datastores/local_storage.py +12 -6
- metaflow/plugins/datastores/spin_storage.py +12 -0
- metaflow/plugins/datatools/s3/s3.py +49 -17
- metaflow/plugins/datatools/s3/s3op.py +113 -66
- metaflow/plugins/env_escape/client_modules.py +102 -72
- metaflow/plugins/events_decorator.py +127 -121
- metaflow/plugins/exit_hook/__init__.py +0 -0
- metaflow/plugins/exit_hook/exit_hook_decorator.py +46 -0
- metaflow/plugins/exit_hook/exit_hook_script.py +52 -0
- metaflow/plugins/kubernetes/kubernetes.py +12 -1
- metaflow/plugins/kubernetes/kubernetes_cli.py +11 -0
- metaflow/plugins/kubernetes/kubernetes_decorator.py +25 -6
- metaflow/plugins/kubernetes/kubernetes_job.py +12 -4
- metaflow/plugins/kubernetes/kubernetes_jobsets.py +31 -30
- metaflow/plugins/metadata_providers/local.py +76 -82
- metaflow/plugins/metadata_providers/service.py +13 -9
- metaflow/plugins/metadata_providers/spin.py +16 -0
- metaflow/plugins/package_cli.py +36 -24
- metaflow/plugins/parallel_decorator.py +11 -2
- metaflow/plugins/parsers.py +16 -0
- metaflow/plugins/pypi/bootstrap.py +7 -1
- metaflow/plugins/pypi/conda_decorator.py +41 -82
- metaflow/plugins/pypi/conda_environment.py +14 -6
- metaflow/plugins/pypi/micromamba.py +9 -1
- metaflow/plugins/pypi/pip.py +41 -5
- metaflow/plugins/pypi/pypi_decorator.py +4 -4
- metaflow/plugins/pypi/utils.py +22 -0
- metaflow/plugins/secrets/__init__.py +3 -0
- metaflow/plugins/secrets/secrets_decorator.py +14 -178
- metaflow/plugins/secrets/secrets_func.py +49 -0
- metaflow/plugins/secrets/secrets_spec.py +101 -0
- metaflow/plugins/secrets/utils.py +74 -0
- metaflow/plugins/test_unbounded_foreach_decorator.py +2 -2
- metaflow/plugins/timeout_decorator.py +0 -1
- metaflow/plugins/uv/bootstrap.py +29 -1
- metaflow/plugins/uv/uv_environment.py +5 -3
- metaflow/pylint_wrapper.py +5 -1
- metaflow/runner/click_api.py +79 -26
- metaflow/runner/deployer.py +208 -6
- metaflow/runner/deployer_impl.py +32 -12
- metaflow/runner/metaflow_runner.py +266 -33
- metaflow/runner/subprocess_manager.py +21 -1
- metaflow/runner/utils.py +27 -16
- metaflow/runtime.py +660 -66
- metaflow/task.py +255 -26
- metaflow/user_configs/config_options.py +33 -21
- metaflow/user_configs/config_parameters.py +220 -58
- metaflow/user_decorators/__init__.py +0 -0
- metaflow/user_decorators/common.py +144 -0
- metaflow/user_decorators/mutable_flow.py +512 -0
- metaflow/user_decorators/mutable_step.py +424 -0
- metaflow/user_decorators/user_flow_decorator.py +264 -0
- metaflow/user_decorators/user_step_decorator.py +749 -0
- metaflow/util.py +197 -7
- metaflow/vendor.py +23 -7
- metaflow/version.py +1 -1
- {ob_metaflow-2.15.13.1.data → ob_metaflow-2.19.7.1rc0.data}/data/share/metaflow/devtools/Makefile +13 -2
- {ob_metaflow-2.15.13.1.data → ob_metaflow-2.19.7.1rc0.data}/data/share/metaflow/devtools/Tiltfile +107 -7
- {ob_metaflow-2.15.13.1.data → ob_metaflow-2.19.7.1rc0.data}/data/share/metaflow/devtools/pick_services.sh +1 -0
- {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/METADATA +2 -3
- {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/RECORD +162 -121
- {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/WHEEL +1 -1
- metaflow/_vendor/v3_5/__init__.py +0 -1
- metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -644
- metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -152
- metaflow/_vendor/v3_5/zipp.py +0 -329
- metaflow/info_file.py +0 -25
- metaflow/package.py +0 -203
- metaflow/user_configs/config_decorators.py +0 -568
- {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/entry_points.txt +0 -0
- {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/licenses/LICENSE +0 -0
- {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
|
|
2
|
+
__all__ = ['Serializer', 'SerializerError']
|
|
3
|
+
|
|
4
|
+
from .error import YAMLError
|
|
5
|
+
from .events import *
|
|
6
|
+
from .nodes import *
|
|
7
|
+
|
|
8
|
+
class SerializerError(YAMLError):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
class Serializer:
|
|
12
|
+
|
|
13
|
+
ANCHOR_TEMPLATE = 'id%03d'
|
|
14
|
+
|
|
15
|
+
def __init__(self, encoding=None,
|
|
16
|
+
explicit_start=None, explicit_end=None, version=None, tags=None):
|
|
17
|
+
self.use_encoding = encoding
|
|
18
|
+
self.use_explicit_start = explicit_start
|
|
19
|
+
self.use_explicit_end = explicit_end
|
|
20
|
+
self.use_version = version
|
|
21
|
+
self.use_tags = tags
|
|
22
|
+
self.serialized_nodes = {}
|
|
23
|
+
self.anchors = {}
|
|
24
|
+
self.last_anchor_id = 0
|
|
25
|
+
self.closed = None
|
|
26
|
+
|
|
27
|
+
def open(self):
|
|
28
|
+
if self.closed is None:
|
|
29
|
+
self.emit(StreamStartEvent(encoding=self.use_encoding))
|
|
30
|
+
self.closed = False
|
|
31
|
+
elif self.closed:
|
|
32
|
+
raise SerializerError("serializer is closed")
|
|
33
|
+
else:
|
|
34
|
+
raise SerializerError("serializer is already opened")
|
|
35
|
+
|
|
36
|
+
def close(self):
|
|
37
|
+
if self.closed is None:
|
|
38
|
+
raise SerializerError("serializer is not opened")
|
|
39
|
+
elif not self.closed:
|
|
40
|
+
self.emit(StreamEndEvent())
|
|
41
|
+
self.closed = True
|
|
42
|
+
|
|
43
|
+
#def __del__(self):
|
|
44
|
+
# self.close()
|
|
45
|
+
|
|
46
|
+
def serialize(self, node):
|
|
47
|
+
if self.closed is None:
|
|
48
|
+
raise SerializerError("serializer is not opened")
|
|
49
|
+
elif self.closed:
|
|
50
|
+
raise SerializerError("serializer is closed")
|
|
51
|
+
self.emit(DocumentStartEvent(explicit=self.use_explicit_start,
|
|
52
|
+
version=self.use_version, tags=self.use_tags))
|
|
53
|
+
self.anchor_node(node)
|
|
54
|
+
self.serialize_node(node, None, None)
|
|
55
|
+
self.emit(DocumentEndEvent(explicit=self.use_explicit_end))
|
|
56
|
+
self.serialized_nodes = {}
|
|
57
|
+
self.anchors = {}
|
|
58
|
+
self.last_anchor_id = 0
|
|
59
|
+
|
|
60
|
+
def anchor_node(self, node):
|
|
61
|
+
if node in self.anchors:
|
|
62
|
+
if self.anchors[node] is None:
|
|
63
|
+
self.anchors[node] = self.generate_anchor(node)
|
|
64
|
+
else:
|
|
65
|
+
self.anchors[node] = None
|
|
66
|
+
if isinstance(node, SequenceNode):
|
|
67
|
+
for item in node.value:
|
|
68
|
+
self.anchor_node(item)
|
|
69
|
+
elif isinstance(node, MappingNode):
|
|
70
|
+
for key, value in node.value:
|
|
71
|
+
self.anchor_node(key)
|
|
72
|
+
self.anchor_node(value)
|
|
73
|
+
|
|
74
|
+
def generate_anchor(self, node):
|
|
75
|
+
self.last_anchor_id += 1
|
|
76
|
+
return self.ANCHOR_TEMPLATE % self.last_anchor_id
|
|
77
|
+
|
|
78
|
+
def serialize_node(self, node, parent, index):
|
|
79
|
+
alias = self.anchors[node]
|
|
80
|
+
if node in self.serialized_nodes:
|
|
81
|
+
self.emit(AliasEvent(alias))
|
|
82
|
+
else:
|
|
83
|
+
self.serialized_nodes[node] = True
|
|
84
|
+
self.descend_resolver(parent, index)
|
|
85
|
+
if isinstance(node, ScalarNode):
|
|
86
|
+
detected_tag = self.resolve(ScalarNode, node.value, (True, False))
|
|
87
|
+
default_tag = self.resolve(ScalarNode, node.value, (False, True))
|
|
88
|
+
implicit = (node.tag == detected_tag), (node.tag == default_tag)
|
|
89
|
+
self.emit(ScalarEvent(alias, node.tag, implicit, node.value,
|
|
90
|
+
style=node.style))
|
|
91
|
+
elif isinstance(node, SequenceNode):
|
|
92
|
+
implicit = (node.tag
|
|
93
|
+
== self.resolve(SequenceNode, node.value, True))
|
|
94
|
+
self.emit(SequenceStartEvent(alias, node.tag, implicit,
|
|
95
|
+
flow_style=node.flow_style))
|
|
96
|
+
index = 0
|
|
97
|
+
for item in node.value:
|
|
98
|
+
self.serialize_node(item, node, index)
|
|
99
|
+
index += 1
|
|
100
|
+
self.emit(SequenceEndEvent())
|
|
101
|
+
elif isinstance(node, MappingNode):
|
|
102
|
+
implicit = (node.tag
|
|
103
|
+
== self.resolve(MappingNode, node.value, True))
|
|
104
|
+
self.emit(MappingStartEvent(alias, node.tag, implicit,
|
|
105
|
+
flow_style=node.flow_style))
|
|
106
|
+
for key, value in node.value:
|
|
107
|
+
self.serialize_node(key, node, None)
|
|
108
|
+
self.serialize_node(value, node, key)
|
|
109
|
+
self.emit(MappingEndEvent())
|
|
110
|
+
self.ascend_resolver()
|
|
111
|
+
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
|
|
2
|
+
class Token(object):
|
|
3
|
+
def __init__(self, start_mark, end_mark):
|
|
4
|
+
self.start_mark = start_mark
|
|
5
|
+
self.end_mark = end_mark
|
|
6
|
+
def __repr__(self):
|
|
7
|
+
attributes = [key for key in self.__dict__
|
|
8
|
+
if not key.endswith('_mark')]
|
|
9
|
+
attributes.sort()
|
|
10
|
+
arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
|
|
11
|
+
for key in attributes])
|
|
12
|
+
return '%s(%s)' % (self.__class__.__name__, arguments)
|
|
13
|
+
|
|
14
|
+
#class BOMToken(Token):
|
|
15
|
+
# id = '<byte order mark>'
|
|
16
|
+
|
|
17
|
+
class DirectiveToken(Token):
|
|
18
|
+
id = '<directive>'
|
|
19
|
+
def __init__(self, name, value, start_mark, end_mark):
|
|
20
|
+
self.name = name
|
|
21
|
+
self.value = value
|
|
22
|
+
self.start_mark = start_mark
|
|
23
|
+
self.end_mark = end_mark
|
|
24
|
+
|
|
25
|
+
class DocumentStartToken(Token):
|
|
26
|
+
id = '<document start>'
|
|
27
|
+
|
|
28
|
+
class DocumentEndToken(Token):
|
|
29
|
+
id = '<document end>'
|
|
30
|
+
|
|
31
|
+
class StreamStartToken(Token):
|
|
32
|
+
id = '<stream start>'
|
|
33
|
+
def __init__(self, start_mark=None, end_mark=None,
|
|
34
|
+
encoding=None):
|
|
35
|
+
self.start_mark = start_mark
|
|
36
|
+
self.end_mark = end_mark
|
|
37
|
+
self.encoding = encoding
|
|
38
|
+
|
|
39
|
+
class StreamEndToken(Token):
|
|
40
|
+
id = '<stream end>'
|
|
41
|
+
|
|
42
|
+
class BlockSequenceStartToken(Token):
|
|
43
|
+
id = '<block sequence start>'
|
|
44
|
+
|
|
45
|
+
class BlockMappingStartToken(Token):
|
|
46
|
+
id = '<block mapping start>'
|
|
47
|
+
|
|
48
|
+
class BlockEndToken(Token):
|
|
49
|
+
id = '<block end>'
|
|
50
|
+
|
|
51
|
+
class FlowSequenceStartToken(Token):
|
|
52
|
+
id = '['
|
|
53
|
+
|
|
54
|
+
class FlowMappingStartToken(Token):
|
|
55
|
+
id = '{'
|
|
56
|
+
|
|
57
|
+
class FlowSequenceEndToken(Token):
|
|
58
|
+
id = ']'
|
|
59
|
+
|
|
60
|
+
class FlowMappingEndToken(Token):
|
|
61
|
+
id = '}'
|
|
62
|
+
|
|
63
|
+
class KeyToken(Token):
|
|
64
|
+
id = '?'
|
|
65
|
+
|
|
66
|
+
class ValueToken(Token):
|
|
67
|
+
id = ':'
|
|
68
|
+
|
|
69
|
+
class BlockEntryToken(Token):
|
|
70
|
+
id = '-'
|
|
71
|
+
|
|
72
|
+
class FlowEntryToken(Token):
|
|
73
|
+
id = ','
|
|
74
|
+
|
|
75
|
+
class AliasToken(Token):
|
|
76
|
+
id = '<alias>'
|
|
77
|
+
def __init__(self, value, start_mark, end_mark):
|
|
78
|
+
self.value = value
|
|
79
|
+
self.start_mark = start_mark
|
|
80
|
+
self.end_mark = end_mark
|
|
81
|
+
|
|
82
|
+
class AnchorToken(Token):
|
|
83
|
+
id = '<anchor>'
|
|
84
|
+
def __init__(self, value, start_mark, end_mark):
|
|
85
|
+
self.value = value
|
|
86
|
+
self.start_mark = start_mark
|
|
87
|
+
self.end_mark = end_mark
|
|
88
|
+
|
|
89
|
+
class TagToken(Token):
|
|
90
|
+
id = '<tag>'
|
|
91
|
+
def __init__(self, value, start_mark, end_mark):
|
|
92
|
+
self.value = value
|
|
93
|
+
self.start_mark = start_mark
|
|
94
|
+
self.end_mark = end_mark
|
|
95
|
+
|
|
96
|
+
class ScalarToken(Token):
|
|
97
|
+
id = '<scalar>'
|
|
98
|
+
def __init__(self, value, plain, start_mark, end_mark, style=None):
|
|
99
|
+
self.value = value
|
|
100
|
+
self.plain = plain
|
|
101
|
+
self.start_mark = start_mark
|
|
102
|
+
self.end_mark = end_mark
|
|
103
|
+
self.style = style
|
|
104
|
+
|
metaflow/cards.py
CHANGED
|
@@ -8,7 +8,11 @@ from metaflow.plugins.cards.card_modules.components import (
|
|
|
8
8
|
Markdown,
|
|
9
9
|
VegaChart,
|
|
10
10
|
ProgressBar,
|
|
11
|
+
ValueBox,
|
|
11
12
|
PythonCode,
|
|
13
|
+
EventsTimeline,
|
|
14
|
+
JSONViewer,
|
|
15
|
+
YAMLViewer,
|
|
12
16
|
)
|
|
13
17
|
from metaflow.plugins.cards.card_modules.basic import (
|
|
14
18
|
DefaultCard,
|
metaflow/cli.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import functools
|
|
2
3
|
import inspect
|
|
4
|
+
import os
|
|
3
5
|
import sys
|
|
4
6
|
import traceback
|
|
5
7
|
from datetime import datetime
|
|
@@ -13,7 +15,7 @@ from .cli_components.utils import LazyGroup, LazyPluginCommandCollection
|
|
|
13
15
|
from .datastore import FlowDataStore, TaskDataStoreSet
|
|
14
16
|
from .debug import debug
|
|
15
17
|
from .exception import CommandException, MetaflowException
|
|
16
|
-
from .flowspec import
|
|
18
|
+
from .flowspec import FlowStateItems
|
|
17
19
|
from .graph import FlowGraph
|
|
18
20
|
from .metaflow_config import (
|
|
19
21
|
DEFAULT_DATASTORE,
|
|
@@ -25,8 +27,10 @@ from .metaflow_config import (
|
|
|
25
27
|
DEFAULT_PACKAGE_SUFFIXES,
|
|
26
28
|
)
|
|
27
29
|
from .metaflow_current import current
|
|
30
|
+
from .metaflow_profile import from_start
|
|
28
31
|
from metaflow.system import _system_monitor, _system_logger
|
|
29
32
|
from .metaflow_environment import MetaflowEnvironment
|
|
33
|
+
from .packaging_sys import MetaflowCodeContent
|
|
30
34
|
from .plugins import (
|
|
31
35
|
DATASTORES,
|
|
32
36
|
ENVIRONMENTS,
|
|
@@ -36,7 +40,7 @@ from .plugins import (
|
|
|
36
40
|
)
|
|
37
41
|
from .pylint_wrapper import PyLint
|
|
38
42
|
from .R import metaflow_r_version, use_r
|
|
39
|
-
from .util import get_latest_run_id, resolve_identity
|
|
43
|
+
from .util import get_latest_run_id, resolve_identity, decompress_list
|
|
40
44
|
from .user_configs.config_options import LocalFileInput, config_options
|
|
41
45
|
from .user_configs.config_parameters import ConfigValue
|
|
42
46
|
|
|
@@ -54,6 +58,15 @@ def echo_dev_null(*args, **kwargs):
|
|
|
54
58
|
|
|
55
59
|
|
|
56
60
|
def echo_always(line, **kwargs):
|
|
61
|
+
if kwargs.pop("wrap", False):
|
|
62
|
+
import textwrap
|
|
63
|
+
|
|
64
|
+
indent_str = INDENT if kwargs.get("indent", None) else ""
|
|
65
|
+
effective_width = 80 - len(indent_str)
|
|
66
|
+
wrapped = textwrap.wrap(line, width=effective_width, break_long_words=False)
|
|
67
|
+
line = "\n".join(indent_str + l for l in wrapped)
|
|
68
|
+
kwargs["indent"] = False
|
|
69
|
+
|
|
57
70
|
kwargs["err"] = kwargs.get("err", True)
|
|
58
71
|
if kwargs.pop("indent", None):
|
|
59
72
|
line = "\n".join(INDENT + x for x in line.splitlines())
|
|
@@ -114,6 +127,8 @@ def logger(body="", system_msg=False, head="", bad=False, timestamp=True, nl=Tru
|
|
|
114
127
|
"step": "metaflow.cli_components.step_cmd.step",
|
|
115
128
|
"run": "metaflow.cli_components.run_cmds.run",
|
|
116
129
|
"resume": "metaflow.cli_components.run_cmds.resume",
|
|
130
|
+
"spin": "metaflow.cli_components.run_cmds.spin",
|
|
131
|
+
"spin-step": "metaflow.cli_components.step_cmd.spin_step",
|
|
117
132
|
},
|
|
118
133
|
)
|
|
119
134
|
def cli(ctx):
|
|
@@ -151,8 +166,13 @@ def check(obj, warnings=False):
|
|
|
151
166
|
def show(obj):
|
|
152
167
|
echo_always("\n%s" % obj.graph.doc)
|
|
153
168
|
for node_name in obj.graph.sorted_nodes:
|
|
169
|
+
echo_always("")
|
|
154
170
|
node = obj.graph[node_name]
|
|
155
|
-
|
|
171
|
+
for deco in node.decorators:
|
|
172
|
+
echo_always("@%s" % deco.name, err=False)
|
|
173
|
+
for deco in node.wrappers:
|
|
174
|
+
echo_always("@%s" % deco.decorator_name, err=False)
|
|
175
|
+
echo_always("Step *%s*" % node.name, err=False)
|
|
156
176
|
echo_always(node.doc if node.doc else "?", indent=True, err=False)
|
|
157
177
|
if node.type != "end":
|
|
158
178
|
echo_always(
|
|
@@ -242,6 +262,14 @@ def version(obj):
|
|
|
242
262
|
type=click.Choice(["local"] + [m.TYPE for m in ENVIRONMENTS]),
|
|
243
263
|
help="Execution environment type",
|
|
244
264
|
)
|
|
265
|
+
@click.option(
|
|
266
|
+
"--force-rebuild-environments/--no-force-rebuild-environments",
|
|
267
|
+
is_flag=True,
|
|
268
|
+
default=False,
|
|
269
|
+
hidden=True,
|
|
270
|
+
type=bool,
|
|
271
|
+
help="Explicitly rebuild the execution environments",
|
|
272
|
+
)
|
|
245
273
|
# See comment for --quiet
|
|
246
274
|
@click.option(
|
|
247
275
|
"--datastore",
|
|
@@ -294,12 +322,20 @@ def version(obj):
|
|
|
294
322
|
hidden=True,
|
|
295
323
|
is_eager=True,
|
|
296
324
|
)
|
|
325
|
+
@click.option(
|
|
326
|
+
"--mode",
|
|
327
|
+
type=click.Choice(["spin"]),
|
|
328
|
+
default=None,
|
|
329
|
+
help="Execution mode for metaflow CLI commands. Use 'spin' to enable "
|
|
330
|
+
"spin metadata and spin datastore for executions",
|
|
331
|
+
)
|
|
297
332
|
@click.pass_context
|
|
298
333
|
def start(
|
|
299
334
|
ctx,
|
|
300
335
|
quiet=False,
|
|
301
336
|
metadata=None,
|
|
302
337
|
environment=None,
|
|
338
|
+
force_rebuild_environments=False,
|
|
303
339
|
datastore=None,
|
|
304
340
|
datastore_root=None,
|
|
305
341
|
decospecs=None,
|
|
@@ -310,6 +346,7 @@ def start(
|
|
|
310
346
|
local_config_file=None,
|
|
311
347
|
config=None,
|
|
312
348
|
config_value=None,
|
|
349
|
+
mode=None,
|
|
313
350
|
**deco_options
|
|
314
351
|
):
|
|
315
352
|
if quiet:
|
|
@@ -322,10 +359,16 @@ def start(
|
|
|
322
359
|
if use_r():
|
|
323
360
|
version = metaflow_r_version()
|
|
324
361
|
|
|
362
|
+
from_start("MetaflowCLI: Starting")
|
|
325
363
|
echo("Metaflow %s" % version, fg="magenta", bold=True, nl=False)
|
|
326
364
|
echo(" executing *%s*" % ctx.obj.flow.name, fg="magenta", nl=False)
|
|
327
365
|
echo(" for *%s*" % resolve_identity(), fg="magenta")
|
|
328
366
|
|
|
367
|
+
# Check if we need to setup the distribution finder (if running )
|
|
368
|
+
dist_info = MetaflowCodeContent.get_distribution_finder()
|
|
369
|
+
if dist_info:
|
|
370
|
+
sys.meta_path.append(dist_info)
|
|
371
|
+
|
|
329
372
|
# Setup the context
|
|
330
373
|
cli_args._set_top_kwargs(ctx.params)
|
|
331
374
|
ctx.obj.echo = echo
|
|
@@ -336,6 +379,7 @@ def start(
|
|
|
336
379
|
ctx.obj.check = functools.partial(_check, echo)
|
|
337
380
|
ctx.obj.top_cli = cli
|
|
338
381
|
ctx.obj.package_suffixes = package_suffixes.split(",")
|
|
382
|
+
ctx.obj.spin_mode = mode == "spin"
|
|
339
383
|
|
|
340
384
|
ctx.obj.datastore_impl = [d for d in DATASTORES if d.TYPE == datastore][0]
|
|
341
385
|
|
|
@@ -414,8 +458,8 @@ def start(
|
|
|
414
458
|
# We can now set the the CONFIGS value in the flow properly. This will overwrite
|
|
415
459
|
# anything that may have been passed in by default and we will use exactly what
|
|
416
460
|
# the original flow had. Note that these are accessed through the parameter name
|
|
417
|
-
ctx.obj.flow._flow_state[
|
|
418
|
-
d = ctx.obj.flow._flow_state[
|
|
461
|
+
ctx.obj.flow._flow_state[FlowStateItems.CONFIGS].clear()
|
|
462
|
+
d = ctx.obj.flow._flow_state[FlowStateItems.CONFIGS]
|
|
419
463
|
for param_name, var_name in zip(config_param_names, config_var_names):
|
|
420
464
|
val = param_ds[var_name]
|
|
421
465
|
debug.userconf_exec("Loaded config %s as: %s" % (param_name, val))
|
|
@@ -426,6 +470,10 @@ def start(
|
|
|
426
470
|
# be raised. For resume, since we ignore those options, we ignore the error.
|
|
427
471
|
raise ctx.obj.delayed_config_exception
|
|
428
472
|
|
|
473
|
+
# Init all values in the flow mutators and then process them
|
|
474
|
+
for decorator in ctx.obj.flow._flow_state[FlowStateItems.FLOW_MUTATORS]:
|
|
475
|
+
decorator.external_init()
|
|
476
|
+
|
|
429
477
|
new_cls = ctx.obj.flow._process_config_decorators(config_options)
|
|
430
478
|
if new_cls:
|
|
431
479
|
ctx.obj.flow = new_cls(use_cli=False)
|
|
@@ -435,20 +483,15 @@ def start(
|
|
|
435
483
|
ctx.obj.environment = [
|
|
436
484
|
e for e in ENVIRONMENTS + [MetaflowEnvironment] if e.TYPE == environment
|
|
437
485
|
][0](ctx.obj.flow)
|
|
486
|
+
# set force rebuild flag for environments that support it.
|
|
487
|
+
ctx.obj.environment._force_rebuild = force_rebuild_environments
|
|
438
488
|
ctx.obj.environment.validate_environment(ctx.obj.logger, datastore)
|
|
439
|
-
|
|
440
489
|
ctx.obj.event_logger = LOGGING_SIDECARS[event_logger](
|
|
441
490
|
flow=ctx.obj.flow, env=ctx.obj.environment
|
|
442
491
|
)
|
|
443
|
-
ctx.obj.event_logger.start()
|
|
444
|
-
_system_logger.init_system_logger(ctx.obj.flow.name, ctx.obj.event_logger)
|
|
445
|
-
|
|
446
492
|
ctx.obj.monitor = MONITOR_SIDECARS[monitor](
|
|
447
493
|
flow=ctx.obj.flow, env=ctx.obj.environment
|
|
448
494
|
)
|
|
449
|
-
ctx.obj.monitor.start()
|
|
450
|
-
_system_monitor.init_system_monitor(ctx.obj.flow.name, ctx.obj.monitor)
|
|
451
|
-
|
|
452
495
|
ctx.obj.metadata = [m for m in METADATA_PROVIDERS if m.TYPE == metadata][0](
|
|
453
496
|
ctx.obj.environment, ctx.obj.flow, ctx.obj.event_logger, ctx.obj.monitor
|
|
454
497
|
)
|
|
@@ -462,6 +505,57 @@ def start(
|
|
|
462
505
|
)
|
|
463
506
|
|
|
464
507
|
ctx.obj.config_options = config_options
|
|
508
|
+
ctx.obj.is_spin = False
|
|
509
|
+
ctx.obj.skip_decorators = False
|
|
510
|
+
|
|
511
|
+
# Override values for spin steps, or if we are in spin mode
|
|
512
|
+
if (
|
|
513
|
+
hasattr(ctx, "saved_args")
|
|
514
|
+
and ctx.saved_args
|
|
515
|
+
and "spin" in ctx.saved_args[0]
|
|
516
|
+
or ctx.obj.spin_mode
|
|
517
|
+
):
|
|
518
|
+
# To minimize side effects for spin, we will only use the following:
|
|
519
|
+
# - local metadata provider,
|
|
520
|
+
# - local datastore,
|
|
521
|
+
# - local environment,
|
|
522
|
+
# - null event logger,
|
|
523
|
+
# - null monitor
|
|
524
|
+
ctx.obj.is_spin = True
|
|
525
|
+
if "--skip-decorators" in ctx.saved_args:
|
|
526
|
+
ctx.obj.skip_decorators = True
|
|
527
|
+
|
|
528
|
+
ctx.obj.event_logger = LOGGING_SIDECARS["nullSidecarLogger"](
|
|
529
|
+
flow=ctx.obj.flow, env=ctx.obj.environment
|
|
530
|
+
)
|
|
531
|
+
ctx.obj.monitor = MONITOR_SIDECARS["nullSidecarMonitor"](
|
|
532
|
+
flow=ctx.obj.flow, env=ctx.obj.environment
|
|
533
|
+
)
|
|
534
|
+
# Use spin metadata, spin datastore, and spin datastore root
|
|
535
|
+
ctx.obj.metadata = [m for m in METADATA_PROVIDERS if m.TYPE == "spin"][0](
|
|
536
|
+
ctx.obj.environment, ctx.obj.flow, ctx.obj.event_logger, ctx.obj.monitor
|
|
537
|
+
)
|
|
538
|
+
ctx.obj.datastore_impl = [d for d in DATASTORES if d.TYPE == "spin"][0]
|
|
539
|
+
datastore_root = ctx.obj.datastore_impl.get_datastore_root_from_config(
|
|
540
|
+
ctx.obj.echo, create_on_absent=True
|
|
541
|
+
)
|
|
542
|
+
ctx.obj.datastore_impl.datastore_root = datastore_root
|
|
543
|
+
|
|
544
|
+
ctx.obj.flow_datastore = FlowDataStore(
|
|
545
|
+
ctx.obj.flow.name,
|
|
546
|
+
ctx.obj.environment, # Same environment as run/resume
|
|
547
|
+
ctx.obj.metadata, # local metadata
|
|
548
|
+
ctx.obj.event_logger, # null event logger
|
|
549
|
+
ctx.obj.monitor, # null monitor
|
|
550
|
+
storage_impl=ctx.obj.datastore_impl,
|
|
551
|
+
)
|
|
552
|
+
|
|
553
|
+
# Start event logger and monitor
|
|
554
|
+
ctx.obj.event_logger.start()
|
|
555
|
+
_system_logger.init_system_logger(ctx.obj.flow.name, ctx.obj.event_logger)
|
|
556
|
+
|
|
557
|
+
ctx.obj.monitor.start()
|
|
558
|
+
_system_monitor.init_system_monitor(ctx.obj.flow.name, ctx.obj.monitor)
|
|
465
559
|
|
|
466
560
|
decorators._init(ctx.obj.flow)
|
|
467
561
|
|
|
@@ -476,9 +570,11 @@ def start(
|
|
|
476
570
|
ctx.obj.logger,
|
|
477
571
|
echo,
|
|
478
572
|
deco_options,
|
|
573
|
+
ctx.obj.is_spin,
|
|
574
|
+
ctx.obj.skip_decorators,
|
|
479
575
|
)
|
|
480
576
|
|
|
481
|
-
# In the case of run/resume, we will want to apply the TL decospecs
|
|
577
|
+
# In the case of run/resume/spin, we will want to apply the TL decospecs
|
|
482
578
|
# *after* the run decospecs so that they don't take precedence. In other
|
|
483
579
|
# words, for the same decorator, we want `myflow.py run --with foo` to
|
|
484
580
|
# take precedence over any other `foo` decospec
|
|
@@ -496,21 +592,20 @@ def start(
|
|
|
496
592
|
ctx.obj.echo,
|
|
497
593
|
ctx.obj.flow_datastore,
|
|
498
594
|
{
|
|
499
|
-
k: ConfigValue(v)
|
|
500
|
-
for k, v in ctx.obj.flow.__class__._flow_state
|
|
501
|
-
|
|
502
|
-
|
|
595
|
+
k: ConfigValue(v) if v is not None else None
|
|
596
|
+
for k, v in ctx.obj.flow.__class__._flow_state[
|
|
597
|
+
FlowStateItems.CONFIGS
|
|
598
|
+
].items()
|
|
503
599
|
},
|
|
504
600
|
)
|
|
505
601
|
|
|
506
602
|
if (
|
|
507
603
|
hasattr(ctx, "saved_args")
|
|
508
604
|
and ctx.saved_args
|
|
509
|
-
and ctx.saved_args[0] not in ("run", "resume")
|
|
605
|
+
and ctx.saved_args[0] not in ("run", "resume", "spin")
|
|
510
606
|
):
|
|
511
|
-
# run/resume are special cases because they can add more decorators with --with,
|
|
607
|
+
# run/resume/spin are special cases because they can add more decorators with --with,
|
|
512
608
|
# so they have to take care of themselves.
|
|
513
|
-
|
|
514
609
|
all_decospecs = ctx.obj.tl_decospecs + list(
|
|
515
610
|
ctx.obj.environment.decospecs() or []
|
|
516
611
|
)
|
|
@@ -520,11 +615,14 @@ def start(
|
|
|
520
615
|
# or a scheduler setting them up in their own way.
|
|
521
616
|
if ctx.saved_args[0] not in ("step", "init"):
|
|
522
617
|
all_decospecs += DEFAULT_DECOSPECS.split()
|
|
618
|
+
elif ctx.saved_args[0] == "spin-step":
|
|
619
|
+
# If we are in spin-args, we will not attach any decorators
|
|
620
|
+
all_decospecs = []
|
|
523
621
|
if all_decospecs:
|
|
524
622
|
decorators._attach_decorators(ctx.obj.flow, all_decospecs)
|
|
525
623
|
decorators._init(ctx.obj.flow)
|
|
526
624
|
# Regenerate graph if we attached more decorators
|
|
527
|
-
ctx.obj.flow.__class__.
|
|
625
|
+
ctx.obj.flow.__class__._init_graph()
|
|
528
626
|
ctx.obj.graph = ctx.obj.flow._graph
|
|
529
627
|
|
|
530
628
|
decorators._init_step_decorators(
|
|
@@ -533,8 +631,14 @@ def start(
|
|
|
533
631
|
ctx.obj.environment,
|
|
534
632
|
ctx.obj.flow_datastore,
|
|
535
633
|
ctx.obj.logger,
|
|
634
|
+
# The last two arguments are only used for spin steps
|
|
635
|
+
ctx.obj.is_spin,
|
|
636
|
+
ctx.obj.skip_decorators,
|
|
536
637
|
)
|
|
537
638
|
|
|
639
|
+
# Check the graph again (mutators may have changed it)
|
|
640
|
+
ctx.obj.graph = ctx.obj.flow._graph
|
|
641
|
+
|
|
538
642
|
# TODO (savin): Enable lazy instantiation of package
|
|
539
643
|
ctx.obj.package = None
|
|
540
644
|
|
|
@@ -46,6 +46,7 @@ def init(obj, run_id=None, task_id=None, tags=None, **kwargs):
|
|
|
46
46
|
obj.event_logger,
|
|
47
47
|
obj.monitor,
|
|
48
48
|
run_id=run_id,
|
|
49
|
+
skip_decorator_hooks=True,
|
|
49
50
|
)
|
|
50
51
|
obj.flow._set_constants(obj.graph, kwargs, obj.config_options)
|
|
51
52
|
runtime.persist_constants(task_id=task_id)
|