ob-metaflow 2.18.9.2__py2.py3-none-any.whl → 2.18.11.1__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.

@@ -1432,11 +1432,7 @@ class ArgoWorkflows(object):
1432
1432
  dag_tasks.append(dag_task)
1433
1433
  # End the workflow if we have reached the end of the flow
1434
1434
  if node.type == "end":
1435
- return [
1436
- Template(self.flow.name).dag(
1437
- DAGTemplate().fail_fast().tasks(dag_tasks)
1438
- )
1439
- ] + templates, dag_tasks
1435
+ return templates, dag_tasks
1440
1436
  # For split nodes traverse all the children
1441
1437
  if node.type == "split":
1442
1438
  for n in node.out_funcs:
@@ -1559,7 +1555,6 @@ class ArgoWorkflows(object):
1559
1555
  parent_foreach,
1560
1556
  seen,
1561
1557
  )
1562
-
1563
1558
  return _visit(
1564
1559
  self.graph[self._matching_conditional_join(node)],
1565
1560
  exit_node,
@@ -1815,7 +1810,11 @@ class ArgoWorkflows(object):
1815
1810
  for daemon_template in self._daemon_templates()
1816
1811
  ]
1817
1812
 
1818
- templates, _ = _visit(node=self.graph["start"], dag_tasks=daemon_tasks)
1813
+ templates, dag_tasks = _visit(node=self.graph["start"], dag_tasks=daemon_tasks)
1814
+ # Add the DAG template only after fully traversing the graph so we are guaranteed to have all the dag_tasks collected.
1815
+ templates.append(
1816
+ Template(self.flow.name).dag(DAGTemplate().fail_fast().tasks(dag_tasks))
1817
+ )
1819
1818
  return templates
1820
1819
 
1821
1820
  # Visit every node and yield ContainerTemplates.
@@ -2,7 +2,7 @@ import base64
2
2
  import json
3
3
  import os
4
4
  from .card import MetaflowCard, MetaflowCardComponent, with_default_component_id
5
- from .convert_to_native_type import TaskToDict
5
+ from .convert_to_native_type import TaskToDict, MAX_ARTIFACT_SIZE
6
6
  import uuid
7
7
  import inspect
8
8
 
@@ -376,9 +376,14 @@ class TaskInfoComponent(MetaflowCardComponent):
376
376
  components=[],
377
377
  runtime=False,
378
378
  flow=None,
379
+ max_artifact_size=None,
379
380
  ):
380
381
  self._task = task
381
382
  self._only_repr = only_repr
383
+ # Use the global MAX_ARTIFACT_SIZE constant if not specified
384
+ self._max_artifact_size = (
385
+ max_artifact_size if max_artifact_size is not None else MAX_ARTIFACT_SIZE
386
+ )
382
387
  self._graph = graph
383
388
  self._components = components
384
389
  self._page_title = page_title
@@ -394,9 +399,9 @@ class TaskInfoComponent(MetaflowCardComponent):
394
399
  a dictionary of form:
395
400
  dict(metadata = {},components= [])
