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.

@@ -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
  ###
@@ -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.
@@ -214,7 +214,43 @@ class TriggeredRun(object):
214
214
  return None
215
215
 
216
216
 
217
- class DeployedFlow(object):
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"
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.1
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.1; extra == "stubs"
15
+ Requires-Dist: metaflow-stubs==2.12.25.2; extra == "stubs"
16
16
 
17
17
  ![Metaflow_Logo_Horizontal_FullColor_Ribbon_Dark_RGB](https://user-images.githubusercontent.com/763451/89453116-96a57e00-d713-11ea-9fa6-82b29d4d6eff.png)
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=J11vmCjjffr2Koddo1OuymZFheW-0UaTD6rec2Hp0Gk,23017
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=pu5ibRx5X5exQtS3_CEK5XaDBp0Hh7eQMXagfHHVqoA,31
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=EJgoFpti77Niza4G19cgL2Dszk130e4sj06RZiCCJJQ,7227
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=wSSZtThn_VPvE_Wu6NB1L0Q86LmBJh9g009v_lpvBPM,8125
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=xNqxFIezWz3AcVqR4jeL-JnInGtefwEYMbXttxgB_I8,12276
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.1.dist-info/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
349
- ob_metaflow-2.12.25.1.dist-info/METADATA,sha256=YvcCRA52Tr57kElZwUHgPRc1XxTP63gKsjsIQ0ojl-M,5143
350
- ob_metaflow-2.12.25.1.dist-info/WHEEL,sha256=AHX6tWk3qWuce7vKLrj7lnulVHEdWoltgauo8bgCXgU,109
351
- ob_metaflow-2.12.25.1.dist-info/entry_points.txt,sha256=IKwTN1T3I5eJL3uo_vnkyxVffcgnRdFbKwlghZfn27k,57
352
- ob_metaflow-2.12.25.1.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
353
- ob_metaflow-2.12.25.1.dist-info/RECORD,,
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,,