metaflow 2.12.28__py2.py3-none-any.whl → 2.12.30__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.
Files changed (59) hide show
  1. metaflow/__init__.py +2 -3
  2. metaflow/client/core.py +2 -2
  3. metaflow/clone_util.py +1 -1
  4. metaflow/cmd/develop/stub_generator.py +623 -233
  5. metaflow/datastore/task_datastore.py +1 -1
  6. metaflow/extension_support/plugins.py +1 -0
  7. metaflow/flowspec.py +2 -2
  8. metaflow/includefile.py +8 -14
  9. metaflow/metaflow_config.py +4 -0
  10. metaflow/metaflow_current.py +1 -1
  11. metaflow/parameters.py +3 -0
  12. metaflow/plugins/__init__.py +12 -3
  13. metaflow/plugins/airflow/airflow_cli.py +5 -0
  14. metaflow/plugins/airflow/airflow_decorator.py +1 -1
  15. metaflow/plugins/argo/argo_workflows_decorator.py +1 -1
  16. metaflow/plugins/argo/argo_workflows_deployer.py +77 -263
  17. metaflow/plugins/argo/argo_workflows_deployer_objects.py +381 -0
  18. metaflow/plugins/aws/batch/batch_cli.py +1 -1
  19. metaflow/plugins/aws/batch/batch_decorator.py +2 -2
  20. metaflow/plugins/aws/step_functions/step_functions_cli.py +7 -0
  21. metaflow/plugins/aws/step_functions/step_functions_decorator.py +1 -1
  22. metaflow/plugins/aws/step_functions/step_functions_deployer.py +65 -224
  23. metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +236 -0
  24. metaflow/plugins/azure/includefile_support.py +2 -0
  25. metaflow/plugins/cards/card_cli.py +3 -2
  26. metaflow/plugins/cards/card_modules/components.py +9 -9
  27. metaflow/plugins/cards/card_server.py +39 -14
  28. metaflow/plugins/datatools/local.py +2 -0
  29. metaflow/plugins/datatools/s3/s3.py +2 -0
  30. metaflow/plugins/env_escape/__init__.py +3 -3
  31. metaflow/plugins/gcp/includefile_support.py +3 -0
  32. metaflow/plugins/kubernetes/kubernetes_cli.py +1 -1
  33. metaflow/plugins/kubernetes/kubernetes_decorator.py +5 -4
  34. metaflow/plugins/{metadata → metadata_providers}/local.py +2 -2
  35. metaflow/plugins/{metadata → metadata_providers}/service.py +2 -2
  36. metaflow/plugins/parallel_decorator.py +1 -1
  37. metaflow/plugins/pypi/conda_decorator.py +1 -1
  38. metaflow/plugins/test_unbounded_foreach_decorator.py +1 -1
  39. metaflow/runner/click_api.py +4 -0
  40. metaflow/runner/deployer.py +139 -269
  41. metaflow/runner/deployer_impl.py +167 -0
  42. metaflow/runner/metaflow_runner.py +10 -9
  43. metaflow/runner/nbdeploy.py +12 -13
  44. metaflow/runner/nbrun.py +3 -3
  45. metaflow/runner/utils.py +55 -8
  46. metaflow/runtime.py +1 -1
  47. metaflow/task.py +1 -1
  48. metaflow/version.py +1 -1
  49. {metaflow-2.12.28.dist-info → metaflow-2.12.30.dist-info}/METADATA +2 -2
  50. {metaflow-2.12.28.dist-info → metaflow-2.12.30.dist-info}/RECORD +59 -56
  51. {metaflow-2.12.28.dist-info → metaflow-2.12.30.dist-info}/WHEEL +1 -1
  52. /metaflow/{metadata → metadata_provider}/__init__.py +0 -0
  53. /metaflow/{metadata → metadata_provider}/heartbeat.py +0 -0
  54. /metaflow/{metadata → metadata_provider}/metadata.py +0 -0
  55. /metaflow/{metadata → metadata_provider}/util.py +0 -0
  56. /metaflow/plugins/{metadata → metadata_providers}/__init__.py +0 -0
  57. {metaflow-2.12.28.dist-info → metaflow-2.12.30.dist-info}/LICENSE +0 -0
  58. {metaflow-2.12.28.dist-info → metaflow-2.12.30.dist-info}/entry_points.txt +0 -0
  59. {metaflow-2.12.28.dist-info → metaflow-2.12.30.dist-info}/top_level.txt +0 -0
