metaflow 2.11.12__py2.py3-none-any.whl → 2.11.13__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.
@@ -314,6 +314,10 @@ KUBERNETES_FETCH_EC2_METADATA = from_conf("KUBERNETES_FETCH_EC2_METADATA", False
314
314
  KUBERNETES_SHARED_MEMORY = from_conf("KUBERNETES_SHARED_MEMORY", None)
315
315
  # Default port number to open on the pods
316
316
  KUBERNETES_PORT = from_conf("KUBERNETES_PORT", None)
317
+ # Default kubernetes resource requests for CPU, memory and disk
318
+ KUBERNETES_CPU = from_conf("KUBERNETES_CPU", None)
319
+ KUBERNETES_MEMORY = from_conf("KUBERNETES_MEMORY", None)
320
+ KUBERNETES_DISK = from_conf("KUBERNETES_DISK", None)
317
321
 
318
322
  ARGO_WORKFLOWS_KUBERNETES_SECRETS = from_conf("ARGO_WORKFLOWS_KUBERNETES_SECRETS", "")
319
323
  ARGO_WORKFLOWS_ENV_VARS_TO_SKIP = from_conf("ARGO_WORKFLOWS_ENV_VARS_TO_SKIP", "")
@@ -835,7 +835,9 @@ class ArgoWorkflows(object):
835
835
 
836
836
  # Visit every node and yield the uber DAGTemplate(s).
837
837
  def _dag_templates(self):
838
- def _visit(node, exit_node=None, templates=None, dag_tasks=None):
838
+ def _visit(
839
+ node, exit_node=None, templates=None, dag_tasks=None, parent_foreach=None
840
+ ):
839
841
  # Every for-each node results in a separate subDAG and an equivalent
840
842
  # DAGTemplate rooted at the child of the for-each node. Each DAGTemplate
841
843
  # has a unique name - the top-level DAGTemplate is named as the name of
@@ -883,6 +885,37 @@ class ArgoWorkflows(object):
883
885
  )
884
886
  )
885
887
  ]
888
+ # NOTE: Due to limitations with Argo Workflows Parameter size we
889
+ # can not pass arbitrarily large lists of task id's to join tasks.
890
+ # Instead we ensure that task id's for foreach tasks can be
891
+ # deduced deterministically and pass the relevant information to
892
+ # the join task.
893
+ #
894
+ # We need to add the split-index and root-input-path for the last
895
+ # step in any foreach scope and use these to generate the task id,
896
+ # as the join step uses the root and the cardinality of the
897
+ # foreach scope to generate the required id's.
898
+ if (
899
+ node.is_inside_foreach
900
+ and self.graph[node.out_funcs[0]].type == "join"
901
+ ):
902
+ if any(
903
+ self.graph[parent].matching_join
904
+ == self.graph[node.out_funcs[0]].name
905
+ and self.graph[parent].type == "foreach"
906
+ for parent in self.graph[node.out_funcs[0]].split_parents
907
+ ):
908
+ parameters.extend(
909
+ [
910
+ Parameter("split-index").value(
911
+ "{{inputs.parameters.split-index}}"
912
+ ),
913
+ Parameter("root-input-path").value(
914
+ "{{inputs.parameters.input-paths}}"
915
+ ),
916
+ ]
917
+ )
918
+
886
919
  dag_task = (
887
920
  DAGTask(self._sanitize(node.name))
888
921
  .dependencies(
@@ -903,9 +936,19 @@ class ArgoWorkflows(object):
903
936
  # For split nodes traverse all the children
904
937
  if node.type == "split":
905
938
  for n in node.out_funcs:
906
- _visit(self.graph[n], node.matching_join, templates, dag_tasks)
939
+ _visit(
940
+ self.graph[n],
941
+ node.matching_join,
942
+ templates,
943
+ dag_tasks,
944
+ parent_foreach,
945
+ )
907
946
  return _visit(
908
- self.graph[node.matching_join], exit_node, templates, dag_tasks
947
+ self.graph[node.matching_join],
948
+ exit_node,
949
+ templates,
950
+ dag_tasks,
951
+ parent_foreach,
909
952
  )
910
953
  # For foreach nodes generate a new sub DAGTemplate
911
954
  elif node.type == "foreach":
@@ -929,6 +972,16 @@ class ArgoWorkflows(object):
929
972
  ),
930
973
  Parameter("split-index").value("{{item}}"),
931
974
  ]
