ob-metaflow 2.16.6.4rc0__py2.py3-none-any.whl → 2.16.6.5rc2__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 (30) hide show
  1. metaflow/_vendor/imghdr/__init__.py +0 -5
  2. metaflow/client/core.py +1 -6
  3. metaflow/extension_support/__init__.py +3 -4
  4. metaflow/metaflow_environment.py +6 -14
  5. metaflow/package/__init__.py +9 -18
  6. metaflow/packaging_sys/__init__.py +43 -53
  7. metaflow/packaging_sys/backend.py +6 -21
  8. metaflow/packaging_sys/tar_backend.py +3 -16
  9. metaflow/packaging_sys/v1.py +21 -21
  10. metaflow/plugins/argo/argo_client.py +31 -14
  11. metaflow/plugins/argo/argo_workflows.py +66 -17
  12. metaflow/plugins/argo/argo_workflows_cli.py +1 -2
  13. metaflow/plugins/argo/argo_workflows_deployer_objects.py +32 -0
  14. metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +14 -0
  15. metaflow/plugins/kubernetes/kubernetes_decorator.py +1 -1
  16. metaflow/plugins/pypi/conda_decorator.py +2 -4
  17. metaflow/runner/click_api.py +7 -14
  18. metaflow/runner/deployer.py +83 -7
  19. metaflow/runner/subprocess_manager.py +12 -20
  20. metaflow/user_decorators/mutable_flow.py +3 -1
  21. metaflow/version.py +1 -1
  22. {ob_metaflow-2.16.6.4rc0.data → ob_metaflow-2.16.6.5rc2.data}/data/share/metaflow/devtools/Tiltfile +43 -2
  23. {ob_metaflow-2.16.6.4rc0.data → ob_metaflow-2.16.6.5rc2.data}/data/share/metaflow/devtools/pick_services.sh +1 -0
  24. {ob_metaflow-2.16.6.4rc0.dist-info → ob_metaflow-2.16.6.5rc2.dist-info}/METADATA +2 -2
  25. {ob_metaflow-2.16.6.4rc0.dist-info → ob_metaflow-2.16.6.5rc2.dist-info}/RECORD +30 -30
  26. {ob_metaflow-2.16.6.4rc0.data → ob_metaflow-2.16.6.5rc2.data}/data/share/metaflow/devtools/Makefile +0 -0
  27. {ob_metaflow-2.16.6.4rc0.dist-info → ob_metaflow-2.16.6.5rc2.dist-info}/WHEEL +0 -0
  28. {ob_metaflow-2.16.6.4rc0.dist-info → ob_metaflow-2.16.6.5rc2.dist-info}/entry_points.txt +0 -0
  29. {ob_metaflow-2.16.6.4rc0.dist-info → ob_metaflow-2.16.6.5rc2.dist-info}/licenses/LICENSE +0 -0
  30. {ob_metaflow-2.16.6.4rc0.dist-info → ob_metaflow-2.16.6.5rc2.dist-info}/top_level.txt +0 -0
@@ -1,14 +1,9 @@
1
1
  """Recognize image file formats based on their first few bytes."""
2
2
 
3
3
  from os import PathLike
4
- import warnings
5
4
 
6
5
  __all__ = ["what"]
7
6
 
8
-
9
- warnings._deprecated(__name__, remove=(3, 13))
10
-
11
-
12
7
  #-------------------------#
13
8
  # Recognize image headers #
14
9
  #-------------------------#
metaflow/client/core.py CHANGED
@@ -831,12 +831,10 @@ class MetaflowCode(object):
831
831
  )
832
832
  self._code_obj = BytesIO(blobdata)
833
833
  self._info = MetaflowPackage.cls_get_info(self._code_metadata, self._code_obj)
834
- self._code_obj.seek(0)
835
834
  if self._info:
836
835
  self._flowspec = MetaflowPackage.cls_get_content(
837
836
  self._code_metadata, self._code_obj, self._info["script"]
838
837
  )
839
- self._code_obj.seek(0)
840
838
  else:
841
839
  raise MetaflowInternalError("Code package metadata is invalid.")
842
840
 
@@ -887,9 +885,7 @@ class MetaflowCode(object):
887
885
  TarFile for everything in this code package
