metaflow 2.12.10__py2.py3-none-any.whl → 2.12.12__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 (39) hide show
  1. metaflow/client/core.py +6 -6
  2. metaflow/client/filecache.py +16 -3
  3. metaflow/cmd/develop/stub_generator.py +62 -47
  4. metaflow/datastore/content_addressed_store.py +1 -1
  5. metaflow/datastore/task_datastore.py +1 -1
  6. metaflow/decorators.py +2 -4
  7. metaflow/extension_support/__init__.py +3 -3
  8. metaflow/extension_support/plugins.py +3 -3
  9. metaflow/metaflow_config.py +35 -18
  10. metaflow/parameters.py +3 -3
  11. metaflow/plugins/airflow/airflow.py +6 -6
  12. metaflow/plugins/airflow/airflow_utils.py +5 -3
  13. metaflow/plugins/argo/argo_workflows.py +407 -193
  14. metaflow/plugins/argo/argo_workflows_cli.py +17 -4
  15. metaflow/plugins/argo/argo_workflows_decorator.py +6 -13
  16. metaflow/plugins/argo/capture_error.py +70 -0
  17. metaflow/plugins/aws/step_functions/step_functions.py +3 -3
  18. metaflow/plugins/cards/card_modules/basic.py +5 -3
  19. metaflow/plugins/cards/card_modules/convert_to_native_type.py +2 -2
  20. metaflow/plugins/cards/card_modules/renderer_tools.py +1 -0
  21. metaflow/plugins/cards/card_modules/test_cards.py +0 -2
  22. metaflow/plugins/datatools/s3/s3op.py +5 -3
  23. metaflow/plugins/kubernetes/kubernetes.py +1 -0
  24. metaflow/plugins/kubernetes/kubernetes_job.py +10 -8
  25. metaflow/plugins/kubernetes/kubernetes_jobsets.py +15 -14
  26. metaflow/plugins/logs_cli.py +1 -0
  27. metaflow/plugins/pypi/conda_environment.py +1 -3
  28. metaflow/plugins/pypi/pip.py +3 -3
  29. metaflow/plugins/tag_cli.py +3 -3
  30. metaflow/procpoll.py +1 -1
  31. metaflow/runtime.py +1 -0
  32. metaflow/util.py +6 -6
  33. metaflow/version.py +1 -1
  34. {metaflow-2.12.10.dist-info → metaflow-2.12.12.dist-info}/METADATA +2 -2
  35. {metaflow-2.12.10.dist-info → metaflow-2.12.12.dist-info}/RECORD +39 -38
  36. {metaflow-2.12.10.dist-info → metaflow-2.12.12.dist-info}/WHEEL +1 -1
  37. {metaflow-2.12.10.dist-info → metaflow-2.12.12.dist-info}/LICENSE +0 -0
  38. {metaflow-2.12.10.dist-info → metaflow-2.12.12.dist-info}/entry_points.txt +0 -0
  39. {metaflow-2.12.10.dist-info → metaflow-2.12.12.dist-info}/top_level.txt +0 -0
metaflow/client/core.py CHANGED
@@ -391,9 +391,9 @@ class MetaflowObject(object):
391
391
  _object=obj,
392
392
  _parent=self,
393
393
  _namespace_check=self._namespace_check,
394
- _current_namespace=self._current_namespace
395
- if self._namespace_check
396
- else None,
394
+ _current_namespace=(
395
+ self._current_namespace if self._namespace_check else None
396
+ ),
397
397
  )
398
398
  for obj in unfiltered_children
399
399
  ),
@@ -506,9 +506,9 @@ class MetaflowObject(object):
506
506
  _object=obj,
507
507
  _parent=self,
508
508
  _namespace_check=self._namespace_check,
509
- _current_namespace=self._current_namespace
510
- if self._namespace_check
511
- else None,
509
+ _current_namespace=(
510
+ self._current_namespace if self._namespace_check else None
511
+ ),
512
512
  )
513
513
  else:
514
514
  raise KeyError(id)
@@ -6,6 +6,8 @@ import time
6
6
  from tempfile import NamedTemporaryFile
7
7
  from hashlib import sha1
8
8
 
9
+ from urllib.parse import urlparse
10
+
9
11
  from metaflow.datastore import FlowDataStore
10
12
  from metaflow.datastore.content_addressed_store import BlobCache