@@ -81,6 +81,8 @@ class Local(object):
81
81
  In the future, we may want to allow it to be used in a way similar to the S3() client.
82
82
  """
83
83
 
84
+ TYPE = "local"
85
+
84
86
  @staticmethod
85
87
  def _makedirs(path):
86
88
  try:
@@ -504,6 +504,8 @@ class S3(object):
504
504
  If `run` is not specified, use this as the S3 prefix.
505
505
  """
506
506
 
507
+ TYPE = "s3"
508
+
507
509
  @classmethod
508
510
  def get_root_from_config(cls, echo, create_on_absent=True):
509
511
  return DATATOOLS_S3ROOT
@@ -124,9 +124,9 @@ def load():
124
124
  cur_path = os.path.dirname(__file__)
125
125
  sys.path = [p for p in old_paths if p != cur_path]
126
126
  # Handle special case where we launch a shell (including with a command)
127
- # and we are in the CWD (searched if '' is the first element of sys.path)
128
- if cur_path == os.getcwd() and sys.path[0] == '':
129
- sys.path = sys.path[1:]
127
+ # and we are in the CWD (searched if '' is present in sys.path)
128
+ if cur_path == os.getcwd() and '' in sys.path:
129
+ sys.path.remove("")
130
130
 
131
131
  # Remove the module (this file) to reload it properly. Do *NOT* update sys.modules but
132
132
  # modify directly since it may be referenced elsewhere
@@ -8,6 +8,9 @@ from metaflow.exception import MetaflowException, MetaflowInternalError
8
8
 
9
9
 
10
10
  class GS(object):
11
+
12
+ TYPE = "gs"
13
+
11
14
  @classmethod
12
15
  def get_root_from_config(cls, echo, create_on_absent=True):
13
16
  from metaflow.metaflow_config import DATATOOLS_GSROOT
@@ -9,7 +9,7 @@ import metaflow.tracing as tracing
9
9
  from metaflow import JSONTypeClass, util
10
10
  from metaflow._vendor import click
11
11
  from metaflow.exception import METAFLOW_EXIT_DISALLOW_RETRY, MetaflowException
12
- from metaflow.metadata.util import sync_local_metadata_from_datastore
12
+ from metaflow.metadata_provider.util import sync_local_metadata_from_datastore
13
13
  from metaflow.metaflow_config import DATASTORE_LOCAL_DIR, KUBERNETES_LABELS
14
14
  from metaflow.mflog import TASK_LOG_SOURCE
15
15
  from metaflow.unbounded_foreach import UBF_CONTROL, UBF_TASK
@@ -7,8 +7,8 @@ import time
7
7
  from metaflow import current
8
8
  from metaflow.decorators import StepDecorator
9
9
  from metaflow.exception import MetaflowException