888
886
  """
889
887
  if self._backend.type == "tgz":
890
- to_return = self._backend.cls_open(self._code_obj)
891
- self._code_obj.seek(0)
892
- return to_return
888
+ return self._backend.cls_open(self._code_obj)
893
889
  raise RuntimeError("Archive is not a tarball")
894
890
 
895
891
  def extract(self) -> TemporaryDirectory:
@@ -925,7 +921,6 @@ class MetaflowCode(object):
925
921
  MetaflowPackage.cls_extract_into(
926
922
  self._code_metadata, self._code_obj, tmp.name, ContentType.USER_CONTENT
927
923
  )
928
- self._code_obj.seek(0)
929
924
  return tmp
930
925
 
931
926
  @property
@@ -205,10 +205,9 @@ def package_mfext_all():
205
205
  # the packaged metaflow_extensions directory "self-contained" so that
206
206
  # python doesn't go and search other parts of the system for more
207
207
  # metaflow_extensions.
208
- if _all_packages:
209
- yield os.path.join(
210
- os.path.dirname(os.path.abspath(__file__)), "_empty_file.py"
211
- ), os.path.join(EXT_PKG, "__init__.py")
208
+ yield os.path.join(
209
+ os.path.dirname(os.path.abspath(__file__)), "_empty_file.py"
210
+ ), os.path.join(EXT_PKG, "__init__.py")
212
211
 
213
212
  for p in _all_packages:
214
213
  for path_tuple in package_mfext_package(p):
@@ -203,19 +203,6 @@ class MetaflowEnvironment(object):
203
203
  "mfcontent_version": 1,
204
204
  }
205
205
  )
206
-
207
- extra_exports = []
208
- for k, v in MetaflowPackage.get_post_extract_env_vars(
209
- code_package_metadata, dest_dir="$(pwd)"
210
- ).items():
211
- if k.endswith(":"):
212
- # If the value ends with a colon, we override the existing value
213
- extra_exports.append("export %s=%s" % (k[:-1], v))
214
- else:
215
- extra_exports.append(
216
- "export %s=%s:$(printenv %s)" % (k, v.replace('"', '\\"'), k)
217
- )
218
-
219
206
  cmds = (
220
207
  [
221
208
  BASH_MFLOG,
@@ -239,7 +226,12 @@ class MetaflowEnvironment(object):
239
226
  + MetaflowPackage.get_extract_commands(
240
227
  code_package_metadata, "job.tar", dest_dir="."
241
228
  )
242
- + extra_exports
229
+ + [
230
+ "export %s=%s:$(printenv %s)" % (k, v.replace('"', '\\"'), k)
231
+ for k, v in MetaflowPackage.get_post_extract_env_vars(
232
+ code_package_metadata, dest_dir="."
233
+ ).items()
234
+ ]
243
235
  + [
244
236
  "mflog 'Task is starting.'",
245
237
  "flush_mflogs",
@@ -17,6 +17,7 @@ from ..packaging_sys.utils import suffix_filter, walk
17
17
  from ..metaflow_config import DEFAULT_PACKAGE_SUFFIXES
18
18
  from ..exception import MetaflowException
19
19
  from ..user_configs.config_parameters import dump_config_values
20
+ from ..util import get_metaflow_root
20
21
  from .. import R
21
22
 
22
23
  DEFAULT_SUFFIXES_LIST = DEFAULT_PACKAGE_SUFFIXES.split(",")
@@ -75,22 +76,12 @@ class MetaflowPackage(object):
75
76
  from ..user_decorators.user_flow_decorator import FlowMutatorMeta
76
77
  from ..user_decorators.user_step_decorator import UserStepDecoratorMeta
77
78
 
78
- # Be very defensive here to filter modules in case there are
79
- # some badly behaved modules that have weird values for
80
- # METAFLOW_PACKAGE_POLICY for example.
81
- try:
82
- if (
83
- m.__name__ in FlowMutatorMeta._import_modules
84
- or m.__name__ in UserStepDecoratorMeta._import_modules
85
- or (
86
- hasattr(m, "METAFLOW_PACKAGE_POLICY")
87
- and m.METAFLOW_PACKAGE_POLICY == "include"
88
- )
89
- ):
90
- return True
91
- return False
92
- except:
93
- return False
79
+ if (
80
+ m.__name__ in FlowMutatorMeta._import_modules
81
+ or m.__name__ in UserStepDecoratorMeta._import_modules
82
+ or hasattr(m, "METAFLOW_PACKAGE")
83
+ ):
84
+ return True
94
85
 
95
86
  if mfcontent is None:
96
87
  self._mfcontent = MetaflowCodeContentV1(criteria=_module_selector)
@@ -359,10 +350,10 @@ class MetaflowPackage(object):
359
350
  """
