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.

Files changed (93) hide show
  1. metaflow/__init__.py +7 -1
  2. metaflow/_vendor/imghdr/__init__.py +180 -0
  3. metaflow/cli.py +16 -1
  4. metaflow/cli_components/init_cmd.py +1 -0
  5. metaflow/cli_components/run_cmds.py +6 -2
  6. metaflow/client/core.py +22 -30
  7. metaflow/cmd/develop/stub_generator.py +19 -2
  8. metaflow/datastore/task_datastore.py +0 -1
  9. metaflow/debug.py +5 -0
  10. metaflow/decorators.py +230 -70
  11. metaflow/extension_support/__init__.py +15 -8
  12. metaflow/extension_support/_empty_file.py +2 -2
  13. metaflow/flowspec.py +80 -53
  14. metaflow/graph.py +24 -2
  15. metaflow/meta_files.py +13 -0
  16. metaflow/metadata_provider/metadata.py +7 -1
  17. metaflow/metaflow_config.py +5 -0
  18. metaflow/metaflow_environment.py +82 -25
  19. metaflow/metaflow_version.py +1 -1
  20. metaflow/package/__init__.py +664 -0
  21. metaflow/packaging_sys/__init__.py +870 -0
  22. metaflow/packaging_sys/backend.py +113 -0
  23. metaflow/packaging_sys/distribution_support.py +153 -0
  24. metaflow/packaging_sys/tar_backend.py +86 -0
  25. metaflow/packaging_sys/utils.py +91 -0
  26. metaflow/packaging_sys/v1.py +476 -0
  27. metaflow/plugins/__init__.py +3 -0
  28. metaflow/plugins/airflow/airflow.py +11 -1
  29. metaflow/plugins/airflow/airflow_cli.py +15 -4
  30. metaflow/plugins/argo/argo_workflows.py +346 -301
  31. metaflow/plugins/argo/argo_workflows_cli.py +16 -4
  32. metaflow/plugins/argo/exit_hooks.py +209 -0
  33. metaflow/plugins/aws/aws_utils.py +1 -1
  34. metaflow/plugins/aws/batch/batch.py +22 -3
  35. metaflow/plugins/aws/batch/batch_cli.py +3 -0
  36. metaflow/plugins/aws/batch/batch_decorator.py +13 -5
  37. metaflow/plugins/aws/step_functions/step_functions.py +10 -1
  38. metaflow/plugins/aws/step_functions/step_functions_cli.py +15 -4
  39. metaflow/plugins/cards/card_cli.py +20 -1
  40. metaflow/plugins/cards/card_creator.py +24 -1
  41. metaflow/plugins/cards/card_decorator.py +57 -6
  42. metaflow/plugins/cards/card_modules/convert_to_native_type.py +5 -2
  43. metaflow/plugins/cards/card_modules/test_cards.py +16 -0
  44. metaflow/plugins/cards/metadata.py +22 -0
  45. metaflow/plugins/exit_hook/__init__.py +0 -0
  46. metaflow/plugins/exit_hook/exit_hook_decorator.py +46 -0
  47. metaflow/plugins/exit_hook/exit_hook_script.py +52 -0
  48. metaflow/plugins/kubernetes/kubernetes.py +8 -1
  49. metaflow/plugins/kubernetes/kubernetes_cli.py +3 -0
  50. metaflow/plugins/kubernetes/kubernetes_decorator.py +13 -5
  51. metaflow/plugins/package_cli.py +25 -23
  52. metaflow/plugins/parallel_decorator.py +4 -2
  53. metaflow/plugins/pypi/bootstrap.py +8 -2
  54. metaflow/plugins/pypi/conda_decorator.py +39 -82
  55. metaflow/plugins/pypi/conda_environment.py +6 -2
  56. metaflow/plugins/pypi/pypi_decorator.py +4 -4
  57. metaflow/plugins/secrets/__init__.py +3 -0
  58. metaflow/plugins/secrets/secrets_decorator.py +9 -173
  59. metaflow/plugins/secrets/secrets_func.py +49 -0
  60. metaflow/plugins/secrets/secrets_spec.py +101 -0
  61. metaflow/plugins/secrets/utils.py +74 -0
  62. metaflow/plugins/test_unbounded_foreach_decorator.py +2 -2
  63. metaflow/plugins/timeout_decorator.py +0 -1
  64. metaflow/plugins/uv/bootstrap.py +11 -0
  65. metaflow/plugins/uv/uv_environment.py +4 -2
  66. metaflow/pylint_wrapper.py +5 -1
  67. metaflow/runner/click_api.py +5 -4
  68. metaflow/runner/metaflow_runner.py +16 -1
  69. metaflow/runner/subprocess_manager.py +14 -2
  70. metaflow/runtime.py +82 -11
  71. metaflow/task.py +91 -7
  72. metaflow/user_configs/config_options.py +13 -8
  73. metaflow/user_configs/config_parameters.py +0 -4
  74. metaflow/user_decorators/__init__.py +0 -0
  75. metaflow/user_decorators/common.py +144 -0
  76. metaflow/user_decorators/mutable_flow.py +499 -0
  77. metaflow/user_decorators/mutable_step.py +424 -0
  78. metaflow/user_decorators/user_flow_decorator.py +263 -0
  79. metaflow/user_decorators/user_step_decorator.py +712 -0
  80. metaflow/util.py +4 -1
  81. metaflow/version.py +1 -1
  82. {ob_metaflow-2.15.18.1.data → ob_metaflow-2.16.0.1.data}/data/share/metaflow/devtools/Tiltfile +27 -2
  83. {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/METADATA +2 -2
  84. {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/RECORD +90 -70
  85. metaflow/info_file.py +0 -25
  86. metaflow/package.py +0 -203
  87. metaflow/user_configs/config_decorators.py +0 -568
  88. {ob_metaflow-2.15.18.1.data → ob_metaflow-2.16.0.1.data}/data/share/metaflow/devtools/Makefile +0 -0
  89. {ob_metaflow-2.15.18.1.data → ob_metaflow-2.16.0.1.data}/data/share/metaflow/devtools/pick_services.sh +0 -0
  90. {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/WHEEL +0 -0
  91. {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/entry_points.txt +0 -0
  92. {ob_metaflow-2.15.18.1.dist-info → ob_metaflow-2.16.0.1.dist-info}/licenses/LICENSE +0 -0
  93. {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
- )