11
13
  from metaflow.exception import MetaflowException
@@ -83,7 +85,6 @@ class FileCache(object):
83
85
  def get_log_legacy(
84
86
  self, ds_type, location, logtype, attempt, flow_name, run_id, step_name, task_id
85
87
  ):
86
-
87
88
  ds_cls = self._get_datastore_storage_impl(ds_type)
88
89
  ds_root = ds_cls.path_join(*ds_cls.path_split(location)[:-5])
89
90
  cache_id = self._flow_ds_id(ds_type, ds_root, flow_name)
@@ -311,12 +312,24 @@ class FileCache(object):
311
312
 
312
313
  @staticmethod
313
314
  def _flow_ds_id(ds_type, ds_root, flow_name):
314
- return ".".join([ds_type, ds_root, flow_name])
315
+ p = urlparse(ds_root)
316
+ sanitized_root = (p.netloc + p.path).replace("/", "_")
317
+ return ".".join([ds_type, sanitized_root, flow_name])
315
318
 
316
319
  @staticmethod
317
320
  def _task_ds_id(ds_type, ds_root, flow_name, run_id, step_name, task_id, attempt):
321
+ p = urlparse(ds_root)
322
+ sanitized_root = (p.netloc + p.path).replace("/", "_")
318
323
  return ".".join(
319
- [ds_type, ds_root, flow_name, run_id, step_name, task_id, str(attempt)]
324
+ [
325
+ ds_type,
326
+ sanitized_root,
327
+ flow_name,
328
+ run_id,
329
+ step_name,
330
+ task_id,
331
+ str(attempt),
332
+ ]
320
333
  )
321
334
 
322
335
  def _garbage_collect(self):
@@ -292,9 +292,11 @@ class StubGenerator:
292
292
  try:
293
293
  potential_element = eval(
294
294
  element,
295
- self._current_parent_module.__dict__
296
- if self._current_parent_module
297
- else None,
295
+ (
296
+ self._current_parent_module.__dict__
297
+ if self._current_parent_module
298
+ else None
299
+ ),
298
300
  )
299
301
  if potential_element:
300
302
  element = potential_element
@@ -555,14 +557,14 @@ class StubGenerator:
555
557
  inspect.Parameter(
556
558
  name=arg_name,
557
559
  kind=inspect.Parameter.KEYWORD_ONLY,
558
- default=default
559
- if default_set
560
- else None
561
- if is_optional
562
- else inspect.Parameter.empty,
563
- annotation=Optional[type_name]
564
- if is_optional
565
- else type_name,
560
+ default=(
561
+ default
562
+ if default_set
563
+ else None if is_optional else inspect.Parameter.empty
564
+ ),
565
+ annotation=(
566
+ Optional[type_name] if is_optional else type_name
567
+ ),
566
568
  )
567
569
  )
568
570
  if not default_set:
@@ -706,24 +708,31 @@ class StubGenerator:
706
708
  result = result + [
707
709
  (
708
710
  inspect.Signature(
709
- parameters=[
710
- inspect.Parameter(
711
- name="f",
712
- kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
713
- annotation=Optional[typing.Type[FlowSpecDerived]],
714
- default=None
715
- if no_arg_version
716
- else inspect.Parameter.empty,
717
- )
718
- ]
719
- + parameters
720
- if no_arg_version
721
- else [] + parameters,
722
- return_annotation=inspect.Signature.empty
723
- if no_arg_version
724
- else Callable[
725
- [typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]
726
- ],
711
+ parameters=(
712
+ [
713
+ inspect.Parameter(
714
+ name="f",
715
+ kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
716
+ annotation=Optional[typing.Type[FlowSpecDerived]],
717
+ default=(
718
+ None
719
+ if no_arg_version
720
+ else inspect.Parameter.empty
721
+ ),
722
+ )
723
+ ]
724
+ + parameters
725
+ if no_arg_version
726
+ else [] + parameters
727
+ ),
728
+ return_annotation=(
729
+ inspect.Signature.empty
730
+ if no_arg_version
731
+ else Callable[
732
+ [typing.Type[FlowSpecDerived]],
733
+ typing.Type[FlowSpecDerived],
734
+ ]
735
+ ),
727
736
  ),
728
737
  "",
729
738
  ),
@@ -732,24 +741,30 @@ class StubGenerator:
732
741
  result = result + [
733
742
  (
734
743
  inspect.Signature(
735
- parameters=[
736
- inspect.Parameter(
737
- name="f",
738
- kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
739
- annotation=Optional[MetaflowStepFunction],
740
- default=None
741
- if no_arg_version
742
- else inspect.Parameter.empty,
743
- )
744
- ]
745
- + parameters
746
- if no_arg_version
747
- else [] + parameters,
748
- return_annotation=inspect.Signature.empty
749
- if no_arg_version
750
- else typing.Callable[
751
- [MetaflowStepFunction], MetaflowStepFunction
752
- ],
744
+ parameters=(
745
+ [
746
+ inspect.Parameter(
747
+ name="f",
748
+ kind=inspect.Parameter.POSITIONAL_OR_KEYWORD,
749
+ annotation=Optional[MetaflowStepFunction],
750
+ default=(
751
+ None
752
+ if no_arg_version
753
+ else inspect.Parameter.empty
754
+ ),
755
+ )
756
+ ]
757
+ + parameters
758
+ if no_arg_version
759
+ else [] + parameters
760
+ ),
761
+ return_annotation=(
762
+ inspect.Signature.empty
763
+ if no_arg_version
764
+ else typing.Callable[
765
+ [MetaflowStepFunction], MetaflowStepFunction
766
+ ]
767
+ ),
753
768
  ),
754
769
  "",
755
770
  ),
@@ -133,7 +133,7 @@ class ContentAddressedStore(object):
133
133
  load_paths.append((key, path))
134
134
 
135
135
  with self._storage_impl.load_bytes([p for _, p in load_paths]) as loaded:
136
- for (path_key, file_path, meta) in loaded:
136
+ for path_key, file_path, meta in loaded:
137
137
  key = self._storage_impl.path_split(path_key)[-1]
138
138
  # At this point, we either return the object as is (if raw) or
139
139
  # decode it according to the encoding version
@@ -381,7 +381,7 @@ class TaskDataStore(object):
381
381
  # We assume that if we have one "old" style artifact, all of them are
382
382
  # like that which is an easy assumption to make since artifacts are all
383
383
  # stored by the same implementation of the datastore for a given task.
384
- for (key, blob) in self._ca_store.load_blobs(to_load.keys()):
384
+ for key, blob in self._ca_store.load_blobs(to_load.keys()):
385
385
  names = to_load[key]
386
386
  for name in names:
387
387
  # We unpickle everytime to have fully distinct objects (the user
metaflow/decorators.py CHANGED
@@ -575,15 +575,13 @@ StepFlag = NewType("StepFlag", bool)
575
575
  @overload
576
576
  def step(
577
577
  f: Callable[[FlowSpecDerived], None]
578
- ) -> Callable[[FlowSpecDerived, StepFlag], None]:
579
- ...
578
+ ) -> Callable[[FlowSpecDerived, StepFlag], None]: ...
580
579
 
581
580
 
582
581
  @overload
583
582
  def step(
584
583
  f: Callable[[FlowSpecDerived, Any], None],
585
- ) -> Callable[[FlowSpecDerived, Any, StepFlag], None]:
586
- ...
584
+ ) -> Callable[[FlowSpecDerived, Any, StepFlag], None]: ...
587
585
 
588
586
 