10
- from metaflow.metadata import MetaDatum
11
- from metaflow.metadata.util import sync_local_metadata_to_datastore
10
+ from metaflow.metadata_provider import MetaDatum
11
+ from metaflow.metadata_provider.util import sync_local_metadata_to_datastore
12
12
  from metaflow.metaflow_config import (
13
13
  DATASTORE_LOCAL_DIR,
14
14
  KUBERNETES_CONTAINER_IMAGE,
@@ -73,8 +73,9 @@ class KubernetesDecorator(StepDecorator):
73
73
  in Metaflow configuration.
74
74
  node_selector: Union[Dict[str,str], str], optional, default None
75
75
  Kubernetes node selector(s) to apply to the pod running the task.
76
- Can be passed in as a comma separated string of values e.g. "kubernetes.io/os=linux,kubernetes.io/arch=amd64"
77
- or as a dictionary {"kubernetes.io/os": "linux", "kubernetes.io/arch": "amd64"}
76
+ Can be passed in as a comma separated string of values e.g.
77
+ 'kubernetes.io/os=linux,kubernetes.io/arch=amd64' or as a dictionary
78
+ {'kubernetes.io/os': 'linux', 'kubernetes.io/arch': 'amd64'}
78
79
  namespace : str, default METAFLOW_KUBERNETES_NAMESPACE
79
80
  Kubernetes namespace to use when launching pod in Kubernetes.
80
81
  gpu : int, optional, default None
@@ -8,9 +8,9 @@ import time
8
8
  from collections import namedtuple
9
9
 
10
10
  from metaflow.exception import MetaflowInternalError, MetaflowTaggingError
11
- from metaflow.metadata.metadata import ObjectOrder
11
+ from metaflow.metadata_provider.metadata import ObjectOrder
12
12
  from metaflow.metaflow_config import DATASTORE_LOCAL_DIR
13
- from metaflow.metadata import MetadataProvider
13
+ from metaflow.metadata_provider import MetadataProvider
14
14
  from metaflow.tagging_util import MAX_USER_TAG_SET_SIZE, validate_tags
15
15
 
16
16
 
@@ -14,8 +14,8 @@ from metaflow.metaflow_config import (
14
14
  SERVICE_HEADERS,
15
15
  SERVICE_URL,
16
16
  )
17
- from metaflow.metadata import MetadataProvider
18
- from metaflow.metadata.heartbeat import HB_URL_KEY
17
+ from metaflow.metadata_provider import MetadataProvider
18
+ from metaflow.metadata_provider.heartbeat import HB_URL_KEY
19
19
  from metaflow.sidecar import Message, MessageTypes, Sidecar
20
20
 
21
21
  from metaflow.util import version_parse
@@ -2,7 +2,7 @@ from collections import namedtuple
2
2
  from metaflow.decorators import StepDecorator
3
3
  from metaflow.unbounded_foreach import UBF_CONTROL, CONTROL_TASK_TAG
4
4
  from metaflow.exception import MetaflowException
5
- from metaflow.metadata import MetaDatum
5
+ from metaflow.metadata_provider import MetaDatum
6
6
  from metaflow.metaflow_current import current, Parallel
7
7
  import os
8
8
  import sys
@@ -8,7 +8,7 @@ import tempfile
8
8
 
9
9
  from metaflow.decorators import FlowDecorator, StepDecorator
10
10
  from metaflow.extension_support import EXT_PKG
11
- from metaflow.metadata import MetaDatum
11
+ from metaflow.metadata_provider import MetaDatum
12
12
  from metaflow.metaflow_environment import InvalidEnvironmentException
13
13
  from metaflow.util import get_metaflow_root
14
14
 
@@ -15,7 +15,7 @@ from metaflow.unbounded_foreach import (
15
15
  CONTROL_TASK_TAG,
16
16
  )
17
17
  from metaflow.util import to_unicode
18
- from metaflow.metadata import MetaDatum
18
+ from metaflow.metadata_provider import MetaDatum
19
19
 
20
20
 
21
21
  class InternalTestUnboundedForeachInput(UnboundedForeachInput):
@@ -193,6 +193,10 @@ class MetaflowAPI(object):
193
193
  def chain(self):
194
194
  return self._chain
195
195
 
196
+ @property
197
+ def name(self):
198
+ return self._API_NAME
199
+
196
200
  @classmethod
197
201
  def from_cli(cls, flow_file: str, cli_collection: Callable) -> Callable:
198
202
  flow_cls = extract_flow_class_from_file(flow_file)
@@ -1,53 +1,50 @@
1
- import os
2
- import sys
3
1
  import json
4
2
  import time
5
- import importlib
6
- import functools
7
- import tempfile
8
3
 
9
- from typing import Optional, Dict, ClassVar
4
+ from typing import ClassVar, Dict, Optional, TYPE_CHECKING
10
5
 
11
6
  from metaflow.exception import MetaflowNotFound
12
- from metaflow.runner.subprocess_manager import SubprocessManager
13
- from metaflow.runner.utils import handle_timeout
7
+ from metaflow.metaflow_config import DEFAULT_FROM_DEPLOYMENT_IMPL
14
8
 
9
+ if TYPE_CHECKING:
10
+ import metaflow
11
+ import metaflow.runner.deployer_impl
15
12
 
16
- def get_lower_level_group(
17
- api, top_level_kwargs: Dict, _type: Optional[str], deployer_kwargs: Dict
18
- ):
19
- """
20
- Retrieve a lower-level group from the API based on the type and provided arguments.
21
13
 
22
- Parameters
23
- ----------
24
- api : MetaflowAPI
25
- Metaflow API instance.
26
- top_level_kwargs : Dict
27
- Top-level keyword arguments to pass to the API.
28
- _type : str
29
- Type of the deployer implementation to target.
30
- deployer_kwargs : Dict
31
- Keyword arguments specific to the deployer.
32
-
33
- Returns
34
- -------
35
- Any
36
- The lower-level group object retrieved from the API.
37
-
38
- Raises
39
- ------
40
- ValueError
41
- If the `_type` is None.
42
- """
43
- if _type is None:
44
- raise ValueError(
45
- "DeployerImpl doesn't have a 'TYPE' to target. Please use a sub-class of DeployerImpl."
46
- )
47
- return getattr(api(**top_level_kwargs), _type)(**deployer_kwargs)
14
+ class DeployerMeta(type):
15
+ def __new__(mcs, name, bases, dct):
16
+ cls = super().__new__(mcs, name, bases, dct)
17
+
18
+ from metaflow.plugins import DEPLOYER_IMPL_PROVIDERS
19
+
20
+ def _injected_method(method_name, deployer_class):
21
+ def f(self, **deployer_kwargs):
22
+ return deployer_class(
23
+ deployer_kwargs=deployer_kwargs,
24
+ flow_file=self.flow_file,
25
+ show_output=self.show_output,
26
+ profile=self.profile,
27
+ env=self.env,
28
+ cwd=self.cwd,
29
+ file_read_timeout=self.file_read_timeout,
30
+ **self.top_level_kwargs,
31
+ )
32
+
33
+ f.__doc__ = provider_class.__doc__ or ""
34
+ f.__name__ = method_name
35
+ return f
36
+
37
+ for provider_class in DEPLOYER_IMPL_PROVIDERS:
38
+ # TYPE is the name of the CLI groups i.e.
39
+ # `argo-workflows` instead of `argo_workflows`
40
+ # The injected method names replace '-' by '_' though.
41
+ method_name = provider_class.TYPE.replace("-", "_")
42
+ setattr(cls, method_name, _injected_method(method_name, provider_class))
43
+
44
+ return cls
48
45
 
49
46
 
50
- class Deployer(object):
47
+ class Deployer(metaclass=DeployerMeta):
51
48
  """
52
49
  Use the `Deployer` class to configure and access one of the production
53
50
  orchestrators supported by Metaflow.
@@ -81,7 +78,7 @@ class Deployer(object):
81
78
  env: Optional[Dict] = None,
82
79
  cwd: Optional[str] = None,
83
80
  file_read_timeout: int = 3600,
84
- **kwargs
81
+ **kwargs,
85
82
  ):
86
83
  self.flow_file = flow_file
87
84
  self.show_output = show_output
@@ -91,56 +88,16 @@ class Deployer(object):
91
88
  self.file_read_timeout = file_read_timeout
92
89
  self.top_level_kwargs = kwargs
93
90
 
94
- from metaflow.plugins import DEPLOYER_IMPL_PROVIDERS
95
-
96
- for provider_class in DEPLOYER_IMPL_PROVIDERS:
97
- # TYPE is the name of the CLI groups i.e.
98
- # `argo-workflows` instead of `argo_workflows`
99
- # The injected method names replace '-' by '_' though.
100
- method_name = provider_class.TYPE.replace("-", "_")
101
- setattr(Deployer, method_name, self.__make_function(provider_class))
102
-
103
- def __make_function(self, deployer_class):
104
- """
105
- Create a function for the given deployer class.
106
-
107
- Parameters
108
- ----------
109
- deployer_class : Type[DeployerImpl]
110
- Deployer implementation class.
111
-
112
- Returns
113
- -------
114
- Callable
115
- Function that initializes and returns an instance of the deployer class.
116
- """
117
-
118
- def f(self, **deployer_kwargs):
119
- return deployer_class(
120
- deployer_kwargs=deployer_kwargs,
121
- flow_file=self.flow_file,
122
- show_output=self.show_output,
123
- profile=self.profile,
124
- env=self.env,
125
- cwd=self.cwd,
126
- file_read_timeout=self.file_read_timeout,
127
- **self.top_level_kwargs
128
- )
129
-
130
- return f
131
-
132
91
 
133
92
  class TriggeredRun(object):
134
93
  """
135
- TriggeredRun class represents a run that has been triggered on a production orchestrator.
136
-
137
- Only when the `start` task starts running, the `run` object corresponding to the run
138
- becomes available.
94
+ TriggeredRun class represents a run that has been triggered on a
95
+ production orchestrator.
139
96
  """
140
97
 
141
98
  def __init__(
142
99
  self,
143
- deployer: "DeployerImpl",
100
+ deployer: "metaflow.runner.deployer_impl.DeployerImpl",
144
101
  content: str,
145
102
  ):
146
103
  self.deployer = deployer
@@ -149,31 +106,18 @@ class TriggeredRun(object):
149
106
  self.pathspec = content_json.get("pathspec")
150
107
  self.name = content_json.get("name")
151
108
 
152
- def _enrich_object(self, env):
153
- """
154
- Enrich the TriggeredRun object with additional properties and methods.
155
-
156
- Parameters
157
- ----------
158
- env : dict
159
- Environment dictionary containing properties and methods to add.
160
- """
161
- for k, v in env.items():
162
- if isinstance(v, property):
163
- setattr(self.__class__, k, v)
164
- elif callable(v):
165
- setattr(self, k, functools.partial(v, self))
166
- else:
167
- setattr(self, k, v)
168
-
169
- def wait_for_run(self, timeout=None):
109
+ def wait_for_run(self, timeout: Optional[int] = None):
170
110
  """
171
111
  Wait for the `run` property to become available.
172
112
 
113
+ The `run` property becomes available only after the `start` task of the triggered
114
+ flow starts running.
115
+
173
116
  Parameters
174
117
  ----------
175
- timeout : int, optional
176
- Maximum time to wait for the `run` to become available, in seconds. If None, wait indefinitely.
118
+ timeout : int, optional, default None
119
+ Maximum time to wait for the `run` to become available, in seconds. If
120
+ None, wait indefinitely.
177
121
 
178
122
  Raises
179
123
  ------
@@ -194,7 +138,7 @@ class TriggeredRun(object):
194
138
  time.sleep(check_interval)
195
139
 
196
140
  @property
197
- def run(self):
141
+ def run(self) -> Optional["metaflow.Run"]:
198
142
  """
199
143
  Retrieve the `Run` object for the triggered run.
200
144
 
@@ -214,178 +158,104 @@ class TriggeredRun(object):
214
158
  return None
215
159
 
216
160
 
217
- class DeployedFlow(object):
218
- """
219
- DeployedFlow class represents a flow that has been deployed.
161
+ class DeployedFlowMeta(type):
162
+ def __new__(mcs, name, bases, dct):
163
+ cls = super().__new__(mcs, name, bases, dct)
164
+ if not bases:
165
+ # Inject methods only in DeployedFlow and not any of its
166
+ # subclasses
167
+ from metaflow.plugins import DEPLOYER_IMPL_PROVIDERS
220
168
 
221
- Parameters
222
- ----------
223
- deployer : DeployerImpl
224
- Instance of the deployer implementation.
225
- """
226
-
227
- def __init__(self, deployer: "DeployerImpl"):
228
- self.deployer = deployer
169
+ allowed_providers = dict(
170
+ {
171
+ provider.TYPE.replace("-", "_"): provider
172
+ for provider in DEPLOYER_IMPL_PROVIDERS
173
+ }
174
+ )
229
175
 
230
- def _enrich_object(self, env):
231
- """
232
- Enrich the DeployedFlow object with additional properties and methods.
176
+ def _default_injected_method():
177
+ def f(
178
+ cls,
179
+ identifier: str,
180
+ metadata: Optional[str] = None,
181
+ impl: str = DEFAULT_FROM_DEPLOYMENT_IMPL.replace("-", "_"),
182
+ ) -> "DeployedFlow":
183
+ """
184
+ Retrieves a `DeployedFlow` object from an identifier and optional
185
+ metadata. The `impl` parameter specifies the deployer implementation
186
+ to use (like `argo-workflows`).
187
+
188
+ Parameters
189
+ ----------
190
+ identifier : str
191
+ Deployer specific identifier for the workflow to retrieve
192
+ metadata : str, optional, default None
193
+ Optional deployer specific metadata.
194
+ impl : str, optional, default given by METAFLOW_DEFAULT_FROM_DEPLOYMENT_IMPL
195
+ The default implementation to use if not specified
196
+
197
+ Returns
198
+ -------
199
+ DeployedFlow
200
+ A `DeployedFlow` object representing the deployed flow corresponding
201
+ to the identifier
202
+ """
203
+ if impl in allowed_providers:
204
+ return (
205
+ allowed_providers[impl]
206
+ .deployed_flow_type()
207
+ .from_deployment(identifier, metadata)
208
+ )
209
+ else:
210
+ raise ValueError(
211
+ f"No deployer '{impl}' exists; valid deployers are: "
212
+ f"{list(allowed_providers.keys())}"
213
+ )
214
+
215
+ f.__name__ = "from_deployment"
216
+ return f
217
+
218
+ def _per_type_injected_method(method_name, impl):
219
+ def f(
220
+ cls,
221
+ identifier: str,
222
+ metadata: Optional[str] = None,
223
+ ):
224
+ return (
225
+ allowed_providers[impl]
226
+ .deployed_flow_type()
227
+ .from_deployment(identifier, metadata)
228
+ )
229
+
230
+ f.__name__ = method_name
231
+ return f
232
+
233
+ setattr(cls, "from_deployment", classmethod(_default_injected_method()))
234
+
235
+ for impl in allowed_providers:
236
+ method_name = f"from_{impl}"
237
+ setattr(
238
+ cls,
239
+ method_name,
240
+ classmethod(_per_type_injected_method(method_name, impl)),
241
+ )
233
242
 
234
- Parameters
235
- ----------
236
- env : dict
237
- Environment dictionary containing properties and methods to add.
238
- """
239
- for k, v in env.items():
240
- if isinstance(v, property):
241
- setattr(self.__class__, k, v)
242
- elif callable(v):
243
- setattr(self, k, functools.partial(v, self))
244
- else:
245
- setattr(self, k, v)
243
+ return cls
246
244
 
247
245
 
248
- class DeployerImpl(object):
246
+ class DeployedFlow(metaclass=DeployedFlowMeta):
249
247
  """
250
- Base class for deployer implementations. Each implementation should define a TYPE
251
- class variable that matches the name of the CLI group.
248
+ DeployedFlow class represents a flow that has been deployed.
252
249
 
253
- Parameters
254
- ----------
255
- flow_file : str
256
- Path to the flow file to deploy.
257
- show_output : bool, default True
258
- Show the 'stdout' and 'stderr' to the console by default.
259
- profile : Optional[str], default None
260
- Metaflow profile to use for the deployment. If not specified, the default
261
- profile is used.
262
- env : Optional[Dict], default None
263
- Additional environment variables to set for the deployment.
264
- cwd : Optional[str], default None
265
- The directory to run the subprocess in; if not specified, the current
266
- directory is used.
267
- file_read_timeout : int, default 3600
268
- The timeout until which we try to read the deployer attribute file.
269
- **kwargs : Any
270
- Additional arguments that you would pass to `python myflow.py` before
271
- the deployment command.
250
+ This class is not meant to be instantiated directly. Instead, it is returned from
251
+ methods of `Deployer`.
272
252
  """
273
253
 
254
+ # This should match the TYPE value in DeployerImpl for proper stub generation
274
255
  TYPE: ClassVar[Optional[str]] = None
275
256
 
276
- def __init__(
277
- self,
278
- flow_file: str,
279
- show_output: bool = True,
280
- profile: Optional[str] = None,
281
- env: Optional[Dict] = None,
282
- cwd: Optional[str] = None,
283
- file_read_timeout: int = 3600,
284
- **kwargs
285
- ):
286
- if self.TYPE is None:
287
- raise ValueError(
288
- "DeployerImpl doesn't have a 'TYPE' to target. Please use a sub-class of DeployerImpl."
289
- )
290
-
291
- if "metaflow.cli" in sys.modules:
292
- importlib.reload(sys.modules["metaflow.cli"])
293
- from metaflow.cli import start
294
- from metaflow.runner.click_api import MetaflowAPI
295
-
296
- self.flow_file = flow_file
297
- self.show_output = show_output
298
- self.profile = profile
299
- self.env = env
300
- self.cwd = cwd
301
- self.file_read_timeout = file_read_timeout
302
-
303
- self.env_vars = os.environ.copy()
304
- self.env_vars.update(self.env or {})
305
- if self.profile:
306
- self.env_vars["METAFLOW_PROFILE"] = profile
307
-
308
- self.spm = SubprocessManager()
309
- self.top_level_kwargs = kwargs
310
- self.api = MetaflowAPI.from_cli(self.flow_file, start)
311
-
312
- def __enter__(self) -> "DeployerImpl":
313
- return self
314
-
315
- def create(self, **kwargs) -> DeployedFlow:
316
- """
317
- Create a deployed flow using the deployer implementation.
318
-
319
- Parameters
320
- ----------
321
- **kwargs : Any
322
- Additional arguments to pass to `create` corresponding to the
323
- command line arguments of `create`
324
-
325
- Returns
326
- -------
327
- DeployedFlow
328
- DeployedFlow object representing the deployed flow.
329
-
330
- Raises
331
- ------
332
- Exception
333
- If there is an error during deployment.
334
- """
335
- with tempfile.TemporaryDirectory() as temp_dir:
336
- tfp_runner_attribute = tempfile.NamedTemporaryFile(
337
- dir=temp_dir, delete=False
338
- )
339
- # every subclass needs to have `self.deployer_kwargs`
340
- command = get_lower_level_group(
341
- self.api, self.top_level_kwargs, self.TYPE, self.deployer_kwargs
342
- ).create(deployer_attribute_file=tfp_runner_attribute.name, **kwargs)
343
-
344
- pid = self.spm.run_command(
345
- [sys.executable, *command],
346
- env=self.env_vars,
347
- cwd=self.cwd,
348
- show_output=self.show_output,
349
- )
350
-
351
- command_obj = self.spm.get(pid)
352
- content = handle_timeout(
353
- tfp_runner_attribute, command_obj, self.file_read_timeout
354
- )
355
- content = json.loads(content)
356
- self.name = content.get("name")
357
- self.flow_name = content.get("flow_name")
358
- self.metadata = content.get("metadata")
359
- # Additional info is used to pass additional deployer specific information.
360
- # It is used in non-OSS deployers (extensions).
361
- self.additional_info = content.get("additional_info", {})
362
-
363
- if command_obj.process.returncode == 0:
364
- deployed_flow = DeployedFlow(deployer=self)
365
- self._enrich_deployed_flow(deployed_flow)
366
- return deployed_flow
367
-
368
- raise Exception("Error deploying %s to %s" % (self.flow_file, self.TYPE))
369
-
370
- def _enrich_deployed_flow(self, deployed_flow: DeployedFlow):
371
- """
372
- Enrich the DeployedFlow object with additional properties and methods.
373
-
374
- Parameters
375
- ----------
376
- deployed_flow : DeployedFlow
377
- The DeployedFlow object to enrich.
378
- """
379
- raise NotImplementedError
380
-
381
- def __exit__(self, exc_type, exc_value, traceback):
382
- """
383
- Cleanup resources on exit.
384
- """
385
- self.cleanup()
386
-
387
- def cleanup(self):
388
- """
389
- Cleanup resources.
390
- """
391
- self.spm.cleanup()
257
+ def __init__(self, deployer: "metaflow.runner.deployer_impl.DeployerImpl"):
258
+ self.deployer = deployer
259
+ self.name = self.deployer.name
260
+ self.flow_name = self.deployer.flow_name
261
+ self.metadata = self.deployer.metadata