360
351
  backend = cls.get_backend(pkg_metadata)
361
352
  with backend.cls_open(archive) as opened_archive:
362
- include_members = MetaflowCodeContent.get_archive_content_members(
353
+ include_names = MetaflowCodeContent.get_archive_content_names(
363
354
  opened_archive, content_types, backend
364
355
  )
365
- backend.cls_extract_members(opened_archive, include_members, dest_dir)
356
+ backend.extract_members(include_names, dest_dir)
366
357
 
367
358
  def user_tuples(self, timeout: Optional[float] = None):
368
359
  # Wait for at least the blob to be formed
@@ -118,7 +118,9 @@ class MetaflowCodeContent:
118
118
  return handling_cls.get_filename_impl(mfcontent_info, filename, content_type)
119
119
 
120
120
  @classmethod
121
- def get_env_vars_for_packaged_metaflow(cls, dest_dir: str) -> Dict[str, str]:
121
+ def get_env_vars_for_packaged_metaflow(
122
+ cls, dest_dir: str
123
+ ) -> Optional[Dict[str, str]]:
122
124
  """
123
125
  Get the environment variables that are needed to run Metaflow when it is
124
126
  packaged. This is typically used to set the PYTHONPATH to include the
@@ -126,19 +128,17 @@ class MetaflowCodeContent:
126
128
 
127
129
  Returns
128
130
  -------
129
- Dict[str, str]
131
+ Optional[Dict[str, str]]
130
132
  The environment variables that are needed to run Metaflow when it is
131
- packaged it present.
133
+ packaged -- None if there are no such variables (not packaged for example)
132
134
  """
133
- mfcontent_info = cls._extract_mfcontent_info(dest_dir)
135
+ mfcontent_info = cls._extract_mfcontent_info()
134
136
  if mfcontent_info is None:
135
137
  # No MFCONTENT_MARKER file found -- this is not a packaged Metaflow code
136
138
  # package so no environment variables to set.
137
- return {}
139
+ return None
138
140
  handling_cls = cls._get_mfcontent_class(mfcontent_info)
139
- v = handling_cls.get_post_extract_env_vars_impl(dest_dir)
140
- v["METAFLOW_EXTRACTED_ROOT:"] = dest_dir
141
- return v
141
+ return handling_cls.get_post_extract_env_vars_impl(dest_dir)
142
142
 
143
143
  @classmethod
144
144
  def get_archive_info(
@@ -216,15 +216,15 @@ class MetaflowCodeContent:
216
216
  )
217
217
 
218
218
  @classmethod
219
- def get_archive_content_members(
219
+ def get_archive_content_names(
220
220
  cls,
221
221
  archive: Any,
222
222
  content_types: Optional[int] = None,
223
223
  packaging_backend: Type[PackagingBackend] = TarPackagingBackend,
224
- ) -> List[Any]:
224
+ ) -> List[str]:
225
225
  mfcontent_info = cls._extract_archive_mfcontent_info(archive, packaging_backend)
226
226
  handling_cls = cls._get_mfcontent_class(mfcontent_info)
227
- return handling_cls.get_archive_content_members_impl(
227
+ return handling_cls.get_archive_content_names_impl(
228
228
  mfcontent_info, archive, content_types, packaging_backend
229
229
  )
230
230
 
@@ -276,9 +276,7 @@ class MetaflowCodeContent:
276
276
  "Invalid package -- unknown version %s in info: %s"
277
277
  % (version_id, cls._mappings)
278
278
  )
279
- v = cls._mappings[version_id].get_post_extract_env_vars_impl(dest_dir)
280
- v["METAFLOW_EXTRACTED_ROOT:"] = dest_dir
281
- return v
279
+ return cls._mappings[version_id].get_post_extract_env_vars_impl(dest_dir)
282
280
 
283
281
  # Implement the _impl methods in the base subclass (in this file). These need to
284
282
  # happen with as few imports as possible to prevent circular dependencies.
@@ -339,14 +337,14 @@ class MetaflowCodeContent:
339
337
  raise NotImplementedError("get_archive_filename_impl not implemented")
340
338
 
341
339
  @classmethod
342
- def get_archive_content_members_impl(
340
+ def get_archive_content_names_impl(
343
341
  cls,
344
342
  mfcontent_info: Optional[Dict[str, Any]],
345
343
  archive: Any,
346
344
  content_types: Optional[int] = None,
347
345
  packaging_backend: Type[PackagingBackend] = TarPackagingBackend,
348
- ) -> List[Any]:
349
- raise NotImplementedError("get_archive_content_members_impl not implemented")
346
+ ) -> List[str]:
347
+ raise NotImplementedError("get_archive_content_names_impl not implemented")
350
348
 
351
349
  @classmethod
352
350
  def get_post_extract_env_vars_impl(cls, dest_dir: str) -> Dict[str, str]:
@@ -525,22 +523,19 @@ class MetaflowCodeContent:
525
523
  return mfcontent_info
526
524
 
527
525
  @classmethod
528
- def _extract_mfcontent_info(
529
- cls, target_dir: Optional[str] = None
530
- ) -> Optional[Dict[str, Any]]:
531
- target_dir = target_dir or "_local"
532
- if target_dir in cls._cached_mfcontent_info:
533
- return cls._cached_mfcontent_info[target_dir]
526
+ def _extract_mfcontent_info(cls) -> Optional[Dict[str, Any]]:
527
+ if "_local" in cls._cached_mfcontent_info:
528
+ return cls._cached_mfcontent_info["_local"]
534
529
 
535
530
  mfcontent_info = None # type: Optional[Dict[str, Any]]
536
- if target_dir == "_local":
537
- root = os.environ.get("METAFLOW_EXTRACTED_ROOT", get_metaflow_root())
538
- else:
539
- root = target_dir
540
- if os.path.exists(os.path.join(root, MFCONTENT_MARKER)):
541
- with open(os.path.join(root, MFCONTENT_MARKER), "r", encoding="utf-8") as f:
531
+ if os.path.exists(os.path.join(get_metaflow_root(), MFCONTENT_MARKER)):
532
+ with open(
533
+ os.path.join(get_metaflow_root(), MFCONTENT_MARKER),
534
+ "r",
535
+ encoding="utf-8",
536
+ ) as f:
542
537
  mfcontent_info = json.load(f)
543
- cls._cached_mfcontent_info[target_dir] = mfcontent_info
538
+ cls._cached_mfcontent_info["_local"] = mfcontent_info
544
539
  return mfcontent_info
545
540
 
546
541
  def get_package_version(self) -> int:
@@ -632,13 +627,13 @@ class MetaflowCodeContentV0(MetaflowCodeContent, version_id=0):
632
627
  return None
633
628
 
634
629
  @classmethod
635
- def get_archive_content_members_impl(
630
+ def get_archive_content_names_impl(
636
631
  cls,
637
632
  mfcontent_info: Optional[Dict[str, Any]],
638
633
  archive: Any,
639
634
  content_types: Optional[int] = None,
640
635
  packaging_backend: Type[PackagingBackend] = TarPackagingBackend,
641
- ) -> List[Any]:
636
+ ) -> List[str]:
642
637
  """
643
638
  For V0, we use a static list of known files to classify the content
644
639
  """
@@ -654,20 +649,16 @@ class MetaflowCodeContentV0(MetaflowCodeContent, version_id=0):
654
649
  "condav2-1.cnd": ContentType.OTHER_CONTENT.value,
655
650
  }
