ob-metaflow 2.12.25.1__py2.py3-none-any.whl → 2.12.25.2__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/metaflow_config.py +7 -0
- metaflow/plugins/__init__.py +5 -0
- metaflow/plugins/argo/argo_workflows_deployer.py +100 -0
- metaflow/runner/deployer.py +40 -1
- metaflow/version.py +1 -1
- {ob_metaflow-2.12.25.1.dist-info → ob_metaflow-2.12.25.2.dist-info}/METADATA +2 -2
- {ob_metaflow-2.12.25.1.dist-info → ob_metaflow-2.12.25.2.dist-info}/RECORD +11 -11
- {ob_metaflow-2.12.25.1.dist-info → ob_metaflow-2.12.25.2.dist-info}/LICENSE +0 -0
- {ob_metaflow-2.12.25.1.dist-info → ob_metaflow-2.12.25.2.dist-info}/WHEEL +0 -0
- {ob_metaflow-2.12.25.1.dist-info → ob_metaflow-2.12.25.2.dist-info}/entry_points.txt +0 -0
- {ob_metaflow-2.12.25.1.dist-info → ob_metaflow-2.12.25.2.dist-info}/top_level.txt +0 -0
metaflow/metaflow_config.py
CHANGED
|
@@ -411,6 +411,13 @@ AIRFLOW_KUBERNETES_KUBECONFIG_CONTEXT = from_conf(
|
|
|
411
411
|
)
|
|
412
412
|
|
|
413
413
|
|
|
414
|
+
###
|
|
415
|
+
# From Deployment configuration
|
|
416
|
+
###
|
|
417
|
+
# From Deployment Configuration for DeployedFlow
|
|
418
|
+
FROM_DEPLOYMENT_IMPL = from_conf("FROM_DEPLOYMENT_IMPL", "argo-workflows")
|
|
419
|
+
|
|
420
|
+
|
|
414
421
|
###
|
|
415
422
|
# Conda configuration
|
|
416
423
|
###
|
metaflow/plugins/__init__.py
CHANGED
|
@@ -156,6 +156,11 @@ def get_plugin_cli():
|
|
|
156
156
|
return resolve_plugins("cli")
|
|
157
157
|
|
|
158
158
|
|
|
159
|
+
# just a normal dictionary, not a plugin since there is no class..
|
|
160
|
+
FROM_DEPLOYMENT_PROVIDERS = {
|
|
161
|
+
"argo-workflows": "metaflow.plugins.argo.argo_workflows_deployer",
|
|
162
|
+
}
|
|
163
|
+
|
|
159
164
|
STEP_DECORATORS = resolve_plugins("step_decorator")
|
|
160
165
|
FLOW_DECORATORS = resolve_plugins("flow_decorator")
|
|
161
166
|
ENVIRONMENTS = resolve_plugins("environment")
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import sys
|
|
2
|
+
import json
|
|
2
3
|
import tempfile
|
|
3
4
|
from typing import Optional, ClassVar
|
|
4
5
|
|
|
6
|
+
from metaflow.client.core import get_metadata
|
|
7
|
+
from metaflow.exception import MetaflowException
|
|
8
|
+
from metaflow.plugins.argo.argo_client import ArgoClient
|
|
9
|
+
from metaflow.metaflow_config import KUBERNETES_NAMESPACE
|
|
5
10
|
from metaflow.plugins.argo.argo_workflows import ArgoWorkflows
|
|
6
11
|
from metaflow.runner.deployer import (
|
|
12
|
+
Deployer,
|
|
7
13
|
DeployerImpl,
|
|
8
14
|
DeployedFlow,
|
|
9
15
|
TriggeredRun,
|
|
@@ -12,6 +18,100 @@ from metaflow.runner.deployer import (
|
|
|
12
18
|
)
|
|
13
19
|
|
|
14
20
|
|
|
21
|
+
def generate_fake_flow_file_contents(
|
|
22
|
+
flow_name: str, param_info: dict, project_name: Optional[str] = None
|
|
23
|
+
):
|
|
24
|
+
params_code = ""
|
|
25
|
+
for _, param_details in param_info.items():
|
|
26
|
+
param_name = param_details["name"]
|
|
27
|
+
param_type = param_details["type"]
|
|
28
|
+
param_help = param_details["description"]
|
|
29
|
+
param_required = param_details["is_required"]
|
|
30
|
+
|
|
31
|
+
if param_type == "JSON":
|
|
32
|
+
params_code += f" {param_name} = Parameter('{param_name}', type=JSONType, help='{param_help}', required={param_required})\n"
|
|
33
|
+
elif param_type == "FilePath":
|
|
34
|
+
is_text = param_details.get("is_text", True)
|
|
35
|
+
encoding = param_details.get("encoding", "utf-8")
|
|
36
|
+
params_code += f" {param_name} = IncludeFile('{param_name}', is_text={is_text}, encoding='{encoding}', help='{param_help}', required={param_required})\n"
|
|
37
|
+
else:
|
|
38
|
+
params_code += f" {param_name} = Parameter('{param_name}', type={param_type}, help='{param_help}', required={param_required})\n"
|
|
39
|
+
|
|
40
|
+
project_decorator = f"@project(name='{project_name}')\n" if project_name else ""
|
|
41
|
+
|
|
42
|
+
contents = f"""\
|
|
43
|
+
from metaflow import FlowSpec, Parameter, IncludeFile, JSONType, step, project
|
|
44
|
+
{project_decorator}class {flow_name}(FlowSpec):
|
|
45
|
+
{params_code}
|
|
46
|
+
@step
|
|
47
|
+
def start(self):
|
|
48
|
+
self.next(self.end)
|
|
49
|
+
@step
|
|
50
|
+
def end(self):
|
|
51
|
+
pass
|
|
52
|
+
if __name__ == '__main__':
|
|
53
|
+
{flow_name}()
|
|
54
|
+
"""
|
|
55
|
+
return contents
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def from_deployment(identifier: str, metadata: Optional[str] = None):
|
|
59
|
+
client = ArgoClient(namespace=KUBERNETES_NAMESPACE)
|
|
60
|
+
workflow_template = client.get_workflow_template(identifier)
|
|
61
|
+
|
|
62
|
+
if workflow_template is None:
|
|
63
|
+
raise MetaflowException("No deployed flow found for: %s" % identifier)
|
|
64
|
+
|
|
65
|
+
metadata_annotations = workflow_template.get("metadata", {}).get("annotations", {})
|
|
66
|
+
|
|
67
|
+
flow_name = metadata_annotations.get("metaflow/flow_name", "")
|
|
68
|
+
username = metadata_annotations.get("metaflow/owner", "")
|
|
69
|
+
parameters = json.loads(metadata_annotations.get("metaflow/parameters", {}))
|
|
70
|
+
|
|
71
|
+
# these two only exist if @project decorator is used..
|
|
72
|
+
branch_name = metadata_annotations.get("metaflow/branch_name", None)
|
|
73
|
+
project_name = metadata_annotations.get("metaflow/project_name", None)
|
|
74
|
+
|
|
75
|
+
project_kwargs = {}
|
|
76
|
+
if branch_name is not None:
|
|
77
|
+
if branch_name.startswith("prod."):
|
|
78
|
+
project_kwargs["production"] = True
|
|
79
|
+
project_kwargs["branch"] = branch_name[len("prod.") :]
|
|
80
|
+
elif branch_name.startswith("test."):
|
|
81
|
+
project_kwargs["branch"] = branch_name[len("test.") :]
|
|
82
|
+
elif branch_name == "prod":
|
|
83
|
+
project_kwargs["production"] = True
|
|
84
|
+
|
|
85
|
+
fake_flow_file_contents = generate_fake_flow_file_contents(
|
|
86
|
+
flow_name=flow_name, param_info=parameters, project_name=project_name
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as fake_flow_file:
|
|
90
|
+
with open(fake_flow_file.name, "w") as fp:
|
|
91
|
+
fp.write(fake_flow_file_contents)
|
|
92
|
+
|
|
93
|
+
if branch_name is not None:
|
|
94
|
+
d = Deployer(
|
|
95
|
+
fake_flow_file.name, env={"METAFLOW_USER": username}, **project_kwargs
|
|
96
|
+
).argo_workflows()
|
|
97
|
+
else:
|
|
98
|
+
d = Deployer(
|
|
99
|
+
fake_flow_file.name, env={"METAFLOW_USER": username}
|
|
100
|
+
).argo_workflows(name=identifier)
|
|
101
|
+
|
|
102
|
+
d.name = identifier
|
|
103
|
+
d.flow_name = flow_name
|
|
104
|
+
if metadata is None:
|
|
105
|
+
d.metadata = get_metadata()
|
|
106
|
+
else:
|
|
107
|
+
d.metadata = metadata
|
|
108
|
+
|
|
109
|
+
df = DeployedFlow(deployer=d)
|
|
110
|
+
d._enrich_deployed_flow(df)
|
|
111
|
+
|
|
112
|
+
return df
|
|
113
|
+
|
|
114
|
+
|
|
15
115
|
def suspend(instance: TriggeredRun, **kwargs):
|
|
16
116
|
"""
|
|
17
117
|
Suspend the running workflow.
|
metaflow/runner/deployer.py
CHANGED
|
@@ -214,7 +214,43 @@ class TriggeredRun(object):
|
|
|
214
214
|
return None
|
|
215
215
|
|
|
216
216
|
|
|
217
|
-
class
|
|
217
|
+
class LazyDeploymentMethod:
|
|
218
|
+
def __init__(self, module_path, func_name):
|
|
219
|
+
self.module_path = module_path
|
|
220
|
+
self.func_name = func_name
|
|
221
|
+
self.func = None
|
|
222
|
+
|
|
223
|
+
def __call__(self, *args, **kwargs):
|
|
224
|
+
if self.func is None:
|
|
225
|
+
module = importlib.import_module(self.module_path)
|
|
226
|
+
self.func = getattr(module, self.func_name)
|
|
227
|
+
return self.func(*args, **kwargs)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class DeploymentMethodsMeta(type):
|
|
231
|
+
from metaflow.plugins import FROM_DEPLOYMENT_PROVIDERS
|
|
232
|
+
from metaflow.metaflow_config import FROM_DEPLOYMENT_IMPL
|
|
233
|
+
|
|
234
|
+
def __new__(mcs, name, bases, dct):
|
|
235
|
+
cls = super().__new__(mcs, name, bases, dct)
|
|
236
|
+
|
|
237
|
+
def from_deployment(identifier, metadata=None, impl=None):
|
|
238
|
+
if impl is None:
|
|
239
|
+
impl = mcs.FROM_DEPLOYMENT_IMPL
|
|
240
|
+
|
|
241
|
+
if impl not in mcs.FROM_DEPLOYMENT_PROVIDERS:
|
|
242
|
+
raise ValueError("This method is not available for: %s" % impl)
|
|
243
|
+
|
|
244
|
+
module_path = mcs.FROM_DEPLOYMENT_PROVIDERS[impl]
|
|
245
|
+
lazy_method = LazyDeploymentMethod(module_path, "from_deployment")
|
|
246
|
+
return lazy_method(identifier=identifier, metadata=metadata)
|
|
247
|
+
|
|
248
|
+
setattr(cls, "from_deployment", staticmethod(from_deployment))
|
|
249
|
+
|
|
250
|
+
return cls
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class DeployedFlow(metaclass=DeploymentMethodsMeta):
|
|
218
254
|
"""
|
|
219
255
|
DeployedFlow class represents a flow that has been deployed.
|
|
220
256
|
|
|
@@ -226,6 +262,9 @@ class DeployedFlow(object):
|
|
|
226
262
|
|
|
227
263
|
def __init__(self, deployer: "DeployerImpl"):
|
|
228
264
|
self.deployer = deployer
|
|
265
|
+
self.name = self.deployer.name
|
|
266
|
+
self.flow_name = self.deployer.flow_name
|
|
267
|
+
self.metadata = self.deployer.metadata
|
|
229
268
|
|
|
230
269
|
def _enrich_object(self, env):
|
|
231
270
|
"""
|
metaflow/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
metaflow_version = "2.12.25.
|
|
1
|
+
metaflow_version = "2.12.25.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ob-metaflow
|
|
3
|
-
Version: 2.12.25.
|
|
3
|
+
Version: 2.12.25.2
|
|
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.25.
|
|
15
|
+
Requires-Dist: metaflow-stubs==2.12.25.2; extra == "stubs"
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
|
|
@@ -16,7 +16,7 @@ metaflow/includefile.py,sha256=yHczcZ_U0SrasxSNhZb3DIBzx8UZnrJCl3FzvpEQLOA,19753
|
|
|
16
16
|
metaflow/info_file.py,sha256=wtf2_F0M6dgiUu74AFImM8lfy5RrUw5Yj7Rgs2swKRY,686
|
|
17
17
|
metaflow/integrations.py,sha256=LlsaoePRg03DjENnmLxZDYto3NwWc9z_PtU6nJxLldg,1480
|
|
18
18
|
metaflow/lint.py,sha256=5rj1MlpluxyPTSINjtMoJ7viotyNzfjtBJSAihlAwMU,10870
|
|
19
|
-
metaflow/metaflow_config.py,sha256=
|
|
19
|
+
metaflow/metaflow_config.py,sha256=ZqNVr3MlauHxYZ5nJX2HRl8c-E3dfdaWcBN5zSC34Nw,23183
|
|
20
20
|
metaflow/metaflow_config_funcs.py,sha256=5GlvoafV6SxykwfL8D12WXSfwjBN_NsyuKE_Q3gjGVE,6738
|
|
21
21
|
metaflow/metaflow_current.py,sha256=pC-EMnAsnvBLvLd61W6MvfiCKcboryeui9f6r8z_sg8,7161
|
|
22
22
|
metaflow/metaflow_environment.py,sha256=rojFyGdyY56sN1HaEb1-0XX53Q3XPNnl0SaH-8xXZ8w,7987
|
|
@@ -36,7 +36,7 @@ metaflow/tuple_util.py,sha256=_G5YIEhuugwJ_f6rrZoelMFak3DqAR2tt_5CapS1XTY,830
|
|
|
36
36
|
metaflow/unbounded_foreach.py,sha256=p184WMbrMJ3xKYHwewj27ZhRUsSj_kw1jlye5gA9xJk,387
|
|
37
37
|
metaflow/util.py,sha256=olAvJK3y1it_k99MhLulTaAJo7OFVt5rnrD-ulIFLCU,13616
|
|
38
38
|
metaflow/vendor.py,sha256=FchtA9tH22JM-eEtJ2c9FpUdMn8sSb1VHuQS56EcdZk,5139
|
|
39
|
-
metaflow/version.py,sha256=
|
|
39
|
+
metaflow/version.py,sha256=CT8RBvPGLOTlpmf1k4yY6HvScS3c40tcvgeGWTZhKZw,31
|
|
40
40
|
metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
|
|
41
41
|
metaflow/_vendor/typing_extensions.py,sha256=0nUs5p1A_UrZigrAVBoOEM6TxU37zzPDUtiij1ZwpNc,110417
|
|
42
42
|
metaflow/_vendor/zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425
|
|
@@ -143,7 +143,7 @@ metaflow/mflog/mflog.py,sha256=VebXxqitOtNAs7VJixnNfziO_i_urG7bsJ5JiB5IXgY,4370
|
|
|
143
143
|
metaflow/mflog/save_logs.py,sha256=ZBAF4BMukw4FMAC7odpr9OI2BC_2petPtDX0ca6srC4,2352
|
|
144
144
|
metaflow/mflog/save_logs_periodically.py,sha256=2Uvk9hi-zlCqXxOQoXmmjH1SCugfw6eG6w70WgfI-ho,1256
|
|
145
145
|
metaflow/mflog/tee.py,sha256=wTER15qeHuiRpCkOqo-bd-r3Gj-EVlf3IvWRCA4beW4,887
|
|
146
|
-
metaflow/plugins/__init__.py,sha256=
|
|
146
|
+
metaflow/plugins/__init__.py,sha256=SCRd06keAc_tpUZt8AC38TUYx-5DJL06GLmUZMWf3vg,7398
|
|
147
147
|
metaflow/plugins/catch_decorator.py,sha256=UOM2taN_OL2RPpuJhwEOA9ZALm0-hHD0XS2Hn2GUev0,4061
|
|
148
148
|
metaflow/plugins/debug_logger.py,sha256=mcF5HYzJ0NQmqCMjyVUk3iAP-heroHRIiVWQC6Ha2-I,879
|
|
149
149
|
metaflow/plugins/debug_monitor.py,sha256=Md5X_sDOSssN9pt2D8YcaIjTK5JaQD55UAYTcF6xYF0,1099
|
|
@@ -178,7 +178,7 @@ metaflow/plugins/argo/argo_events.py,sha256=_C1KWztVqgi3zuH57pInaE9OzABc2NnncC-z
|
|
|
178
178
|
metaflow/plugins/argo/argo_workflows.py,sha256=AFP0ZmtsxoAAnReYEgfkGYOIWDdG6Ee-hu37CLMo4gY,175217
|
|
179
179
|
metaflow/plugins/argo/argo_workflows_cli.py,sha256=0qAGo0YlC1Y9-1zqYAzhVCpCcITotfOI421VOIRpseM,37232
|
|
180
180
|
metaflow/plugins/argo/argo_workflows_decorator.py,sha256=yprszMdbE3rBTcEA9VR0IEnPjTprUauZBc4SBb-Q7sA,7878
|
|
181
|
-
metaflow/plugins/argo/argo_workflows_deployer.py,sha256=
|
|
181
|
+
metaflow/plugins/argo/argo_workflows_deployer.py,sha256=_buPhlVPRtAuZRYuLRXmalvvBMeOAR0ZAQO9eLhsSsU,11969
|
|
182
182
|
metaflow/plugins/argo/capture_error.py,sha256=Ys9dscGrTpW-ZCirLBU0gD9qBM0BjxyxGlUMKcwewQc,1852
|
|
183
183
|
metaflow/plugins/argo/generate_input_paths.py,sha256=loYsI6RFX9LlFsHb7Fe-mzlTTtRdySoOu7sYDy-uXK0,881
|
|
184
184
|
metaflow/plugins/argo/jobset_input_paths.py,sha256=_JhZWngA6p9Q_O2fx3pdzKI0WE-HPRHz_zFvY2pHPTQ,525
|
|
@@ -303,7 +303,7 @@ metaflow/plugins/secrets/inline_secrets_provider.py,sha256=EChmoBGA1i7qM3jtYwPpL
|
|
|
303
303
|
metaflow/plugins/secrets/secrets_decorator.py,sha256=s-sFzPWOjahhpr5fMj-ZEaHkDYAPTO0isYXGvaUwlG8,11273
|
|
304
304
|
metaflow/runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
305
305
|
metaflow/runner/click_api.py,sha256=Qfg4BOz5K2LaXTYBsi1y4zTfNIsGGHBVF3UkorX_-o8,13878
|
|
306
|
-
metaflow/runner/deployer.py,sha256=
|
|
306
|
+
metaflow/runner/deployer.py,sha256=l-ofKKvMbFqhV9Md0-kMjt2KVVgmT3ohCbJYHrTIuJc,13689
|
|
307
307
|
metaflow/runner/metaflow_runner.py,sha256=I7Ao0GHHfP55nUCE8g6CpTPGjuWgXedSc9EZX-tIE2c,15001
|
|
308
308
|
metaflow/runner/nbdeploy.py,sha256=fP1s_5MeiDyT_igP82pB5EUqX9rOy2s06Hyc-OUbOvQ,4115
|
|
309
309
|
metaflow/runner/nbrun.py,sha256=lmvhzMCz7iC9LSPGRijifW1wMXxa4RW_jVmpdjQi22E,7261
|
|
@@ -345,9 +345,9 @@ metaflow/tutorials/07-worldview/README.md,sha256=5vQTrFqulJ7rWN6r20dhot9lI2sVj9W
|
|
|
345
345
|
metaflow/tutorials/07-worldview/worldview.ipynb,sha256=ztPZPI9BXxvW1QdS2Tfe7LBuVzvFvv0AToDnsDJhLdE,2237
|
|
346
346
|
metaflow/tutorials/08-autopilot/README.md,sha256=GnePFp_q76jPs991lMUqfIIh5zSorIeWznyiUxzeUVE,1039
|
|
347
347
|
metaflow/tutorials/08-autopilot/autopilot.ipynb,sha256=DQoJlILV7Mq9vfPBGW-QV_kNhWPjS5n6SJLqePjFYLY,3191
|
|
348
|
-
ob_metaflow-2.12.25.
|
|
349
|
-
ob_metaflow-2.12.25.
|
|
350
|
-
ob_metaflow-2.12.25.
|
|
351
|
-
ob_metaflow-2.12.25.
|
|
352
|
-
ob_metaflow-2.12.25.
|
|
353
|
-
ob_metaflow-2.12.25.
|
|
348
|
+
ob_metaflow-2.12.25.2.dist-info/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
|
|
349
|
+
ob_metaflow-2.12.25.2.dist-info/METADATA,sha256=6zJcRHpOc6ffW0m-B4wBnGrjQxxrtvv3qva_DTBSrjs,5143
|
|
350
|
+
ob_metaflow-2.12.25.2.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
|
|
351
|
+
ob_metaflow-2.12.25.2.dist-info/entry_points.txt,sha256=IKwTN1T3I5eJL3uo_vnkyxVffcgnRdFbKwlghZfn27k,57
|
|
352
|
+
ob_metaflow-2.12.25.2.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
|
|
353
|
+
ob_metaflow-2.12.25.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|