975
+ + (
976
+ [
977
+ Parameter("root-input-path").value(
978
+ "argo-{{workflow.name}}/%s/{{tasks.%s.outputs.parameters.task-id}}"
979
+ % (node.name, self._sanitize(node.name))
980
+ ),
981
+ ]
982
+ if parent_foreach
983
+ else []
984
+ )
932
985
  )
933
986
  )
934
987
  .with_param(
@@ -938,13 +991,18 @@ class ArgoWorkflows(object):
938
991
  )
939
992
  dag_tasks.append(foreach_task)
940
993
  templates, dag_tasks_1 = _visit(
941
- self.graph[node.out_funcs[0]], node.matching_join, templates, []
994
+ self.graph[node.out_funcs[0]],
995
+ node.matching_join,
996
+ templates,
997
+ [],
998
+ node.name,
942
999
  )
943
1000
  templates.append(
944
1001
  Template(foreach_template_name)
945
1002
  .inputs(
946
1003
  Inputs().parameters(
947
1004
  [Parameter("input-paths"), Parameter("split-index")]
1005
+ + ([Parameter("root-input-path")] if parent_foreach else [])
948
1006
  )
949
1007
  )
950
1008
  .outputs(
@@ -971,13 +1029,26 @@ class ArgoWorkflows(object):
971
1029
  Arguments().parameters(
972
1030
  [
973
1031
  Parameter("input-paths").value(
974
- "argo-{{workflow.name}}/%s/{{tasks.%s.outputs.parameters}}"
975
- % (
976
- self.graph[node.matching_join].in_funcs[-1],
977
- foreach_template_name,
978
- )
979
- )
1032
+ "argo-{{workflow.name}}/%s/{{tasks.%s.outputs.parameters.task-id}}"
1033
+ % (node.name, self._sanitize(node.name))
1034
+ ),
1035
+ Parameter("split-cardinality").value(
1036
+ "{{tasks.%s.outputs.parameters.split-cardinality}}"
1037
+ % self._sanitize(node.name)
1038
+ ),
980
1039
  ]
1040
+ + (
1041
+ [
1042
+ Parameter("split-index").value(
1043
+ "{{inputs.parameters.split-index}}"
1044
+ ),
1045
+ Parameter("root-input-path").value(
1046
+ "{{inputs.parameters.input-paths}}"
1047
+ ),
1048
+ ]
1049
+ if parent_foreach
1050
+ else []
1051
+ )
981
1052
  )
982
1053
  )
983
1054
  )
@@ -987,11 +1058,16 @@ class ArgoWorkflows(object):
987
1058
  exit_node,
988
1059
  templates,
989
1060
  dag_tasks,
1061
+ parent_foreach,
990
1062
  )
991
1063
  # For linear nodes continue traversing to the next node
992
1064
  if node.type in ("linear", "join", "start"):
993
1065
  return _visit(
994
- self.graph[node.out_funcs[0]], exit_node, templates, dag_tasks
1066
+ self.graph[node.out_funcs[0]],
1067
+ exit_node,
1068
+ templates,
1069
+ dag_tasks,
1070
+ parent_foreach,
995
1071
  )
996
1072
  else:
997
1073
  raise ArgoWorkflowsException(
@@ -1034,11 +1110,43 @@ class ArgoWorkflows(object):
1034
1110
  # Ideally, we would like these task ids to be the same as node name
1035
1111
  # (modulo retry suffix) on Argo Workflows but that doesn't seem feasible
1036
1112
  # right now.
1037
- task_str = node.name + "-{{workflow.creationTimestamp}}"
1113
+
1114
+ task_idx = ""
1115
+ input_paths = ""
1116
+ root_input = None
1117
+ # export input_paths as it is used multiple times in the container script
1118
+ # and we do not want to repeat the values.
1119
+ input_paths_expr = "export INPUT_PATHS=''"
1038
1120
  if node.name != "start":
1039
- task_str += "-{{inputs.parameters.input-paths}}"
1121
+ input_paths_expr = (
1122
+ "export INPUT_PATHS={{inputs.parameters.input-paths}}"
1123
+ )
1124
+ input_paths = "$(echo $INPUT_PATHS)"
1040
1125
  if any(self.graph[n].type == "foreach" for n in node.in_funcs):
1041
- task_str += "-{{inputs.parameters.split-index}}"
1126
+ task_idx = "{{inputs.parameters.split-index}}"
1127
+ if node.is_inside_foreach and self.graph[node.out_funcs[0]].type == "join":
1128
+ if any(
1129
+ self.graph[parent].matching_join
1130
+ == self.graph[node.out_funcs[0]].name
1131
+ for parent in self.graph[node.out_funcs[0]].split_parents
1132
+ if self.graph[parent].type == "foreach"
1133
+ ) and any(not self.graph[f].type == "foreach" for f in node.in_funcs):
1134
+ # we need to propagate the split-index and root-input-path info for
1135
+ # the last step inside a foreach for correctly joining nested
1136
+ # foreaches
1137
+ task_idx = "{{inputs.parameters.split-index}}"
1138
+ root_input = "{{inputs.parameters.root-input-path}}"
1139
+
1140
+ # Task string to be hashed into an ID
1141
+ task_str = "-".join(
1142
+ [
1143
+ node.name,
1144
+ "{{workflow.creationTimestamp}}",
1145
+ root_input or input_paths,
1146
+ task_idx,
1147
+ ]
1148
+ )
1149
+
1042
1150
  # Generated task_ids need to be non-numeric - see register_task_id in
1043
1151
  # service.py. We do so by prefixing `t-`
1044
1152
  task_id_expr = (
@@ -1087,6 +1195,7 @@ class ArgoWorkflows(object):
1087
1195
  # env var.
1088
1196
  '${METAFLOW_INIT_SCRIPT:+eval \\"${METAFLOW_INIT_SCRIPT}\\"}',
1089
1197
  "mkdir -p $PWD/.logs",
1198
+ input_paths_expr,
1090
1199
  task_id_expr,
1091
1200
  mflog_expr,
1092
1201
  ]
@@ -1098,8 +1207,6 @@ class ArgoWorkflows(object):
1098
1207
  node.name, self.flow_datastore.TYPE
1099
1208
  )
1100
1209
 