396
401
  """
397
- task_data_dict = TaskToDict(only_repr=self._only_repr)(
398
- self._task, graph=self._graph
399
- )
402
+ task_data_dict = TaskToDict(
403
+ only_repr=self._only_repr, max_artifact_size=self._max_artifact_size
404
+ )(self._task, graph=self._graph)
400
405
  # ignore the name as an artifact
401
406
  if "name" in task_data_dict["data"]:
402
407
  del task_data_dict["data"]["name"]
@@ -693,10 +698,14 @@ class DefaultCard(MetaflowCard):
693
698
  **kwargs
694
699
  ):
695
700
  self._only_repr = True
701
+ # Default max artifact size uses the global MAX_ARTIFACT_SIZE constant (200MB)
702
+ self._max_artifact_size = MAX_ARTIFACT_SIZE
696
703
  self._graph = None if graph is None else transform_flow_graph(graph)
697
704
  self._flow = flow
698
705
  if "only_repr" in options:
699
706
  self._only_repr = options["only_repr"]
707
+ if "max_artifact_size" in options:
708
+ self._max_artifact_size = options["max_artifact_size"]
700
709
  self._components = components
701
710
 
702
711
  def render(self, task, runtime=False):
@@ -710,6 +719,7 @@ class DefaultCard(MetaflowCard):
710
719
  components=self._components,
711
720
  runtime=runtime,
712
721
  flow=self._flow,
722
+ max_artifact_size=self._max_artifact_size,
713
723
  ).render()
714
724
  pt = self._get_mustache()
715
725
  data_dict = dict(
@@ -8,7 +8,9 @@ TypeResolvedObject = namedtuple("TypeResolvedObject", ["data", "is_image", "is_t
8
8
 
9
9
 
10
10
  TIME_FORMAT = "%Y-%m-%d %I:%M:%S %p"
11
- MAX_ARTIFACT_SIZE = 1 # in 1 MB
11
+ # Maximum artifact size to render in cards: 200MB (in bytes)
12
+ # Artifacts larger than this will be skipped during card rendering to avoid memory issues
13
+ MAX_ARTIFACT_SIZE = 256 * 1024 * 1024 # 256 MB = 268435456 bytes
12
14
 
13
15
 
14
16
  def _get_object_size(obj, seen=None):
@@ -44,7 +46,7 @@ def _full_classname(obj):
44
46
 
45
47
 
46
48
  class TaskToDict:
47
- def __init__(self, only_repr=False, runtime=False):
49
+ def __init__(self, only_repr=False, runtime=False, max_artifact_size=None):
48
50
  # this dictionary holds all the supported functions
49
51
  import reprlib
50
52
  import pprint
@@ -61,6 +63,10 @@ class TaskToDict:
61
63
  self._repr = r
62
64
  self._runtime = runtime
63
65
  self._only_repr = only_repr
66
+ # Use the global MAX_ARTIFACT_SIZE constant if not specified
67
+ self._max_artifact_size = (
68
+ max_artifact_size if max_artifact_size is not None else MAX_ARTIFACT_SIZE
69
+ )
64
70
  self._supported_types = {
65
71
  "tuple": self._parse_tuple,
66
72
  "NoneType": self._parse_nonetype,
@@ -110,6 +116,19 @@ class TaskToDict:
110
116
  task_data_dict = {}
111
117
  type_inferred_objects = {"images": {}, "tables": {}}
112
118
  for data in task:
119
+ # Check if artifact size exceeds the maximum allowed size
120
+ if data.size > self._max_artifact_size:
121
+ # Skip artifacts that are too large
122
+ task_data_dict[data.id] = dict(
123
+ type="skipped",
124
+ data=f"<artifact too large: {data.size} bytes, max: {self._max_artifact_size} bytes>",
125
+ large_object=True,
126
+ supported_type=False,
127
+ only_repr=self._only_repr,
128
+ name=data.id,
129
+ )
130
+ continue
131
+
113
132
  try:
114
133
  data_object = data.data
115
134
  task_data_dict[data.id] = self._convert_to_native_type(data_object)
@@ -241,7 +260,8 @@ class TaskToDict:
241
260
  supported_type = True
242
261
  type_parsing_func = self._supported_types[obj_type_name]
243
262
  data_obj = type_parsing_func(data_object)
244
- if _get_object_size(data_obj) * 1e-6 > MAX_ARTIFACT_SIZE:
263
+ # Secondary check: if the in-memory object size exceeds our limit, use repr instead
264
+ if _get_object_size(data_obj) > self._max_artifact_size:
245
265
  data_obj = rep.repr(data_obj)
246
266
  large_object = True
247
267
  else:
@@ -595,11 +595,23 @@ class S3Ops(object):
595
595
  # - the trailing slash is significant in S3
596
596
  if "Contents" in page:
597
597
  for key in page.get("Contents", []):
598
- url = url_base + key["Key"]
598
+ key_path = key["Key"]
599
+ # filter out sibling directories that share the same prefix
600
+ if delimiter == "": # recursive mode
601
+ normalized_prefix = prefix_url.path
602
+ if not normalized_prefix.endswith("/"):
603
+ normalized_prefix += "/"
604
+ # Only include keys that are actually under our directory
605
+ if not (
606
+ key_path.startswith(normalized_prefix)
607
+ and len(key_path) > len(normalized_prefix)
608
+ ):
609
+ continue
610
+ url = url_base + key_path
599
611
  urlobj = S3Url(
600
612
  url=url,
601
613
  bucket=prefix_url.bucket,
602
- path=key["Key"],
614
+ path=key_path,
603
615
  local=generate_local_path(url),
604
616
  prefix=prefix_url.url,
605
617
  )
metaflow/version.py CHANGED
@@ -1 +1 @@
1
- metaflow_version = "2.18.9.2"
1
+ metaflow_version = "2.18.11.1"
@@ -184,6 +184,7 @@ if "postgresql" in enabled_components:
184
184
  'auth.username=metaflow',
185
185
  'auth.password=metaflow123',
186
186
  'auth.database=metaflow',
187
+ 'image.repository=bitnamilegacy/postgresql',
187
188
  'primary.persistence.enabled=false',
188
189
  'primary.resources.requests.memory=128Mi',
189
190
  'primary.resources.requests.cpu=50m',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-metaflow
3
- Version: 2.18.9.2
3
+ Version: 2.18.11.1
4
4
  Summary: Metaflow: More AI and ML, 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.18.9.2; extra == "stubs"
15
+ Requires-Dist: metaflow-stubs==2.18.11.1; extra == "stubs"
16
16
  Dynamic: author
17
17
  Dynamic: author-email
18
18
  Dynamic: description
@@ -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=g2SOU_CRzJLgDM_UGF9QDMANMAIHAsDRXE6S76_YzsY,14594
38
38
  metaflow/vendor.py,sha256=A82CGHfStZGDP5pQ5XzRjFkbN1ZC-vFmghXIrzMDDNg,5868
39
- metaflow/version.py,sha256=v3BiQkfwhteu76nlVn2CMPuZiLxVVQA_UzQ3UDaUaBg,30
39
+ metaflow/version.py,sha256=-QMcj4sefonvKRf-aiZY-QSxNx7uwC6eRdhHcerk6Tw,31
40
40
  metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
41
41
  metaflow/_vendor/typing_extensions.py,sha256=q9zxWa6p6CzF1zZvSkygSlklduHf_b3K7MCxGz7MJRc,134519
42
42
  metaflow/_vendor/zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425
@@ -231,7 +231,7 @@ metaflow/plugins/airflow/sensors/s3_sensor.py,sha256=iDReG-7FKnumrtQg-HY6cCUAAqN
231
231
  metaflow/plugins/argo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
232
232
  metaflow/plugins/argo/argo_client.py,sha256=oT4ZrCyE7CYEbqNN0SfoZfSHd5fYW9XtuOrQEiUd1co,17230
233
233
  metaflow/plugins/argo/argo_events.py,sha256=_C1KWztVqgi3zuH57pInaE9OzABc2NnncC-zdwOMZ-w,5909
234
- metaflow/plugins/argo/argo_workflows.py,sha256=GNTckkqlT6t-In-153xEVdw6WUWNYDLXoYT3gDCrXyY,218304
234
+ metaflow/plugins/argo/argo_workflows.py,sha256=Kb2e6XkUegQ_j9cPLk9Tp-ASlc48-cuigaH5_KOc3WA,218398
235
235
  metaflow/plugins/argo/argo_workflows_cli.py,sha256=-blfZp-kAS8oWFTarfou9gRyE4QCnnJwa-0g8QuE0zk,52280
236
236
  metaflow/plugins/argo/argo_workflows_decorator.py,sha256=CLSjPqFTGucZ2_dSQGAYkoWWUZBQ9TCBXul4rxhDj3w,8282
237
237
  metaflow/plugins/argo/argo_workflows_deployer.py,sha256=6kHxEnYXJwzNCM9swI8-0AckxtPWqwhZLerYkX8fxUM,4444
@@ -284,11 +284,11 @@ metaflow/plugins/cards/exception.py,sha256=2UqlNb-Kxpg6cuLu2sBEIPTIElwlVBsSpeCgD
284
284
  metaflow/plugins/cards/metadata.py,sha256=tACaw7_XNAICZ4A25celIbgxUF0CxHh7BBpFzKrMLTo,487
285
285
  metaflow/plugins/cards/card_modules/__init__.py,sha256=WI2IAsFiKGyqPrHtO9S9-MbyVtUTgWJNL4xjJaBErRo,3437
286
286
  metaflow/plugins/cards/card_modules/base.html,sha256=Y208ZKIZqEWWUcoBFTLTdWKAG0C8xH5lmyCRSjaN2FY,21004
287
- metaflow/plugins/cards/card_modules/basic.py,sha256=b6aBg7800CjjkQb0J_TOd3JujVR10X2QoXYdwiXFbkE,25831
287
+ metaflow/plugins/cards/card_modules/basic.py,sha256=bKU_b_Wfs2OC6me6kPp1Jm_SLvaJ4dkUCMAt2VLampk,26430
288
288
  metaflow/plugins/cards/card_modules/bundle.css,sha256=zlYjv5rt7lMqiQzd_OAe4QdQeM3J3YbwljnEghlbTaU,28052
289
289
  metaflow/plugins/cards/card_modules/card.py,sha256=6sbqP5mwf7QWvQvX2N_bC78H9ixuI5sQ8612Q5islys,4627
290
290
  metaflow/plugins/cards/card_modules/components.py,sha256=hF204MUyJ2DZXSPhEt7d23isjdEf4TGK8pzmVkmXyQ0,45574
291
- metaflow/plugins/cards/card_modules/convert_to_native_type.py,sha256=Vcjqn5rfC0kVMdhqDwsYEjknXTbkG_ppraQrQGaQY_E,16245
291
+ metaflow/plugins/cards/card_modules/convert_to_native_type.py,sha256=opjGOvWg7trOqzhTRZ7h1cFlYrNj68Wn3_EyDTIKEvw,17320
292
292
  metaflow/plugins/cards/card_modules/json_viewer.py,sha256=DWOcQPk6DXbeGuYEqv1gGrQW1eMVYlCXv3kMsVLnhNc,7113
293
293
  metaflow/plugins/cards/card_modules/main.css,sha256=avu7BTB9qj0M8LvqNLUhikUFQhmAJhQQ7REcUgh9zMw,11725
294
294
  metaflow/plugins/cards/card_modules/main.js,sha256=wT4PhcwoFwVNOGVZYBkjqfYKROuPSPWGjS-zCQZErz8,1075727
@@ -309,7 +309,7 @@ metaflow/plugins/datatools/__init__.py,sha256=ge4L16OBQLy2J_MMvoHg3lMfdm-MluQgRW
309
309
  metaflow/plugins/datatools/local.py,sha256=FJvMOBcjdyhSPHmdLocBSiIT0rmKkKBmsaclxH75x08,4233
310
310
  metaflow/plugins/datatools/s3/__init__.py,sha256=14tr9fPjN3ULW5IOfKHeG7Uhjmgm7LMtQHfz1SFv-h8,248
311
311
  metaflow/plugins/datatools/s3/s3.py,sha256=b07QwYvfKvR1k0eZ_b5Hk4XQnQs3ORk6b0nvCwfZL8w,67324
312
- metaflow/plugins/datatools/s3/s3op.py,sha256=3GOtIV08gmAo7XE6NNnsSUxTTRIsvgPJn7CC0U5E7XY,48129
312
+ metaflow/plugins/datatools/s3/s3op.py,sha256=WFHEnsNZLEak-OEAJiwayEFm5d36JUbnV5QXxfbrO1s,48847
313
313
  metaflow/plugins/datatools/s3/s3tail.py,sha256=boQjQGQMI-bvTqcMP2y7uSlSYLcvWOy7J3ZUaF78NAA,2597
314
314
  metaflow/plugins/datatools/s3/s3util.py,sha256=FgRgaVmEq7-i2dV7q8XK5w5PfFt-xJjZa8WrK8IJfdI,3769
315
315
  metaflow/plugins/env_escape/__init__.py,sha256=tGNUZnmPvk52eNs__VK443b3CZ7ogEFTT-s9_n_HF8Q,8837
@@ -430,12 +430,12 @@ metaflow/user_decorators/mutable_flow.py,sha256=EywKTN3cnXPQF_s62wQaC4a4aH14j8oe
430
430
  metaflow/user_decorators/mutable_step.py,sha256=-BY0UDXf_RCAEnC5JlLzEXGdiw1KD9oSrSxS_SWaB9Y,16791
431
431
  metaflow/user_decorators/user_flow_decorator.py,sha256=2yDwZq9QGv9W-7kEuKwa8o4ZkTvuHJ5ESz7VVrGViAI,9890
432
432
  metaflow/user_decorators/user_step_decorator.py,sha256=4558NR8RJtN22OyTwCXO80bAMhMTaRGMoX12b1GMcPc,27232
433
- ob_metaflow-2.18.9.2.data/data/share/metaflow/devtools/Makefile,sha256=TT4TCq8ALSfqYyGqDPocN5oPcZe2FqoCZxmGO1LmyCc,13760
434
- ob_metaflow-2.18.9.2.data/data/share/metaflow/devtools/Tiltfile,sha256=8-VMYGdEBFp73Ur5BzQn7TxxkMBMhwJszsVhR_ftgBU,23892
435
- ob_metaflow-2.18.9.2.data/data/share/metaflow/devtools/pick_services.sh,sha256=PGjQeDIigFHeoQ0asmYNdYDPIOdeYy1UYvkw2wdN4zg,2209
436
- ob_metaflow-2.18.9.2.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
437
- ob_metaflow-2.18.9.2.dist-info/METADATA,sha256=hzoPGQGmjO9vH6jHV47B9mmelVBsiYr69Qf5fqlNnwE,5936
438
- ob_metaflow-2.18.9.2.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
439
- ob_metaflow-2.18.9.2.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
440
- ob_metaflow-2.18.9.2.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
441
- ob_metaflow-2.18.9.2.dist-info/RECORD,,
433
+ ob_metaflow-2.18.11.1.data/data/share/metaflow/devtools/Makefile,sha256=TT4TCq8ALSfqYyGqDPocN5oPcZe2FqoCZxmGO1LmyCc,13760
434
+ ob_metaflow-2.18.11.1.data/data/share/metaflow/devtools/Tiltfile,sha256=b6l_fjDO0wtxOkO85lFvuf3HDa6wnzHhhBG8yv1kQqk,23949
435
+ ob_metaflow-2.18.11.1.data/data/share/metaflow/devtools/pick_services.sh,sha256=PGjQeDIigFHeoQ0asmYNdYDPIOdeYy1UYvkw2wdN4zg,2209
436
+ ob_metaflow-2.18.11.1.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
437
+ ob_metaflow-2.18.11.1.dist-info/METADATA,sha256=L3lcj1C3TYV_pPa11ISO5nmDzumf-cYbY7WXrWI1Ouk,5938
438
+ ob_metaflow-2.18.11.1.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
439
+ ob_metaflow-2.18.11.1.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
440
+ ob_metaflow-2.18.11.1.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
441
+ ob_metaflow-2.18.11.1.dist-info/RECORD,,