656
651
  to_return = []
657
- for member in packaging_backend.cls_list_members(archive):
658
- filename = packaging_backend.cls_member_name(member)
659
- added = False
652
+ for filename in packaging_backend.cls_list_members(archive):
660
653
  for prefix, classification in known_prefixes.items():
661
654
  if (
662
655
  prefix[-1] == "/" and filename.startswith(prefix)
663
656
  ) or prefix == filename:
664
657
  if content_types & classification:
665
- to_return.append(member)
666
- added = True
667
- break
668
- if not added and content_types & ContentType.USER_CONTENT.value:
669
- # Everything else is user content
670
- to_return.append(member)
658
+ to_return.append(filename)
659
+ elif content_types & ContentType.USER_CONTENT.value:
660
+ # Everything else is user content
661
+ to_return.append(filename)
671
662
  return to_return
672
663
 
673
664
  @classmethod
@@ -714,7 +705,7 @@ class MetaflowCodeContentV1Base(MetaflowCodeContent, version_id=1):
714
705
  cls, mfcontent_info: Optional[Dict[str, Any]], filename: str, in_archive: bool
715
706
  ) -> str:
716
707
  if in_archive:
717
- return os.path.join(cls._other_dir, filename)
708
+ return filename
718
709
  return os.path.join(get_metaflow_root(), "..", cls._other_dir, filename)