1101
- input_paths = "{{inputs.parameters.input-paths}}"
1102
-
1103
1210
  top_opts_dict = {
1104
1211
  "with": [
1105
1212
  decorator.make_decorator_spec()
@@ -1168,10 +1275,16 @@ class ArgoWorkflows(object):
1168
1275
  node.type == "join"
1169
1276
  and self.graph[node.split_parents[-1]].type == "foreach"
1170
1277
  ):
1171
- # Set aggregated input-paths for a foreach-join
1278
+ # Set aggregated input-paths for a for-each join
1279
+ foreach_step = next(
1280
+ n for n in node.in_funcs if self.graph[n].is_inside_foreach
1281
+ )
1172
1282
  input_paths = (
1173
- "$(python -m metaflow.plugins.argo.process_input_paths %s)"
1174
- % input_paths
1283
+ "$(python -m metaflow.plugins.argo.generate_input_paths %s {{workflow.creationTimestamp}} %s {{inputs.parameters.split-cardinality}})"
1284
+ % (
1285
+ foreach_step,
1286
+ input_paths,
1287
+ )
1175
1288
  )
1176
1289
  step = [
1177
1290
  "step",
@@ -1337,13 +1450,37 @@ class ArgoWorkflows(object):
1337
1450
  # input. Analogously, if the node under consideration is a foreach
1338
1451
  # node, then we emit split cardinality as an extra output. I would like
1339
1452
  # to thank the designers of Argo Workflows for making this so
1340
- # straightforward!
1453
+ # straightforward! Things become a bit more complicated to support very
1454
+ # wide foreaches where we have to resort to passing a root-input-path
1455
+ # so that we can compute the task ids for each parent task of a for-each
1456
+ # join task deterministically inside the join task without resorting to
1457
+ # passing a rather long list of (albiet compressed)
1341
1458
  inputs = []
1342
1459
  if node.name != "start":
1343
1460
  inputs.append(Parameter("input-paths"))
1344
1461
  if any(self.graph[n].type == "foreach" for n in node.in_funcs):
1345
1462
  # Fetch split-index from parent
1346
1463
  inputs.append(Parameter("split-index"))
1464
+ if (
1465
+ node.type == "join"
1466
+ and self.graph[node.split_parents[-1]].type == "foreach"
1467
+ ):
1468
+ # append this only for joins of foreaches, not static splits
1469
+ inputs.append(Parameter("split-cardinality"))
1470
+ if node.is_inside_foreach and self.graph[node.out_funcs[0]].type == "join":
1471
+ if any(
1472
+ self.graph[parent].matching_join
1473
+ == self.graph[node.out_funcs[0]].name
1474
+ for parent in self.graph[node.out_funcs[0]].split_parents
1475
+ if self.graph[parent].type == "foreach"
1476
+ ) and any(not self.graph[f].type == "foreach" for f in node.in_funcs):
1477
+ # we need to propagate the split-index and root-input-path info for
1478
+ # the last step inside a foreach for correctly joining nested
1479
+ # foreaches
1480
+ if not any(self.graph[n].type == "foreach" for n in node.in_funcs):
1481
+ # Don't add duplicate split index parameters.
1482
+ inputs.append(Parameter("split-index"))
1483
+ inputs.append(Parameter("root-input-path"))
1347
1484
 
1348
1485
  outputs = []
1349
1486
  if node.name != "end":
@@ -1353,6 +1490,11 @@ class ArgoWorkflows(object):
1353
1490
  outputs.append(
1354
1491
  Parameter("num-splits").valueFrom({"path": "/mnt/out/splits"})
1355
1492
  )
1493
+ outputs.append(
1494
+ Parameter("split-cardinality").valueFrom(
1495
+ {"path": "/mnt/out/split_cardinality"}
1496
+ )
1497
+ )
1356
1498
 
1357
1499
  # It makes no sense to set env vars to None (shows up as "None" string)
1358
1500
  # Also we skip some env vars (e.g. in case we want to pull them from KUBERNETES_SECRETS)
@@ -102,6 +102,9 @@ class ArgoWorkflowsInternalDecorator(StepDecorator):
102
102
  if graph[step_name].type == "foreach":
103
103
  with open("/mnt/out/splits", "w") as file:
104
104
  json.dump(list(range(flow._foreach_num_splits)), file)
105
+ with open("/mnt/out/split_cardinality", "w") as file:
106
+ json.dump(flow._foreach_num_splits, file)
107
+
105
108
  # Unfortunately, we can't always use pod names as task-ids since the pod names
106
109
  # are not static across retries. We write the task-id to a file that is read
107
110
  # by the next task here.
@@ -0,0 +1,23 @@
1
+ import sys
2
+ from hashlib import md5
3
+
4
+
5
+ def generate_input_paths(step_name, timestamp, input_paths, split_cardinality):
6
+ # => run_id/step/:foo,bar
7
+ run_id = input_paths.split("/")[0]
8
+ foreach_base_id = "{}-{}-{}".format(step_name, timestamp, input_paths)
9
+
10
+ ids = [_generate_task_id(foreach_base_id, i) for i in range(int(split_cardinality))]
11
+ return "{}/{}/:{}".format(run_id, step_name, ",".join(ids))
12
+
13
+
14
+ def _generate_task_id(base, idx):
15
+ # For foreach splits generate the expected input-paths based on split_cardinality and base_id.
16
+ # newline required at the end due to 'echo' appending one in the shell side task_id creation.
17
+ task_str = "%s-%s\n" % (base, idx)
18
+ hash = md5(task_str.encode("utf-8")).hexdigest()[-8:]
19
+ return "t-" + hash
20
+
21
+
22
+ if __name__ == "__main__":
23
+ print(generate_input_paths(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]))
@@ -1626,6 +1626,7 @@ class S3(object):
1626
1626
  # Run the operation.
1627
1627
  env = os.environ.copy()
1628
1628
  tracing.inject_tracing_vars(env)
1629
+ env["METAFLOW_ESCAPE_HATCH_WARNING"] = "False"
1629
1630
  stdout = subprocess.check_output(
1630
1631
  cmdline + addl_cmdline,
1631
1632
  cwd=self._tmpdir,
@@ -22,6 +22,9 @@ from metaflow.metaflow_config import (
22
22
  KUBERNETES_SERVICE_ACCOUNT,
23
23
  KUBERNETES_SHARED_MEMORY,
24
24
  KUBERNETES_PORT,
25
+ KUBERNETES_CPU,
26
+ KUBERNETES_MEMORY,
27
+ KUBERNETES_DISK,
25
28
  )
26
29
  from metaflow.plugins.resources_decorator import ResourcesDecorator
27
30
  from metaflow.plugins.timeout_decorator import get_run_time_limit_for_task
@@ -174,6 +177,15 @@ class KubernetesDecorator(StepDecorator):
174
177
  except (NameError, ImportError):
175
178
  pass
176
179
 
180
+ # parse the CPU, memory, disk, values from the KUBERNETES_ environment variable (you would need to export the METAFLOW_KUBERNETES_CPU, METAFLOW_KUBERNETES_MEMORY and/or METAFLOW_KUBERNTES_DISK environment variable with the desired values before running the flow)
181
+ # find the values from the environment variables, then validate if the values are still the default ones, if so, then replace them with the values from the environment variables (otherwise, keep the values from the decorator)
182
+ if self.attributes["cpu"] == self.defaults["cpu"] and KUBERNETES_CPU:
183
+ self.attributes["cpu"] = KUBERNETES_CPU
184
+ if self.attributes["memory"] == self.defaults["memory"] and KUBERNETES_MEMORY:
185
+ self.attributes["memory"] = KUBERNETES_MEMORY
186
+ if self.attributes["disk"] == self.defaults["disk"] and KUBERNETES_DISK:
187
+ self.attributes["disk"] = KUBERNETES_DISK
188
+
177
189
  # If no docker image is explicitly specified, impute a default image.
178
190
  if not self.attributes["image"]:
179
191
  # If metaflow-config specifies a docker image, just use that.
metaflow/version.py CHANGED
@@ -1 +1 @@
1
- metaflow_version = "2.11.12"
1
+ metaflow_version = "2.11.13"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: metaflow
3
- Version: 2.11.12
3
+ Version: 2.11.13
4
4
  Summary: Metaflow: More Data Science, Less Engineering
5
5
  Author: Metaflow Developers
6
6
  Author-email: help@metaflow.org
@@ -26,7 +26,7 @@ License-File: LICENSE
26
26
  Requires-Dist: requests
27
27
  Requires-Dist: boto3
28
28
  Provides-Extra: stubs
29
- Requires-Dist: metaflow-stubs ==2.11.12 ; extra == 'stubs'
29
+ Requires-Dist: metaflow-stubs ==2.11.13 ; extra == 'stubs'
30
30
 
31
31
  ![Metaflow_Logo_Horizontal_FullColor_Ribbon_Dark_RGB](https://user-images.githubusercontent.com/763451/89453116-96a57e00-d713-11ea-9fa6-82b29d4d6eff.png)
32
32
 
@@ -15,7 +15,7 @@ metaflow/graph.py,sha256=ZPxyG8uwVMk5YYgX4pQEQaPZtZM5Wy-G4NtJK73IEuA,11818
15
15
  metaflow/includefile.py,sha256=yHczcZ_U0SrasxSNhZb3DIBzx8UZnrJCl3FzvpEQLOA,19753
16
16
  metaflow/integrations.py,sha256=LlsaoePRg03DjENnmLxZDYto3NwWc9z_PtU6nJxLldg,1480
17
17
  metaflow/lint.py,sha256=_kYAbAtsP7IG1Rd0FqNbo8I8Zs66_0WXbaZJFARO3dE,10394
18
- metaflow/metaflow_config.py,sha256=X3YbYipCTA5ObumydxQXrgZZerOFlUngnTjHW9wOvtI,20043
18
+ metaflow/metaflow_config.py,sha256=gPFjbtfhAiByGD91NyztyQ5AkuBR_vGcSOPc2hsXNp0,20268
19
19
  metaflow/metaflow_config_funcs.py,sha256=pCaiQ2ez9wXixJI3ehmf3QiW9lUqFrZnBZx1my_0wIg,4874
20
20
  metaflow/metaflow_current.py,sha256=sCENPBiji3LcPbwgOG0ukGd_yEc5tST8EowES8DzRtA,7430
21
21
  metaflow/metaflow_environment.py,sha256=JdsmQsYp1SDQniQ0-q1mKRrmzSFfYuzrf6jLEHmyaiM,7352
@@ -34,7 +34,7 @@ metaflow/task.py,sha256=ecGaULbK8kXPnyWzH1u6wtGclm0qeJm7K95amEL17sQ,25863
34
34
  metaflow/unbounded_foreach.py,sha256=p184WMbrMJ3xKYHwewj27ZhRUsSj_kw1jlye5gA9xJk,387
35
35
  metaflow/util.py,sha256=RrjsvADLKxSqjL76CxKh_J4OJl840B9Ak3V-vXleGas,13429
36
36
  metaflow/vendor.py,sha256=LZgXrh7ZSDmD32D1T5jj3OKKpXIqqxKzdMAOc5V0SD4,5162
37
- metaflow/version.py,sha256=xc9RGVTlcPv4YdjEJQkhp1o3HJkzjUbLq8GEQhX6-3Q,29
37
+ metaflow/version.py,sha256=xYoPiP-fhmJPU0HYJ1VLpv5UnAhbTqBSpY-d72X5rzs,29
38
38
  metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
39
39
  metaflow/_vendor/click/__init__.py,sha256=FkyGDQ-cbiQxP_lxgUspyFYS48f2S_pTcfKPz-d_RMo,2463
40
40
  metaflow/_vendor/click/_bashcomplete.py,sha256=9J98IHQYmCAr2Jup6TDshUr5FJEen-AoQCZR0K5nKxQ,12309
@@ -149,10 +149,10 @@ metaflow/plugins/airflow/sensors/s3_sensor.py,sha256=JUKoGNoTCtrO9MNEneEC7ldRNwg
149
149
  metaflow/plugins/argo/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
150
150
  metaflow/plugins/argo/argo_client.py,sha256=MKKhMCbWOPzf6z5zQQiyDRHHkAXcO7ipboDZDqAAvOk,15849
151
151
  metaflow/plugins/argo/argo_events.py,sha256=_C1KWztVqgi3zuH57pInaE9OzABc2NnncC-zdwOMZ-w,5909
152
- metaflow/plugins/argo/argo_workflows.py,sha256=ufub5eTXZS9idWbVl37PW2vmbYsNxXYpVTw3hByrzrE,122350
152
+ metaflow/plugins/argo/argo_workflows.py,sha256=rnrxo20MCqMDNt0mnQJ5Dy-zA9Oo7vkbKTmADZuMbsg,129329
153
153
  metaflow/plugins/argo/argo_workflows_cli.py,sha256=sZTpgfmc50eT3e0qIxpVqUgWhTcYlO1HM4gU6Oaya8g,33259
154
- metaflow/plugins/argo/argo_workflows_decorator.py,sha256=kCtwB6grJso5UwxKSirJn7L9BWP5rd3arBunAyS-uuU,6656
155
- metaflow/plugins/argo/process_input_paths.py,sha256=4SiUoxbnTX4rCt0RSLcxG5jysbyd8oU-5JT0UOgy-vk,555
154
+ metaflow/plugins/argo/argo_workflows_decorator.py,sha256=K5t4uIk2IXPdK7v7DEjj3buSB8ikLjLycKjbZUYeiaw,6781
155
+ metaflow/plugins/argo/generate_input_paths.py,sha256=loYsI6RFX9LlFsHb7Fe-mzlTTtRdySoOu7sYDy-uXK0,881
156
156
  metaflow/plugins/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
157
157
  metaflow/plugins/aws/aws_client.py,sha256=mO8UD6pxFaOnxDb3hTP3HB7Gqb_ZxoR-76LT683WHvI,4036
158
158
  metaflow/plugins/aws/aws_utils.py,sha256=mSMBTUQ-CELhyPb6w3_Yq6_Hvd_6vbhAojYkrt2RNt8,6941
@@ -213,7 +213,7 @@ metaflow/plugins/datastores/s3_storage.py,sha256=CZdNqaKtxDXQbEg2YHyphph3hWcLIE5
213
213
  metaflow/plugins/datatools/__init__.py,sha256=ge4L16OBQLy2J_MMvoHg3lMfdm-MluQgRWoyZ5GCRnk,1267
214
214
  metaflow/plugins/datatools/local.py,sha256=67hx3O_vInERlL0aJV0Sd-jUTd_2DOw4sJ4-IyEKNKM,4213
215
215
  metaflow/plugins/datatools/s3/__init__.py,sha256=14tr9fPjN3ULW5IOfKHeG7Uhjmgm7LMtQHfz1SFv-h8,248
216
- metaflow/plugins/datatools/s3/s3.py,sha256=v2vkJxN3qYAHpu5na2V0GoXjItg8DGeQe71P3l0xXHQ,66030
216
+ metaflow/plugins/datatools/s3/s3.py,sha256=7jxoDSn4hOM4xoqdwk-xcIfBkAt3RfM-ABXA5ZW0q10,66101
217
217
  metaflow/plugins/datatools/s3/s3op.py,sha256=ZQFSxlaQUt-Ko_kIXMbHOKJc8q4FPXogS3xI6xsDR7Y,43390
218
218
  metaflow/plugins/datatools/s3/s3tail.py,sha256=boQjQGQMI-bvTqcMP2y7uSlSYLcvWOy7J3ZUaF78NAA,2597
219
219
  metaflow/plugins/datatools/s3/s3util.py,sha256=FgRgaVmEq7-i2dV7q8XK5w5PfFt-xJjZa8WrK8IJfdI,3769
@@ -249,7 +249,7 @@ metaflow/plugins/kubernetes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
249
249
  metaflow/plugins/kubernetes/kubernetes.py,sha256=tbM9lfJcii1iAQ5C4bo8vUvwkBroNRVvgrytpcDQkpo,17490
250
250
  metaflow/plugins/kubernetes/kubernetes_cli.py,sha256=cGY-BM5REcVKQCi4JSYSK6PvA9M5TK0ikG09Yfct0jA,9224
251
251
  metaflow/plugins/kubernetes/kubernetes_client.py,sha256=irATJpAob4jINkJw0zT_Xoa6JHRtYxx2IOeimlbzvPo,2373
252
- metaflow/plugins/kubernetes/kubernetes_decorator.py,sha256=StV8TnYtm4hpAGuyC6JQs_LUTHpa5lY-RtVBn9gC8E0,21429
252
+ metaflow/plugins/kubernetes/kubernetes_decorator.py,sha256=OSEVkJRX4Q1E2-Z1AehA40M9ydMU4x3J_AXqmIZjkqA,22409
253
253
  metaflow/plugins/kubernetes/kubernetes_job.py,sha256=qDsvaOcwcaOOaqLePg0HN19LaeJNBEuik9b8ErF9lhg,32259
254
254
  metaflow/plugins/metadata/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
255
255
  metaflow/plugins/metadata/local.py,sha256=YhLJC5zjVJrvQFIyQ92ZBByiUmhCC762RUX7ITX12O8,22428
@@ -298,9 +298,9 @@ metaflow/tutorials/07-worldview/README.md,sha256=5vQTrFqulJ7rWN6r20dhot9lI2sVj9W
298
298
  metaflow/tutorials/07-worldview/worldview.ipynb,sha256=ztPZPI9BXxvW1QdS2Tfe7LBuVzvFvv0AToDnsDJhLdE,2237
299
299
  metaflow/tutorials/08-autopilot/README.md,sha256=GnePFp_q76jPs991lMUqfIIh5zSorIeWznyiUxzeUVE,1039
300
300
  metaflow/tutorials/08-autopilot/autopilot.ipynb,sha256=DQoJlILV7Mq9vfPBGW-QV_kNhWPjS5n6SJLqePjFYLY,3191
301
- metaflow-2.11.12.dist-info/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
302
- metaflow-2.11.12.dist-info/METADATA,sha256=iWxUdtrUA_QE3eu7Grl1NiOlTjpY4g_5RJgr1hvHajQ,5908
303
- metaflow-2.11.12.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
304
- metaflow-2.11.12.dist-info/entry_points.txt,sha256=IKwTN1T3I5eJL3uo_vnkyxVffcgnRdFbKwlghZfn27k,57
305
- metaflow-2.11.12.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
306
- metaflow-2.11.12.dist-info/RECORD,,
301
+ metaflow-2.11.13.dist-info/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
302
+ metaflow-2.11.13.dist-info/METADATA,sha256=Rp060y4CflfHtcHogHhQgQ7jh6Z0wjK3lOctSKg43nc,5908
303
+ metaflow-2.11.13.dist-info/WHEEL,sha256=DZajD4pwLWue70CAfc7YaxT1wLUciNBvN_TTcvXpltE,110
304
+ metaflow-2.11.13.dist-info/entry_points.txt,sha256=IKwTN1T3I5eJL3uo_vnkyxVffcgnRdFbKwlghZfn27k,57
305
+ metaflow-2.11.13.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
306
+ metaflow-2.11.13.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- import re
2
- import sys
3
-
4
-
5
- def process_input_paths(input_paths):
6
- # Convert Argo Workflows provided input-paths string to something that Metaflow
7
- # understands
8
- #
9
- # flow/step/[{task-id:foo},{task-id:bar}] => flow/step/:foo,bar
10
-
11
- flow, run_id, task_ids = input_paths.split("/")
12
- task_ids = re.sub("[\[\]{}]", "", task_ids)
13
- task_ids = task_ids.split(",")
14
- tasks = [t.split(":")[1] for t in task_ids]
15
- return "{}/{}/:{}".format(flow, run_id, ",".join(tasks))
16
-
17
-
18
- if __name__ == "__main__":
19
- print(process_input_paths(sys.argv[1]))