589
587
  def step(
@@ -980,9 +980,9 @@ class _OrigLoader(Loader):
980
980
  if self._previously_loaded_module:
981
981
  sys.modules[self._orig_name] = self._previously_loaded_module
982
982
  if self._previously_loaded_parent_module:
983
- sys.modules[
984
- ".".join(self._orig_name.split(".")[:-1])
985
- ] = self._previously_loaded_parent_module
983
+ sys.modules[".".join(self._orig_name.split(".")[:-1])] = (
984
+ self._previously_loaded_parent_module
985
+ )
986
986
 
987
987
 
988
988
  class _LazyFinder(MetaPathFinder):
@@ -186,9 +186,9 @@ _plugin_categories = {
186
186
  "logging_sidecar": None,
187
187
  "monitor_sidecar": None,
188
188
  "aws_client_provider": lambda x: x.name,
189
- "cli": lambda x: list(x.commands)[0]
190
- if len(x.commands) == 1
191
- else "too many commands",
189
+ "cli": lambda x: (
190
+ list(x.commands)[0] if len(x.commands) == 1 else "too many commands"
191
+ ),
192
192
  }
193
193
 
194
194
 
@@ -104,9 +104,11 @@ RETRY_WARNING_THRESHOLD = 3
104
104
  DATATOOLS_SUFFIX = from_conf("DATATOOLS_SUFFIX", "data")
105
105
  DATATOOLS_S3ROOT = from_conf(
106
106
  "DATATOOLS_S3ROOT",
107
- os.path.join(DATASTORE_SYSROOT_S3, DATATOOLS_SUFFIX)
108
- if DATASTORE_SYSROOT_S3
109
- else None,
107
+ (
108
+ os.path.join(DATASTORE_SYSROOT_S3, DATATOOLS_SUFFIX)
109
+ if DATASTORE_SYSROOT_S3
110
+ else None
111
+ ),
110
112
  )
111
113
 
112
114
  TEMPDIR = from_conf("TEMPDIR", ".")
@@ -124,25 +126,31 @@ DATATOOLS_SESSION_VARS = from_conf("DATATOOLS_SESSION_VARS", {})
124
126
  # Similar to DATATOOLS_LOCALROOT, this is used ONLY by the IncludeFile's internal implementation.
125
127
  DATATOOLS_AZUREROOT = from_conf(
126
128
  "DATATOOLS_AZUREROOT",
127
- os.path.join(DATASTORE_SYSROOT_AZURE, DATATOOLS_SUFFIX)
128
- if DATASTORE_SYSROOT_AZURE
129
- else None,
129
+ (
130
+ os.path.join(DATASTORE_SYSROOT_AZURE, DATATOOLS_SUFFIX)
131
+ if DATASTORE_SYSROOT_AZURE
132
+ else None
133
+ ),
130
134
  )
131
135
  # GS datatools root location
132
136
  # Note: we do not expose an actual datatools library for GS (like we do for S3)
133
137
  # Similar to DATATOOLS_LOCALROOT, this is used ONLY by the IncludeFile's internal implementation.
134
138
  DATATOOLS_GSROOT = from_conf(
135
139
  "DATATOOLS_GSROOT",
136
- os.path.join(DATASTORE_SYSROOT_GS, DATATOOLS_SUFFIX)
137
- if DATASTORE_SYSROOT_GS
138
- else None,
140
+ (
141
+ os.path.join(DATASTORE_SYSROOT_GS, DATATOOLS_SUFFIX)
142
+ if DATASTORE_SYSROOT_GS
143
+ else None
144
+ ),
139
145
  )
140
146
  # Local datatools root location
141
147
  DATATOOLS_LOCALROOT = from_conf(
142
148
  "DATATOOLS_LOCALROOT",
143
- os.path.join(DATASTORE_SYSROOT_LOCAL, DATATOOLS_SUFFIX)
144
- if DATASTORE_SYSROOT_LOCAL
145
- else None,
149
+ (
150
+ os.path.join(DATASTORE_SYSROOT_LOCAL, DATATOOLS_SUFFIX)
151
+ if DATASTORE_SYSROOT_LOCAL
152
+ else None
153
+ ),
146
154
  )
147
155
 
148
156
  # Secrets Backend - AWS Secrets Manager configuration
@@ -176,9 +184,11 @@ CARD_S3ROOT = from_conf(
176
184
  )
177
185
  CARD_AZUREROOT = from_conf(
178
186
  "CARD_AZUREROOT",
179
- os.path.join(DATASTORE_SYSROOT_AZURE, CARD_SUFFIX)
180
- if DATASTORE_SYSROOT_AZURE
181
- else None,
187
+ (
188
+ os.path.join(DATASTORE_SYSROOT_AZURE, CARD_SUFFIX)
189
+ if DATASTORE_SYSROOT_AZURE
190
+ else None
191
+ ),
182
192
  )
183
193
  CARD_GSROOT = from_conf(
184
194
  "CARD_GSROOT",
@@ -238,6 +248,11 @@ DEFAULT_RUNTIME_LIMIT = from_conf("DEFAULT_RUNTIME_LIMIT", 5 * 24 * 60 * 60)
238
248
  ###
239
249
  UI_URL = from_conf("UI_URL")
240
250
 
251
+ ###
252
+ # Capture error logs from argo
253
+ ###
254
+ ARGO_WORKFLOWS_CAPTURE_ERROR_SCRIPT = from_conf("ARGO_WORKFLOWS_CAPTURE_ERROR_SCRIPT")
255
+
241
256
  # Contact information displayed when running the `metaflow` command.
242
257
  # Value should be a dictionary where:
243
258
  # - key is a string describing contact method
@@ -306,9 +321,11 @@ SFN_EXECUTION_LOG_GROUP_ARN = from_conf("SFN_EXECUTION_LOG_GROUP_ARN")
306
321
  # Amazon S3 path for storing the results of AWS Step Functions Distributed Map
307
322
  SFN_S3_DISTRIBUTED_MAP_OUTPUT_PATH = from_conf(
308
323
  "SFN_S3_DISTRIBUTED_MAP_OUTPUT_PATH",
309
- os.path.join(DATASTORE_SYSROOT_S3, "sfn_distributed_map_output")
310
- if DATASTORE_SYSROOT_S3
311
- else None,
324
+ (
325
+ os.path.join(DATASTORE_SYSROOT_S3, "sfn_distributed_map_output")
326
+ if DATASTORE_SYSROOT_S3
327
+ else None
328
+ ),
312
329
  )
313
330
  ###
314
331
  # Kubernetes configuration
metaflow/parameters.py CHANGED
@@ -115,9 +115,9 @@ class DeployTimeField(object):
115
115
  self.parameter_name = parameter_name
116
116
  self.parameter_type = parameter_type
117
117
  self.return_str = return_str
118
- self.print_representation = (
119
- self.user_print_representation
120
- ) = print_representation
118
+ self.print_representation = self.user_print_representation = (
119
+ print_representation
120
+ )
121
121
  if self.print_representation is None:
122
122
  self.print_representation = str(self.fun)
123
123
 
@@ -399,17 +399,17 @@ class Airflow(object):
399
399
  "METAFLOW_CARD_GSROOT": CARD_GSROOT,
400
400
  "METAFLOW_S3_ENDPOINT_URL": S3_ENDPOINT_URL,
401
401
  }
402
- env[
403
- "METAFLOW_AZURE_STORAGE_BLOB_SERVICE_ENDPOINT"
404
- ] = AZURE_STORAGE_BLOB_SERVICE_ENDPOINT
402
+ env["METAFLOW_AZURE_STORAGE_BLOB_SERVICE_ENDPOINT"] = (
403
+ AZURE_STORAGE_BLOB_SERVICE_ENDPOINT
404
+ )
405
405
  env["METAFLOW_DATASTORE_SYSROOT_AZURE"] = DATASTORE_SYSROOT_AZURE
406
406
  env["METAFLOW_CARD_AZUREROOT"] = CARD_AZUREROOT
407
407
  if DEFAULT_SECRETS_BACKEND_TYPE:
408
408
  env["METAFLOW_DEFAULT_SECRETS_BACKEND_TYPE"] = DEFAULT_SECRETS_BACKEND_TYPE
409
409
  if AWS_SECRETS_MANAGER_DEFAULT_REGION:
410
- env[
411
- "METAFLOW_AWS_SECRETS_MANAGER_DEFAULT_REGION"
412
- ] = AWS_SECRETS_MANAGER_DEFAULT_REGION
410
+ env["METAFLOW_AWS_SECRETS_MANAGER_DEFAULT_REGION"] = (
411
+ AWS_SECRETS_MANAGER_DEFAULT_REGION
412
+ )
413
413
  if GCP_SECRET_MANAGER_PREFIX:
414
414
  env["METAFLOW_GCP_SECRET_MANAGER_PREFIX"] = GCP_SECRET_MANAGER_PREFIX
415
415
 
@@ -567,9 +567,11 @@ class AirflowTask(object):
567
567
  return cls(
568
568
  task_dict["name"],
569
569
  is_mapper_node=is_mapper_node,
570
- operator_type=task_dict["operator_type"]
571
- if "operator_type" in task_dict
572
- else "kubernetes",
570
+ operator_type=(
571
+ task_dict["operator_type"]
572
+ if "operator_type" in task_dict
573
+ else "kubernetes"
574
+ ),
573
575
  flow_name=flow_name,
574
576
  flow_contains_foreach=flow_contains_foreach,
575
577
  ).set_operator_args(**op_args)