719
710
 
720
711
  @classmethod
@@ -722,7 +713,7 @@ class MetaflowCodeContentV1Base(MetaflowCodeContent, version_id=1):
722
713
  cls, mfcontent_info: Optional[Dict[str, Any]], filename: str, in_archive: bool
723
714
  ) -> str:
724
715
  if in_archive:
725
- return os.path.join(cls._code_dir, filename)
716
+ return filename
726
717
  return os.path.join(get_metaflow_root(), filename)
727
718
 
728
719
  @classmethod
@@ -841,38 +832,37 @@ class MetaflowCodeContentV1Base(MetaflowCodeContent, version_id=1):
841
832
  return None
842
833
 
843
834
  @classmethod
844
- def get_archive_content_members_impl(
835
+ def get_archive_content_names_impl(
845
836
  cls,
846
837
  mfcontent_info: Optional[Dict[str, Any]],
847
838
  archive: Any,
848
839
  content_types: Optional[int] = None,
849
840
  packaging_backend: Type[PackagingBackend] = TarPackagingBackend,
850
- ) -> List[Any]:
841
+ ) -> List[str]:
851
842
  to_return = []
852
843
  module_content = set(mfcontent_info.get("module_files", []))
853
- for member in packaging_backend.cls_list_members(archive):
854
- filename = packaging_backend.cls_member_name(member)
844
+ for filename in packaging_backend.cls_list_members(archive):
855
845
  if filename.startswith(cls._other_dir) and (
856
846
  content_types & ContentType.OTHER_CONTENT.value
857
847
  ):
858
- to_return.append(member)
848
+ to_return.append(filename)
859
849
  elif filename.startswith(cls._code_dir):
860
850
  # Special case for marker which is a other content even if in code.
861
- if filename == MFCONTENT_MARKER:
851
+ if filename == f"{cls._code_dir}/{MFCONTENT_MARKER}":
862
852
  if content_types & ContentType.OTHER_CONTENT.value:
863
- to_return.append(member)
853
+ to_return.append(filename)
864
854
  else:
865
855
  continue
866
856
  # Here it is either module or code
867
857
  if os.path.join(cls._code_dir, filename) in module_content:
868
858
  if content_types & ContentType.MODULE_CONTENT.value:
869
- to_return.append(member)
859
+ to_return.append(filename)
870
860
  elif content_types & ContentType.CODE_CONTENT.value:
871
- to_return.append(member)
861
+ to_return.append(filename)
872
862
  else:
873
863
  if content_types & ContentType.USER_CONTENT.value:
874
864
  # Everything else is user content
875
- to_return.append(member)
865
+ to_return.append(filename)
876
866
  return to_return
877
867
 
878
868
  @classmethod
@@ -57,15 +57,6 @@ class PackagingBackend(ABC):
57
57
  """Open the archive from the given content."""
58
58
  pass
59
59
 
60
- @classmethod
61
- @abstractmethod
62
- def cls_member_name(cls, member: Union[Any, str]) -> str:
63
- """
64
- Returns the name of the member as a string.
65
- This is used to ensure consistent naming across different archive formats.
66
- """
67
- pass
68
-
69
60
  @classmethod
70
61
  @abstractmethod
