ob-metaflow 2.15.18.1__py2.py3-none-any.whl → 2.16.0.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 +7 -1
- metaflow/_vendor/imghdr/__init__.py +180 -0
- metaflow/cli.py +16 -1
- metaflow/cli_components/init_cmd.py +1 -0
- metaflow/cli_components/run_cmds.py +6 -2
- metaflow/client/core.py +22 -30
- metaflow/cmd/develop/stub_generator.py +19 -2
- metaflow/datastore/task_datastore.py +0 -1
- metaflow/debug.py +5 -0
- metaflow/decorators.py +230 -70
- metaflow/extension_support/__init__.py +15 -8
- metaflow/extension_support/_empty_file.py +2 -2
- metaflow/flowspec.py +80 -53
- metaflow/graph.py +24 -2
- metaflow/meta_files.py +13 -0
- metaflow/metadata_provider/metadata.py +7 -1
- metaflow/metaflow_config.py +5 -0
- metaflow/metaflow_environment.py +82 -25
- metaflow/metaflow_version.py +1 -1
- metaflow/package/__init__.py +664 -0
- metaflow/packaging_sys/__init__.py +870 -0
- metaflow/packaging_sys/backend.py +113 -0
- metaflow/packaging_sys/distribution_support.py +153 -0
- metaflow/packaging_sys/tar_backend.py +86 -0
- metaflow/packaging_sys/utils.py +91 -0
- metaflow/packaging_sys/v1.py +476 -0
- metaflow/plugins/__init__.py +3 -0
- metaflow/plugins/airflow/airflow.py +11 -1
- metaflow/plugins/airflow/airflow_cli.py +15 -4
- metaflow/plugins/argo/argo_workflows.py +346 -301
- metaflow/plugins/argo/argo_workflows_cli.py +16 -4
- metaflow/plugins/argo/exit_hooks.py +209 -0
- metaflow/plugins/aws/aws_utils.py +1 -1
- metaflow/plugins/aws/batch/batch.py +22 -3
- metaflow/plugins/aws/batch/batch_cli.py +3 -0
- metaflow/plugins/aws/batch/batch_decorator.py +13 -5
- metaflow/plugins/aws/step_functions/step_functions.py +10 -1
- metaflow/plugins/aws/step_functions/step_functions_cli.py +15 -4
- metaflow/plugins/cards/card_cli.py +20 -1
- metaflow/plugins/cards/card_creator.py +24 -1
- metaflow/plugins/cards/card_decorator.py +57 -6
- metaflow/plugins/cards/card_modules/convert_to_native_type.py +5 -2
- metaflow/plugins/cards/card_modules/test_cards.py +16 -0
- metaflow/plugins/cards/metadata.py +22 -0
- 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 +8 -1
- metaflow/plugins/kubernetes/kubernetes_cli.py +3 -0
- metaflow/plugins/kubernetes/kubernetes_decorator.py +13 -5
- metaflow/plugins/package_cli.py +25 -23
- metaflow/plugins/parallel_decorator.py +4 -2
- metaflow/plugins/pypi/bootstrap.py +8 -2
- metaflow/plugins/pypi/conda_decorator.py +39 -82
- metaflow/plugins/pypi/conda_environment.py +6 -2
- metaflow/plugins/pypi/pypi_decorator.py +4 -4
- metaflow/plugins/secrets/__init__.py +3 -0
- metaflow/plugins/secrets/secrets_decorator.py +9 -173
- 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 +11 -0
- metaflow/plugins/uv/uv_environment.py +4 -2
- metaflow/pylint_wrapper.py +5 -1
- metaflow/runner/click_api.py +5 -4
- metaflow/runner/metaflow_runner.py +16 -1
- metaflow/runner/subprocess_manager.py +14 -2
- metaflow/runtime.py +82 -11
- metaflow/task.py +91 -7
- metaflow/user_configs/config_options.py +13 -8
- metaflow/user_configs/config_parameters.py +0 -4
- metaflow/user_decorators/__init__.py +0 -0
- metaflow/user_decorators/common.py +144 -0
- metaflow/user_decorators/mutable_flow.py +499 -0
- metaflow/user_decorators/mutable_step.py +424 -0
- metaflow/user_decorators/user_flow_decorator.py +263 -0
- metaflow/user_decorators/user_step_decorator.py +712 -0
- metaflow/util.py +4 -1
- metaflow/version.py +1 -1
- {ob_metaflow-2.15.18.1.data → ob_metaflow-2.16.0.1.data}/data/share/metaflow/devtools/Tiltfile +27 -2
- {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/METADATA +2 -2
- {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/RECORD +90 -70
- metaflow/info_file.py +0 -25
- metaflow/package.py +0 -203
- metaflow/user_configs/config_decorators.py +0 -568
- {ob_metaflow-2.15.18.1.data → ob_metaflow-2.16.0.1.data}/data/share/metaflow/devtools/Makefile +0 -0
- {ob_metaflow-2.15.18.1.data → ob_metaflow-2.16.0.1.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
- {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/WHEEL +0 -0
- {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/entry_points.txt +0 -0
- {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/licenses/LICENSE +0 -0
- {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/top_level.txt +0 -0
metaflow/package.py
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
import importlib
|
|
2
|
-
import os
|
|
3
|
-
import sys
|
|
4
|
-
import tarfile
|
|
5
|
-
import time
|
|
6
|
-
import json
|
|
7
|
-
from io import BytesIO
|
|
8
|
-
|
|
9
|
-
from .user_configs.config_parameters import CONFIG_FILE, dump_config_values
|
|
10
|
-
from .extension_support import EXT_PKG, package_mfext_all
|
|
11
|
-
from .metaflow_config import DEFAULT_PACKAGE_SUFFIXES
|
|
12
|
-
from .exception import MetaflowException
|
|
13
|
-
from .util import to_unicode
|
|
14
|
-
from . import R
|
|
15
|
-
from .info_file import INFO_FILE
|
|
16
|
-
|
|
17
|
-
DEFAULT_SUFFIXES_LIST = DEFAULT_PACKAGE_SUFFIXES.split(",")
|
|
18
|
-
METAFLOW_SUFFIXES_LIST = [".py", ".html", ".css", ".js"]
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class NonUniqueFileNameToFilePathMappingException(MetaflowException):
|
|
22
|
-
headline = "Non Unique file path for a file name included in code package"
|
|
23
|
-
|
|
24
|
-
def __init__(self, filename, file_paths, lineno=None):
|
|
25
|
-
msg = (
|
|
26
|
-
"Filename %s included in the code package includes multiple different paths for the same name : %s.\n"
|
|
27
|
-
"The `filename` in the `add_to_package` decorator hook requires a unique `file_path` to `file_name` mapping"
|
|
28
|
-
% (filename, ", ".join(file_paths))
|
|
29
|
-
)
|
|
30
|
-
super().__init__(msg=msg, lineno=lineno)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
# this is os.walk(follow_symlinks=True) with cycle detection
|
|
34
|
-
def walk_without_cycles(top_root):
|
|
35
|
-
seen = set()
|
|
36
|
-
|
|
37
|
-
def _recurse(root):
|
|
38
|
-
for parent, dirs, files in os.walk(root):
|
|
39
|
-
for d in dirs:
|
|
40
|
-
path = os.path.join(parent, d)
|
|
41
|
-
if os.path.islink(path):
|
|
42
|
-
# Breaking loops: never follow the same symlink twice
|
|
43
|
-
#
|
|
44
|
-
# NOTE: this also means that links to sibling links are
|
|
45
|
-
# not followed. In this case:
|
|
46
|
-
#
|
|
47
|
-
# x -> y
|
|
48
|
-
# y -> oo
|
|
49
|
-
# oo/real_file
|
|
50
|
-
#
|
|
51
|
-
# real_file is only included twice, not three times
|
|
52
|
-
reallink = os.path.realpath(path)
|
|
53
|
-
if reallink not in seen:
|
|
54
|
-
seen.add(reallink)
|
|
55
|
-
for x in _recurse(path):
|
|
56
|
-
yield x
|
|
57
|
-
yield parent, files
|
|
58
|
-
|
|
59
|
-
for x in _recurse(top_root):
|
|
60
|
-
yield x
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class MetaflowPackage(object):
|
|
64
|
-
def __init__(self, flow, environment, echo, suffixes=DEFAULT_SUFFIXES_LIST):
|
|
65
|
-
self.suffixes = list(set().union(suffixes, DEFAULT_SUFFIXES_LIST))
|
|
66
|
-
self.environment = environment
|
|
67
|
-
self.metaflow_root = os.path.dirname(__file__)
|
|
68
|
-
|
|
69
|
-
self.flow_name = flow.name
|
|
70
|
-
self._flow = flow
|
|
71
|
-
self.create_time = time.time()
|
|
72
|
-
environment.init_environment(echo)
|
|
73
|
-
for step in flow:
|
|
74
|
-
for deco in step.decorators:
|
|
75
|
-
deco.package_init(flow, step.__name__, environment)
|
|
76
|
-
self.blob = self._make()
|
|
77
|
-
|
|
78
|
-
def _walk(self, root, exclude_hidden=True, suffixes=None):
|
|
79
|
-
if suffixes is None:
|
|
80
|
-
suffixes = []
|
|
81
|
-
root = to_unicode(root) # handle files/folder with non ascii chars
|
|
82
|
-
prefixlen = len("%s/" % os.path.dirname(root))
|
|
83
|
-
for (
|
|
84
|
-
path,
|
|
85
|
-
files,
|
|
86
|
-
) in walk_without_cycles(root):
|
|
87
|
-
if exclude_hidden and "/." in path:
|
|
88
|
-
continue
|
|
89
|
-
# path = path[2:] # strip the ./ prefix
|
|
90
|
-
# if path and (path[0] == '.' or './' in path):
|
|
91
|
-
# continue
|
|
92
|
-
for fname in files:
|
|
93
|
-
if (fname[0] == "." and fname in suffixes) or (
|
|
94
|
-
fname[0] != "."
|
|
95
|
-
and any(fname.endswith(suffix) for suffix in suffixes)
|
|
96
|
-
):
|
|
97
|
-
p = os.path.join(path, fname)
|
|
98
|
-
yield p, p[prefixlen:]
|
|
99
|
-
|
|
100
|
-
def path_tuples(self):
|
|
101
|
-
"""
|
|
102
|
-
Returns list of (path, arcname) to be added to the job package, where
|
|
103
|
-
`arcname` is the alternative name for the file in the package.
|
|
104
|
-
"""
|
|
105
|
-
# We want the following contents in the tarball
|
|
106
|
-
# Metaflow package itself
|
|
107
|
-
for path_tuple in self._walk(
|
|
108
|
-
self.metaflow_root, exclude_hidden=False, suffixes=METAFLOW_SUFFIXES_LIST
|
|
109
|
-
):
|
|
110
|
-
yield path_tuple
|
|
111
|
-
|
|
112
|
-
# Metaflow extensions; for now, we package *all* extensions but this may change
|
|
113
|
-
# at a later date; it is possible to call `package_mfext_package` instead of
|
|
114
|
-
# `package_mfext_all` but in that case, make sure to also add a
|
|
115
|
-
# metaflow_extensions/__init__.py file to properly "close" the metaflow_extensions
|
|
116
|
-
# package and prevent other extensions from being loaded that may be
|
|
117
|
-
# present in the rest of the system
|
|
118
|
-
for path_tuple in package_mfext_all():
|
|
119
|
-
yield path_tuple
|
|
120
|
-
|
|
121
|
-
# Any custom packages exposed via decorators
|
|
122
|
-
deco_module_paths = {}
|
|
123
|
-
for step in self._flow:
|
|
124
|
-
for deco in step.decorators:
|
|
125
|
-
for path_tuple in deco.add_to_package():
|
|
126
|
-
file_path, file_name = path_tuple
|
|
127
|
-
# Check if the path is not duplicated as
|
|
128
|
-
# many steps can have the same packages being imported
|
|
129
|
-
if file_name not in deco_module_paths:
|
|
130
|
-
deco_module_paths[file_name] = file_path
|
|
131
|
-
yield path_tuple
|
|
132
|
-
elif deco_module_paths[file_name] != file_path:
|
|
133
|
-
raise NonUniqueFileNameToFilePathMappingException(
|
|
134
|
-
file_name, [deco_module_paths[file_name], file_path]
|
|
135
|
-
)
|
|
136
|
-
|
|
137
|
-
# the package folders for environment
|
|
138
|
-
for path_tuple in self.environment.add_to_package():
|
|
139
|
-
yield path_tuple
|
|
140
|
-
if R.use_r():
|
|
141
|
-
# the R working directory
|
|
142
|
-
for path_tuple in self._walk(
|
|
143
|
-
"%s/" % R.working_dir(), suffixes=self.suffixes
|
|
144
|
-
):
|
|
145
|
-
yield path_tuple
|
|
146
|
-
# the R package
|
|
147
|
-
for path_tuple in R.package_paths():
|
|
148
|
-
yield path_tuple
|
|
149
|
-
else:
|
|
150
|
-
# the user's working directory
|
|
151
|
-
flowdir = os.path.dirname(os.path.abspath(sys.argv[0])) + "/"
|
|
152
|
-
for path_tuple in self._walk(flowdir, suffixes=self.suffixes):
|
|
153
|
-
yield path_tuple
|
|
154
|
-
|
|
155
|
-
def _add_configs(self, tar):
|
|
156
|
-
buf = BytesIO()
|
|
157
|
-
buf.write(json.dumps(dump_config_values(self._flow)).encode("utf-8"))
|
|
158
|
-
self._add_file(tar, os.path.basename(CONFIG_FILE), buf)
|
|
159
|
-
|
|
160
|
-
def _add_info(self, tar):
|
|
161
|
-
buf = BytesIO()
|
|
162
|
-
buf.write(
|
|
163
|
-
json.dumps(
|
|
164
|
-
self.environment.get_environment_info(include_ext_info=True)
|
|
165
|
-
).encode("utf-8")
|
|
166
|
-
)
|
|
167
|
-
self._add_file(tar, os.path.basename(INFO_FILE), buf)
|
|
168
|
-
|
|
169
|
-
@staticmethod
|
|
170
|
-
def _add_file(tar, filename, buf):
|
|
171
|
-
info = tarfile.TarInfo(filename)
|
|
172
|
-
buf.seek(0)
|
|
173
|
-
info.size = len(buf.getvalue())
|
|
174
|
-
# Setting this default to Dec 3, 2019
|
|
175
|
-
info.mtime = 1575360000
|
|
176
|
-
tar.addfile(info, buf)
|
|
177
|
-
|
|
178
|
-
def _make(self):
|
|
179
|
-
def no_mtime(tarinfo):
|
|
180
|
-
# a modification time change should not change the hash of
|
|
181
|
-
# the package. Only content modifications will.
|
|
182
|
-
# Setting this default to Dec 3, 2019
|
|
183
|
-
tarinfo.mtime = 1575360000
|
|
184
|
-
return tarinfo
|
|
185
|
-
|
|
186
|
-
buf = BytesIO()
|
|
187
|
-
with tarfile.open(
|
|
188
|
-
fileobj=buf, mode="w:gz", compresslevel=3, dereference=True
|
|
189
|
-
) as tar:
|
|
190
|
-
self._add_info(tar)
|
|
191
|
-
self._add_configs(tar)
|
|
192
|
-
for path, arcname in self.path_tuples():
|
|
193
|
-
tar.add(path, arcname=arcname, recursive=False, filter=no_mtime)
|
|
194
|
-
|
|
195
|
-
blob = bytearray(buf.getvalue())
|
|
196
|
-
blob[4:8] = [0] * 4 # Reset 4 bytes from offset 4 to account for ts
|
|
197
|
-
return blob
|
|
198
|
-
|
|
199
|
-
def __str__(self):
|
|
200
|
-
return "<code package for flow %s (created @ %s)>" % (
|
|
201
|
-
self.flow_name,
|
|
202
|
-
time.strftime("%a, %d %b %Y %H:%M:%S", self.create_time),
|
|
203
|
-
)
|