71
62
  def cls_has_member(cls, archive: Any, name: str) -> bool:
@@ -81,20 +72,14 @@ class PackagingBackend(ABC):
81
72
  def cls_extract_members(
82
73
  cls,
83
74
  archive: Any,
84
- members: Optional[List[Any]] = None,
75
+ members: Optional[List[str]] = None,
85
76
  dest_dir: str = ".",
86
77
  ) -> None:
87
78
  pass
88
79
 
89
80
  @classmethod
90
81
  @abstractmethod
91
- def cls_list_names(cls, archive: Any) -> Optional[List[str]]:
92
- pass
93
-
94
- @classmethod
95
- @abstractmethod
96
- def cls_list_members(cls, archive: Any) -> Optional[List[Any]]:
97
- """List all members in the archive."""
82
+ def cls_list_members(cls, archive: Any) -> Optional[List[str]]:
98
83
  pass
99
84
 
100
85
  def has_member(self, name: str) -> bool:
@@ -108,17 +93,17 @@ class PackagingBackend(ABC):
108
93
  raise ValueError("Cannot get member from an uncreated archive")
109
94
 
110
95
  def extract_members(
111
- self, members: Optional[List[Any]] = None, dest_dir: str = "."
96
+ self, members: Optional[List[str]] = None, dest_dir: str = "."
112
97
  ) -> None:
113
98
  if self._archive:
114
99
  self.cls_extract_members(self._archive, members, dest_dir)
115
100
  else:
116
101
  raise ValueError("Cannot extract from an uncreated archive")
117
102
 
118
- def list_names(self) -> Optional[List[str]]:
103
+ def list_members(self) -> Optional[List[str]]:
119
104
  if self._archive:
120
- return self.cls_list_names(self._archive)
121
- raise ValueError("Cannot list names from an uncreated archive")
105
+ return self.cls_list_members(self._archive)
106
+ raise ValueError("Cannot list members from an uncreated archive")
122
107
 
123
108
  def __enter__(self):
124
109
  self.create()
@@ -1,7 +1,7 @@
1
1
  import tarfile
2
2
 
3
3
  from io import BytesIO
4
- from typing import Any, IO, List, Optional, Union
4
+ from typing import IO, List, Optional, Union
5
5
 
6
6
  from .backend import PackagingBackend
7
7
 
@@ -56,13 +56,6 @@ class TarPackagingBackend(PackagingBackend):
56
56
  def cls_open(cls, content: IO[bytes]) -> tarfile.TarFile:
57
57
  return tarfile.open(fileobj=content, mode="r:gz")
58
58
 
59
- @classmethod
60
- def cls_member_name(cls, member: Union[tarfile.TarInfo, str]) -> str:
61
- """
62
- Returns the name of the member as a string.
63
- """
64
- return member.name if isinstance(member, tarfile.TarInfo) else member
65
-
66
59
  @classmethod
67
60
  def cls_has_member(cls, archive: tarfile.TarFile, name: str) -> bool:
68
61
  try:
@@ -83,17 +76,11 @@ class TarPackagingBackend(PackagingBackend):
83
76
  def cls_extract_members(
84
77
  cls,
85
78
  archive: tarfile.TarFile,
86
- members: Optional[List[Any]] = None,
79
+ members: Optional[List[str]] = None,
87
80
  dest_dir: str = ".",
88
81
  ) -> None:
89
82
  archive.extractall(path=dest_dir, members=members)
90
83
 
91
84
  @classmethod
92
- def cls_list_members(
93
- cls, archive: tarfile.TarFile
94
- ) -> Optional[List[tarfile.TarInfo]]:
95
- return archive.getmembers() or None
96
-
97
- @classmethod
98
- def cls_list_names(cls, archive: tarfile.TarFile) -> Optional[List[str]]:
85
+ def cls_list_members(cls, archive: tarfile.TarFile) -> Optional[List[str]]:
99
86
  return archive.getnames() or None
@@ -61,25 +61,23 @@ class MetaflowCodeContentV1(MetaflowCodeContentV1Base):
61
61
  else:
62
62
  new_modules = []
63
63
 
64
- self._modules = {} # type: Dict[str, _ModuleInfo]
65
- # We do this explicitly module by module to harden it against misbehaving
66
- # modules like the one in:
67
- # https://github.com/Netflix/metaflow/issues/2512
68
- # We will silently ignore modules that are not well built.
69
- for name, mod in new_modules:
70
- try:
71
- minfo = _ModuleInfo(
72
- name,
73
- set(
74
- Path(p).resolve().as_posix()
75
- for p in getattr(mod, "__path__", [mod.__file__])
76
- ),
77
- mod,
78
- True, # This is a Metaflow module (see filter below)
79
- )
80
- except:
81
- continue
82
- self._modules[name] = minfo
64
+ self._modules = {
65
+ name: _ModuleInfo(
66
+ name,
67
+ set(
68
+ Path(p).resolve().as_posix()
69
+ for p in getattr(mod, "__path__", [mod.__file__])
70
+ ),
71
+ mod,
72
+ True, # This is a Metaflow module (see filter below)
73
+ )
74
+ for (name, mod) in new_modules
75
+ }
76
+
77
+ # Filter the modules
78
+ self._modules = {
79
+ name: info for name, info in self._modules.items() if criteria(info.module)
80
+ }
83
81
 
84
82
  # Contain metadata information regarding the distributions packaged.
85
83
  # This allows Metaflow to "fake" distribution information when packaged
@@ -357,14 +355,16 @@ class MetaflowCodeContentV1(MetaflowCodeContentV1Base):
357
355
  )
358
356
  yield json.dumps(self.create_mfcontent_info()).encode(
359
357
  "utf-8"
360
- ), MFCONTENT_MARKER
358
+ ), os.path.join(self._code_dir, MFCONTENT_MARKER)
361
359
  else:
362
360
  for k in self._other_content.keys():
363
361
  yield "<generated %s content>" % (os.path.basename(k)), k
364
362
  yield "<generated %s content>" % (
365
363
  os.path.basename(self._dist_info_file)
366
364
  ), os.path.join(self._other_dir, self._dist_info_file)
367
- yield "<generated %s content>" % MFCONTENT_MARKER, MFCONTENT_MARKER
365
+ yield "<generated %s content>" % MFCONTENT_MARKER, os.path.join(
366
+ self._code_dir, MFCONTENT_MARKER
367
+ )
368
368
 
369
369
  def _metaflow_distribution_files(self) -> Generator[Tuple[str, str], None, None]:
370
370
  debug.package_exec("Including Metaflow from '%s'" % self._metaflow_root)
@@ -58,21 +58,38 @@ class ArgoClient(object):
58
58
  json.loads(e.body)["message"] if e.body is not None else e.reason
59
59
  )
60
60
 
61
- def get_workflow_templates(self):
61
+ def get_workflow_templates(self, page_size=100):
62
62
  client = self._client.get()
63
- try:
64
- return client.CustomObjectsApi().list_namespaced_custom_object(
65
- group=self._group,
66
- version=self._version,
67
- namespace=self._namespace,
68
- plural="workflowtemplates",
69
- )["items"]
70
- except client.rest.ApiException as e:
71
- if e.status == 404:
72
- return None
73
- raise ArgoClientException(
74
- json.loads(e.body)["message"] if e.body is not None else e.reason
75
- )
63
+ continue_token = None
64
+
65
+ while True:
66
+ try:
67
+ params = {"limit": page_size}
68
+ if continue_token:
69
+ params["_continue"] = continue_token
70
+
71
+ response = client.CustomObjectsApi().list_namespaced_custom_object(
72
+ group=self._group,
73
+ version=self._version,
74
+ namespace=self._namespace,
75
+ plural="workflowtemplates",
76
+ **params,
77
+ )
78
+
79
+ for item in response.get("items", []):
80
+ yield item
81
+
82
+ metadata = response.get("metadata", {})
83
+ continue_token = metadata.get("continue")
84
+
85
+ if not continue_token:
86
+ break
87
+ except client.rest.ApiException as e:
88
+ if e.status == 404:
89
+ return None
90
+ raise ArgoClientException(
91
+ json.loads(e.body)["message"] if e.body is not None else e.reason
92
+ )
76
93
 
77
94
  def register_workflow_template(self, name, workflow_template):
78
95
  # Unfortunately, Kubernetes client does not handle optimistic