ob-metaflow 2.17.3.1__tar.gz → 2.18.1.1__tar.gz

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 (447) hide show
  1. {ob_metaflow-2.17.3.1/ob_metaflow.egg-info → ob_metaflow-2.18.1.1}/PKG-INFO +2 -2
  2. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/task_datastore.py +3 -0
  3. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/graph.py +3 -1
  4. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/lint.py +28 -0
  5. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_config.py +2 -0
  6. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_workflows.py +136 -4
  7. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_workflows_cli.py +7 -1
  8. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/aws_utils.py +32 -0
  9. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/batch/batch.py +8 -0
  10. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/batch/batch_cli.py +21 -3
  11. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/batch/batch_decorator.py +44 -1
  12. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/step_functions.py +6 -1
  13. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/step_functions_cli.py +22 -0
  14. ob_metaflow-2.18.1.1/metaflow/plugins/cards/card_modules/bundle.css +1 -0
  15. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/main.js +30 -30
  16. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/package_cli.py +1 -1
  17. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runtime.py +166 -26
  18. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/task.py +70 -3
  19. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_configs/config_parameters.py +3 -1
  20. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_decorators/user_step_decorator.py +7 -1
  21. ob_metaflow-2.18.1.1/metaflow/version.py +1 -0
  22. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1/ob_metaflow.egg-info}/PKG-INFO +2 -2
  23. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/ob_metaflow.egg-info/requires.txt +1 -1
  24. ob_metaflow-2.17.3.1/metaflow/plugins/cards/card_modules/bundle.css +0 -1
  25. ob_metaflow-2.17.3.1/metaflow/version.py +0 -1
  26. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/LICENSE +0 -0
  27. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/MANIFEST.in +0 -0
  28. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/README.md +0 -0
  29. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/devtools/Makefile +0 -0
  30. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/devtools/Tiltfile +0 -0
  31. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/devtools/pick_services.sh +0 -0
  32. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/R.py +0 -0
  33. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/__init__.py +0 -0
  34. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/__init__.py +0 -0
  35. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/__init__.py +0 -0
  36. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/_bashcomplete.py +0 -0
  37. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/_compat.py +0 -0
  38. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/_termui_impl.py +0 -0
  39. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/_textwrap.py +0 -0
  40. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/_unicodefun.py +0 -0
  41. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/_winconsole.py +0 -0
  42. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/core.py +0 -0
  43. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/decorators.py +0 -0
  44. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/exceptions.py +0 -0
  45. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/formatting.py +0 -0
  46. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/globals.py +0 -0
  47. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/parser.py +0 -0
  48. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/termui.py +0 -0
  49. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/testing.py +0 -0
  50. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/types.py +0 -0
  51. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/click/utils.py +0 -0
  52. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/imghdr/__init__.py +0 -0
  53. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/__init__.py +0 -0
  54. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_adapters.py +0 -0
  55. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_collections.py +0 -0
  56. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_compat.py +0 -0
  57. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_functools.py +0 -0
  58. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_itertools.py +0 -0
  59. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_meta.py +0 -0
  60. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/_text.py +0 -0
  61. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/importlib_metadata/py.typed +0 -0
  62. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/__init__.py +0 -0
  63. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/_elffile.py +0 -0
  64. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/_manylinux.py +0 -0
  65. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/_musllinux.py +0 -0
  66. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/_parser.py +0 -0
  67. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/_structures.py +0 -0
  68. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/_tokenizer.py +0 -0
  69. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/markers.py +0 -0
  70. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/py.typed +0 -0
  71. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/requirements.py +0 -0
  72. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/specifiers.py +0 -0
  73. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/tags.py +0 -0
  74. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/utils.py +0 -0
  75. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/packaging/version.py +0 -0
  76. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/__init__.py +0 -0
  77. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_checkers.py +0 -0
  78. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_config.py +0 -0
  79. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_decorators.py +0 -0
  80. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_exceptions.py +0 -0
  81. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_functions.py +0 -0
  82. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_importhook.py +0 -0
  83. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_memo.py +0 -0
  84. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_pytest_plugin.py +0 -0
  85. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_suppression.py +0 -0
  86. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_transformer.py +0 -0
  87. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_union_transformer.py +0 -0
  88. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/_utils.py +0 -0
  89. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typeguard/py.typed +0 -0
  90. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/typing_extensions.py +0 -0
  91. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/__init__.py +0 -0
  92. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/__init__.py +0 -0
  93. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_adapters.py +0 -0
  94. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_collections.py +0 -0
  95. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_compat.py +0 -0
  96. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_functools.py +0 -0
  97. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_itertools.py +0 -0
  98. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_meta.py +0 -0
  99. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/_text.py +0 -0
  100. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/importlib_metadata/py.typed +0 -0
  101. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/typing_extensions.py +0 -0
  102. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_6/zipp.py +0 -0
  103. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/__init__.py +0 -0
  104. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/__init__.py +0 -0
  105. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +0 -0
  106. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_collections.py +0 -0
  107. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_compat.py +0 -0
  108. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_functools.py +0 -0
  109. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +0 -0
  110. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_meta.py +0 -0
  111. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/_text.py +0 -0
  112. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
  113. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/__init__.py +0 -0
  114. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_checkers.py +0 -0
  115. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_config.py +0 -0
  116. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_decorators.py +0 -0
  117. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_exceptions.py +0 -0
  118. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_functions.py +0 -0
  119. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_importhook.py +0 -0
  120. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_memo.py +0 -0
  121. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +0 -0
  122. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_suppression.py +0 -0
  123. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_transformer.py +0 -0
  124. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_union_transformer.py +0 -0
  125. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/_utils.py +0 -0
  126. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
  127. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/typing_extensions.py +0 -0
  128. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/v3_7/zipp.py +0 -0
  129. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/__init__.py +0 -0
  130. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/composer.py +0 -0
  131. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/constructor.py +0 -0
  132. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/cyaml.py +0 -0
  133. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/dumper.py +0 -0
  134. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/emitter.py +0 -0
  135. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/error.py +0 -0
  136. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/events.py +0 -0
  137. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/loader.py +0 -0
  138. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/nodes.py +0 -0
  139. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/parser.py +0 -0
  140. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/reader.py +0 -0
  141. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/representer.py +0 -0
  142. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/resolver.py +0 -0
  143. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/scanner.py +0 -0
  144. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/serializer.py +0 -0
  145. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/yaml/tokens.py +0 -0
  146. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/_vendor/zipp.py +0 -0
  147. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cards.py +0 -0
  148. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli.py +0 -0
  149. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_args.py +0 -0
  150. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_components/__init__.py +0 -0
  151. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_components/dump_cmd.py +0 -0
  152. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_components/init_cmd.py +0 -0
  153. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_components/run_cmds.py +0 -0
  154. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_components/step_cmd.py +0 -0
  155. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cli_components/utils.py +0 -0
  156. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/client/__init__.py +0 -0
  157. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/client/core.py +0 -0
  158. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/client/filecache.py +0 -0
  159. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/clone_util.py +0 -0
  160. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/__init__.py +0 -0
  161. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/code/__init__.py +0 -0
  162. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/configure_cmd.py +0 -0
  163. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/develop/__init__.py +0 -0
  164. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/develop/stub_generator.py +0 -0
  165. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/develop/stubs.py +0 -0
  166. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/main_cli.py +0 -0
  167. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/make_wrapper.py +0 -0
  168. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/tutorials_cmd.py +0 -0
  169. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd/util.py +0 -0
  170. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/cmd_with_io.py +0 -0
  171. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/__init__.py +0 -0
  172. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/content_addressed_store.py +0 -0
  173. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/datastore_set.py +0 -0
  174. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/datastore_storage.py +0 -0
  175. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/exceptions.py +0 -0
  176. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/flow_datastore.py +0 -0
  177. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/datastore/inputs.py +0 -0
  178. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/debug.py +0 -0
  179. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/decorators.py +0 -0
  180. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/event_logger.py +0 -0
  181. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/events.py +0 -0
  182. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/exception.py +0 -0
  183. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/extension_support/__init__.py +0 -0
  184. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/extension_support/_empty_file.py +0 -0
  185. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/extension_support/cmd.py +0 -0
  186. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/extension_support/integrations.py +0 -0
  187. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/extension_support/plugins.py +0 -0
  188. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/flowspec.py +0 -0
  189. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/includefile.py +0 -0
  190. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/integrations.py +0 -0
  191. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/meta_files.py +0 -0
  192. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metadata_provider/__init__.py +0 -0
  193. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metadata_provider/heartbeat.py +0 -0
  194. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metadata_provider/metadata.py +0 -0
  195. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metadata_provider/util.py +0 -0
  196. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_config_funcs.py +0 -0
  197. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_current.py +0 -0
  198. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_environment.py +0 -0
  199. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_git.py +0 -0
  200. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_profile.py +0 -0
  201. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/metaflow_version.py +0 -0
  202. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/mflog/__init__.py +0 -0
  203. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/mflog/mflog.py +0 -0
  204. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/mflog/save_logs.py +0 -0
  205. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/mflog/save_logs_periodically.py +0 -0
  206. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/mflog/tee.py +0 -0
  207. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/monitor.py +0 -0
  208. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/multicore_utils.py +0 -0
  209. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/package/__init__.py +0 -0
  210. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/packaging_sys/__init__.py +0 -0
  211. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/packaging_sys/backend.py +0 -0
  212. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/packaging_sys/distribution_support.py +0 -0
  213. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/packaging_sys/tar_backend.py +0 -0
  214. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/packaging_sys/utils.py +0 -0
  215. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/packaging_sys/v1.py +0 -0
  216. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/parameters.py +0 -0
  217. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/__init__.py +0 -0
  218. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/__init__.py +0 -0
  219. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/airflow.py +0 -0
  220. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/airflow_cli.py +0 -0
  221. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/airflow_decorator.py +0 -0
  222. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/airflow_utils.py +0 -0
  223. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/dag.py +0 -0
  224. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/exception.py +0 -0
  225. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/plumbing/__init__.py +0 -0
  226. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/plumbing/set_parameters.py +0 -0
  227. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/sensors/__init__.py +0 -0
  228. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/sensors/base_sensor.py +0 -0
  229. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/sensors/external_task_sensor.py +0 -0
  230. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/airflow/sensors/s3_sensor.py +0 -0
  231. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/__init__.py +0 -0
  232. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_client.py +0 -0
  233. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_events.py +0 -0
  234. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_workflows_decorator.py +0 -0
  235. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_workflows_deployer.py +0 -0
  236. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/argo_workflows_deployer_objects.py +0 -0
  237. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/capture_error.py +0 -0
  238. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/conditional_input_paths.py +0 -0
  239. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/exit_hooks.py +0 -0
  240. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/generate_input_paths.py +0 -0
  241. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/argo/jobset_input_paths.py +0 -0
  242. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/__init__.py +0 -0
  243. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/aws_client.py +0 -0
  244. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/batch/__init__.py +0 -0
  245. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/batch/batch_client.py +0 -0
  246. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/secrets_manager/__init__.py +0 -0
  247. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +0 -0
  248. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/__init__.py +0 -0
  249. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -0
  250. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/event_bridge_client.py +0 -0
  251. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/production_token.py +0 -0
  252. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/schedule_decorator.py +0 -0
  253. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/set_batch_environment.py +0 -0
  254. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/step_functions_client.py +0 -0
  255. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/step_functions_decorator.py +0 -0
  256. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/step_functions_deployer.py +0 -0
  257. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +0 -0
  258. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/__init__.py +0 -0
  259. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/azure_credential.py +0 -0
  260. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/azure_exceptions.py +0 -0
  261. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +0 -0
  262. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/azure_tail.py +0 -0
  263. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/azure_utils.py +0 -0
  264. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/blob_service_client_factory.py +0 -0
  265. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/azure/includefile_support.py +0 -0
  266. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/__init__.py +0 -0
  267. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_cli.py +0 -0
  268. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_client.py +0 -0
  269. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_creator.py +0 -0
  270. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_datastore.py +0 -0
  271. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_decorator.py +0 -0
  272. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/__init__.py +0 -0
  273. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/base.html +0 -0
  274. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/basic.py +0 -0
  275. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/card.py +0 -0
  276. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/chevron/__init__.py +0 -0
  277. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/chevron/main.py +0 -0
  278. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/chevron/metadata.py +0 -0
  279. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/chevron/renderer.py +0 -0
  280. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/chevron/tokenizer.py +0 -0
  281. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/components.py +0 -0
  282. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/convert_to_native_type.py +0 -0
  283. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/main.css +0 -0
  284. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/renderer_tools.py +0 -0
  285. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_modules/test_cards.py +0 -0
  286. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_resolver.py +0 -0
  287. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_server.py +0 -0
  288. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/card_viewer/viewer.html +0 -0
  289. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/component_serializer.py +0 -0
  290. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/exception.py +0 -0
  291. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/cards/metadata.py +0 -0
  292. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/catch_decorator.py +0 -0
  293. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datastores/__init__.py +0 -0
  294. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datastores/azure_storage.py +0 -0
  295. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datastores/gs_storage.py +0 -0
  296. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datastores/local_storage.py +0 -0
  297. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datastores/s3_storage.py +0 -0
  298. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/__init__.py +0 -0
  299. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/local.py +0 -0
  300. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/s3/__init__.py +0 -0
  301. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/s3/s3.py +0 -0
  302. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/s3/s3op.py +0 -0
  303. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/s3/s3tail.py +0 -0
  304. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/datatools/s3/s3util.py +0 -0
  305. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/debug_logger.py +0 -0
  306. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/debug_monitor.py +0 -0
  307. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/__init__.py +0 -0
  308. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/client.py +0 -0
  309. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/client_modules.py +0 -0
  310. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/communication/__init__.py +0 -0
  311. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/communication/bytestream.py +0 -0
  312. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/communication/channel.py +0 -0
  313. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/communication/socket_bytestream.py +0 -0
  314. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/communication/utils.py +0 -0
  315. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/configurations/emulate_test_lib/__init__.py +0 -0
  316. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/configurations/emulate_test_lib/overrides.py +0 -0
  317. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/configurations/emulate_test_lib/server_mappings.py +0 -0
  318. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/configurations/test_lib_impl/__init__.py +0 -0
  319. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/configurations/test_lib_impl/test_lib.py +0 -0
  320. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/consts.py +0 -0
  321. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/data_transferer.py +0 -0
  322. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/exception_transferer.py +0 -0
  323. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/override_decorators.py +0 -0
  324. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/server.py +0 -0
  325. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/stub.py +0 -0
  326. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/env_escape/utils.py +0 -0
  327. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/environment_decorator.py +0 -0
  328. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/events_decorator.py +0 -0
  329. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/exit_hook/__init__.py +0 -0
  330. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/exit_hook/exit_hook_decorator.py +0 -0
  331. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/exit_hook/exit_hook_script.py +0 -0
  332. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/frameworks/__init__.py +0 -0
  333. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/frameworks/pytorch.py +0 -0
  334. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/__init__.py +0 -0
  335. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +0 -0
  336. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/gs_exceptions.py +0 -0
  337. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/gs_storage_client_factory.py +0 -0
  338. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/gs_tail.py +0 -0
  339. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/gs_utils.py +0 -0
  340. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/gcp/includefile_support.py +0 -0
  341. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/__init__.py +0 -0
  342. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kube_utils.py +0 -0
  343. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kubernetes.py +0 -0
  344. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kubernetes_cli.py +0 -0
  345. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kubernetes_client.py +0 -0
  346. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kubernetes_decorator.py +0 -0
  347. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kubernetes_job.py +0 -0
  348. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/kubernetes_jobsets.py +0 -0
  349. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/spot_metadata_cli.py +0 -0
  350. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/kubernetes/spot_monitor_sidecar.py +0 -0
  351. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/logs_cli.py +0 -0
  352. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/metadata_providers/__init__.py +0 -0
  353. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/metadata_providers/local.py +0 -0
  354. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/metadata_providers/service.py +0 -0
  355. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/parallel_decorator.py +0 -0
  356. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/project_decorator.py +0 -0
  357. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/__init__.py +0 -0
  358. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/bootstrap.py +0 -0
  359. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/conda_decorator.py +0 -0
  360. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/conda_environment.py +0 -0
  361. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/micromamba.py +0 -0
  362. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/parsers.py +0 -0
  363. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/pip.py +0 -0
  364. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/pypi_decorator.py +0 -0
  365. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/pypi_environment.py +0 -0
  366. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/pypi/utils.py +0 -0
  367. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/resources_decorator.py +0 -0
  368. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/retry_decorator.py +0 -0
  369. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/secrets/__init__.py +0 -0
  370. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/secrets/inline_secrets_provider.py +0 -0
  371. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/secrets/secrets_decorator.py +0 -0
  372. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/secrets/secrets_func.py +0 -0
  373. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/secrets/secrets_spec.py +0 -0
  374. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/secrets/utils.py +0 -0
  375. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/storage_executor.py +0 -0
  376. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/tag_cli.py +0 -0
  377. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/test_unbounded_foreach_decorator.py +0 -0
  378. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/timeout_decorator.py +0 -0
  379. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/uv/__init__.py +0 -0
  380. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/uv/bootstrap.py +0 -0
  381. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/plugins/uv/uv_environment.py +0 -0
  382. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/procpoll.py +0 -0
  383. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/py.typed +0 -0
  384. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/pylint_wrapper.py +0 -0
  385. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/__init__.py +0 -0
  386. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/click_api.py +0 -0
  387. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/deployer.py +0 -0
  388. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/deployer_impl.py +0 -0
  389. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/metaflow_runner.py +0 -0
  390. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/nbdeploy.py +0 -0
  391. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/nbrun.py +0 -0
  392. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/subprocess_manager.py +0 -0
  393. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/runner/utils.py +0 -0
  394. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/sidecar/__init__.py +0 -0
  395. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/sidecar/sidecar.py +0 -0
  396. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/sidecar/sidecar_messages.py +0 -0
  397. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/sidecar/sidecar_subprocess.py +0 -0
  398. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/sidecar/sidecar_worker.py +0 -0
  399. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/system/__init__.py +0 -0
  400. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/system/system_logger.py +0 -0
  401. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/system/system_monitor.py +0 -0
  402. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/system/system_utils.py +0 -0
  403. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tagging_util.py +0 -0
  404. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tracing/__init__.py +0 -0
  405. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tracing/propagator.py +0 -0
  406. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tracing/span_exporter.py +0 -0
  407. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tracing/tracing_modules.py +0 -0
  408. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tuple_util.py +0 -0
  409. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/00-helloworld/README.md +0 -0
  410. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/00-helloworld/helloworld.py +0 -0
  411. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/01-playlist/README.md +0 -0
  412. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/01-playlist/movies.csv +0 -0
  413. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/01-playlist/playlist.ipynb +0 -0
  414. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/01-playlist/playlist.py +0 -0
  415. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/02-statistics/README.md +0 -0
  416. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/02-statistics/movies.csv +0 -0
  417. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/02-statistics/stats.ipynb +0 -0
  418. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/02-statistics/stats.py +0 -0
  419. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/03-playlist-redux/README.md +0 -0
  420. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/03-playlist-redux/playlist.py +0 -0
  421. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/04-playlist-plus/README.md +0 -0
  422. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/04-playlist-plus/playlist.py +0 -0
  423. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/05-hello-cloud/README.md +0 -0
  424. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/05-hello-cloud/hello-cloud.ipynb +0 -0
  425. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/05-hello-cloud/hello-cloud.py +0 -0
  426. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/06-statistics-redux/README.md +0 -0
  427. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/06-statistics-redux/stats.ipynb +0 -0
  428. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/07-worldview/README.md +0 -0
  429. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/07-worldview/worldview.ipynb +0 -0
  430. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/08-autopilot/README.md +0 -0
  431. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/tutorials/08-autopilot/autopilot.ipynb +0 -0
  432. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/unbounded_foreach.py +0 -0
  433. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_configs/__init__.py +0 -0
  434. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_configs/config_options.py +0 -0
  435. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_decorators/__init__.py +0 -0
  436. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_decorators/common.py +0 -0
  437. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_decorators/mutable_flow.py +0 -0
  438. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_decorators/mutable_step.py +0 -0
  439. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/user_decorators/user_flow_decorator.py +0 -0
  440. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/util.py +0 -0
  441. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/metaflow/vendor.py +0 -0
  442. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/ob_metaflow.egg-info/SOURCES.txt +0 -0
  443. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/ob_metaflow.egg-info/dependency_links.txt +0 -0
  444. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/ob_metaflow.egg-info/entry_points.txt +0 -0
  445. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/ob_metaflow.egg-info/top_level.txt +0 -0
  446. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/setup.cfg +0 -0
  447. {ob_metaflow-2.17.3.1 → ob_metaflow-2.18.1.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-metaflow
3
- Version: 2.17.3.1
3
+ Version: 2.18.1.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.17.3.1; extra == "stubs"
15
+ Requires-Dist: metaflow-stubs==2.18.1.1; extra == "stubs"
16
16
  Dynamic: author
17
17
  Dynamic: author-email
18
18
  Dynamic: description
@@ -222,6 +222,9 @@ class TaskDataStore(object):
222
222
  @property
223
223
  def pathspec_index(self):
224
224
  idxstr = ",".join(map(str, (f.index for f in self["_foreach_stack"])))
225
+ if "_iteration_stack" in self:
226
+ itrstr = ",".join(map(str, (f for f in self["_iteration_stack"])))
227
+ return "%s/%s[%s][%s]" % (self._run_id, self._step_name, idxstr, itrstr)
225
228
  return "%s/%s[%s]" % (self._run_id, self._step_name, idxstr)
226
229
 
227
230
  @property
@@ -478,7 +478,9 @@ class FlowGraph(object):
478
478
  cur_name = cur_node.matching_join
479
479
  elif node_type == "split-switch":
480
480
  all_paths = [
481
- populate_block(s, end_name) for s in cur_node.out_funcs
481
+ populate_block(s, end_name)
482
+ for s in cur_node.out_funcs
483
+ if s != cur_name
482
484
  ]
483
485
  resulting_list.append(all_paths)
484
486
  cur_name = end_name
@@ -175,6 +175,8 @@ def check_for_acyclicity(graph):
175
175
 
176
176
  def check_path(node, seen):
177
177
  for n in node.out_funcs:
178
+ if node.type == "split-switch" and n == node.name:
179
+ continue
178
180
  if n in seen:
179
181
  path = "->".join(seen + [n])
180
182
  raise LintWarn(
@@ -241,6 +243,8 @@ def check_split_join_balance(graph):
241
243
  elif node.type == "split-switch":
242
244
  # For a switch, continue traversal down each path with the same stack
243
245
  for n in node.out_funcs:
246
+ if node.type == "split-switch" and n == node.name:
247
+ continue
244
248
  traverse(graph[n], split_stack)
245
249
  return
246
250
  elif node.type == "end":
@@ -293,6 +297,8 @@ def check_split_join_balance(graph):
293
297
  new_stack = split_stack
294
298
 
295
299
  for n in node.out_funcs:
300
+ if node.type == "split-switch" and n == node.name:
301
+ continue
296
302
  traverse(graph[n], new_stack)
297
303
 
298
304
  traverse(graph["start"], [])
@@ -410,3 +416,25 @@ def check_nested_foreach(graph):
410
416
  if node.type == "foreach":
411
417
  if any(graph[p].type == "foreach" for p in node.split_parents):
412
418
  raise LintWarn(msg.format(node), node.func_lineno, node.source_file)
419
+
420
+
421
+ @linter.ensure_static_graph
422
+ @linter.check
423
+ def check_ambiguous_joins(graph):
424
+ for node in graph:
425
+ if node.type == "join":
426
+ problematic_parents = [
427
+ p_name
428
+ for p_name in node.in_funcs
429
+ if graph[p_name].type == "split-switch"
430
+ ]
431
+ if problematic_parents:
432
+ msg = (
433
+ "A conditional path cannot lead directly to a join step.\n"
434
+ "In your conditional step(s) {parents}, one or more of the possible paths transition directly to the join step {join_name}.\n"
435
+ "As a workaround, please introduce an intermediate, unconditional step on that specific path before joining."
436
+ ).format(
437
+ parents=", ".join("*%s*" % p for p in problematic_parents),
438
+ join_name="*%s*" % node.name,
439
+ )
440
+ raise LintWarn(msg, node.func_lineno, node.source_file)
@@ -315,6 +315,8 @@ SERVICE_INTERNAL_URL = from_conf("SERVICE_INTERNAL_URL", SERVICE_URL)
315
315
  # in all Metaflow deployments. Hopefully, some day we can flip the
316
316
  # default to True.
317
317
  BATCH_EMIT_TAGS = from_conf("BATCH_EMIT_TAGS", False)
318
+ # Default tags to add to AWS Batch jobs. These are in addition to the defaults set when BATCH_EMIT_TAGS is true.
319
+ BATCH_DEFAULT_TAGS = from_conf("BATCH_DEFAULT_TAGS", {})
318
320
 
319
321
  ###
320
322
  # AWS Step Functions configuration
@@ -935,6 +935,7 @@ class ArgoWorkflows(object):
935
935
  self.conditional_nodes = set()
936
936
  self.conditional_join_nodes = set()
937
937
  self.matching_conditional_join_dict = {}
938
+ self.recursive_nodes = set()
938
939
 
939
940
  node_conditional_parents = {}
940
941
  node_conditional_branches = {}
@@ -957,6 +958,12 @@ class ArgoWorkflows(object):
957
958
  )
958
959
  node_conditional_parents[node.name] = conditional_parents
959
960
 
961
+ # check for recursion. this split is recursive if any of its out functions are itself.
962
+ if any(
963
+ out_func for out_func in node.out_funcs if out_func == node.name
964
+ ):
965
+ self.recursive_nodes.add(node.name)
966
+
960
967
  if conditional_parents and not node.type == "split-switch":
961
968
  node_conditional_parents[node.name] = conditional_parents
962
969
  conditional_branch = conditional_branch + [node.name]
@@ -1042,6 +1049,9 @@ class ArgoWorkflows(object):
1042
1049
  def _is_conditional_join_node(self, node):
1043
1050
  return node.name in self.conditional_join_nodes
1044
1051
 
1052
+ def _is_recursive_node(self, node):
1053
+ return node.name in self.recursive_nodes
1054
+
1045
1055
  def _matching_conditional_join(self, node):
1046
1056
  return self.matching_conditional_join_dict.get(node.name, None)
1047
1057
 
@@ -1053,6 +1063,7 @@ class ArgoWorkflows(object):
1053
1063
  templates=None,
1054
1064
  dag_tasks=None,
1055
1065
  parent_foreach=None,
1066
+ seen=None,
1056
1067
  ): # Returns Tuple[List[Template], List[DAGTask]]
1057
1068
  """ """
1058
1069
  # Every for-each node results in a separate subDAG and an equivalent
@@ -1062,6 +1073,8 @@ class ArgoWorkflows(object):
1062
1073
  # of the for-each node.
1063
1074
 
1064
1075
  # Emit if we have reached the end of the sub workflow
1076
+ if seen is None:
1077
+ seen = []
1065
1078
  if dag_tasks is None:
1066
1079
  dag_tasks = []
1067
1080
  if templates is None:
@@ -1069,6 +1082,13 @@ class ArgoWorkflows(object):
1069
1082
 
1070
1083
  if exit_node is not None and exit_node is node.name:
1071
1084
  return templates, dag_tasks
1085
+ if node.name in seen:
1086
+ return templates, dag_tasks
1087
+
1088
+ seen.append(node.name)
1089
+
1090
+ # helper variable for recursive conditional inputs
1091
+ has_foreach_inputs = False
1072
1092
  if node.name == "start":
1073
1093
  # Start node has no dependencies.
1074
1094
  dag_task = DAGTask(self._sanitize(node.name)).template(
@@ -1082,9 +1102,10 @@ class ArgoWorkflows(object):
1082
1102
  # vs what is a "num_parallel" based foreach (i.e. something that follows gang semantics.)
1083
1103
  # A `regular` foreach is basically any arbitrary kind of foreach.
1084
1104
  ):
1105
+ # helper variable for recursive conditional inputs
1106
+ has_foreach_inputs = True
1085
1107
  # Child of a foreach node needs input-paths as well as split-index
1086
1108
  # This child is the first node of the sub workflow and has no dependency
1087
-
1088
1109
  parameters = [
1089
1110
  Parameter("input-paths").value("{{inputs.parameters.input-paths}}"),
1090
1111
  Parameter("split-index").value("{{inputs.parameters.split-index}}"),
@@ -1262,6 +1283,7 @@ class ArgoWorkflows(object):
1262
1283
  templates,
1263
1284
  dag_tasks,
1264
1285
  parent_foreach,
1286
+ seen,
1265
1287
  )
1266
1288
  return _visit(
1267
1289
  self.graph[node.matching_join],
@@ -1269,8 +1291,102 @@ class ArgoWorkflows(object):
1269
1291
  templates,
1270
1292
  dag_tasks,
1271
1293
  parent_foreach,
1294
+ seen,
1272
1295
  )
1273
1296
  elif node.type == "split-switch":
1297
+ if self._is_recursive_node(node):
1298
+ # we need an additional recursive template if the step is recursive
1299
+ # NOTE: in the recursive case, the original step is renamed in the container templates to 'recursive-<step_name>'
1300
+ # so that we do not have to touch the step references in the DAG.
1301
+ #
1302
+ # NOTE: The way that recursion in Argo Workflows is achieved is with the following structure:
1303
+ # - the usual 'example-step' template which would match example_step in flow code is renamed to 'recursive-example-step'
1304
+ # - templates has another template with the original task name: 'example-step'
1305
+ # - the template 'example-step' in turn has steps
1306
+ # - 'example-step-internal' which uses the metaflow step executing template 'recursive-example-step'
1307
+ # - 'example-step-recursion' which calls the parent template 'example-step' if switch-step output from 'example-step-internal' matches the condition.
1308
+ sanitized_name = self._sanitize(node.name)
1309
+ templates.append(
1310
+ Template(sanitized_name)
1311
+ .steps(
1312
+ [
1313
+ WorkflowStep()
1314
+ .name("%s-internal" % sanitized_name)
1315
+ .template("recursive-%s" % sanitized_name)
1316
+ .arguments(
1317
+ Arguments().parameters(
1318
+ [
1319
+ Parameter("input-paths").value(
1320
+ "{{inputs.parameters.input-paths}}"
1321
+ )
1322
+ ]
1323
+ # Add the additional inputs required by specific node types.
1324
+ # We do not need to cover joins or @parallel, as a split-switch step can not be either one of these.
1325
+ + (
1326
+ [
1327
+ Parameter("split-index").value(
1328
+ "{{inputs.parameters.split-index}}"
1329
+ )
1330
+ ]
1331
+ if has_foreach_inputs
1332
+ else []
1333
+ )
1334
+ )
1335
+ )
1336
+ ]
1337
+ )
1338
+ .steps(
1339
+ [
1340
+ WorkflowStep()
1341
+ .name("%s-recursion" % sanitized_name)
1342
+ .template(sanitized_name)
1343
+ .when(
1344
+ "{{steps.%s-internal.outputs.parameters.switch-step}}==%s"
1345
+ % (sanitized_name, node.name)
1346
+ )
1347
+ .arguments(
1348
+ Arguments().parameters(
1349
+ [
1350
+ Parameter("input-paths").value(
1351
+ "argo-{{workflow.name}}/%s/{{steps.%s-internal.outputs.parameters.task-id}}"
1352
+ % (node.name, sanitized_name)
1353
+ )
1354
+ ]
1355
+ + (
1356
+ [
1357
+ Parameter("split-index").value(
1358
+ "{{inputs.parameters.split-index}}"
1359
+ )
1360
+ ]
1361
+ if has_foreach_inputs
1362
+ else []
1363
+ )
1364
+ )
1365
+ ),
1366
+ ]
1367
+ )
1368
+ .inputs(Inputs().parameters(parameters))
1369
+ .outputs(
1370
+ # NOTE: We try to read the output parameters from the recursive template call first (<step>-recursion), and the internal step second (<step>-internal).
1371
+ # This guarantees that we always get the output parameters of the last recursive step that executed.
1372
+ Outputs().parameters(
1373
+ [
1374
+ Parameter("task-id").valueFrom(
1375
+ {
1376
+ "expression": "(steps['%s-recursion']?.outputs ?? steps['%s-internal']?.outputs).parameters['task-id']"
1377
+ % (sanitized_name, sanitized_name)
1378
+ }
1379
+ ),
1380
+ Parameter("switch-step").valueFrom(
1381
+ {
1382
+ "expression": "(steps['%s-recursion']?.outputs ?? steps['%s-internal']?.outputs).parameters['switch-step']"
1383
+ % (sanitized_name, sanitized_name)
1384
+ }
1385
+ ),
1386
+ ]
1387
+ )
1388
+ )
1389
+ )
1274
1390
  for n in node.out_funcs:
1275
1391
  _visit(
1276
1392
  self.graph[n],
@@ -1278,6 +1394,7 @@ class ArgoWorkflows(object):
1278
1394
  templates,
1279
1395
  dag_tasks,
1280
1396
  parent_foreach,
1397
+ seen,
1281
1398
  )
1282
1399
 
1283
1400
  return _visit(
@@ -1286,6 +1403,7 @@ class ArgoWorkflows(object):
1286
1403
  templates,
1287
1404
  dag_tasks,
1288
1405
  parent_foreach,
1406
+ seen,
1289
1407
  )
1290
1408
  # For foreach nodes generate a new sub DAGTemplate
1291
1409
  # We do this for "regular" foreaches (ie. `self.next(self.a, foreach=)`)
@@ -1376,6 +1494,7 @@ class ArgoWorkflows(object):
1376
1494
  templates,
1377
1495
  [],
1378
1496
  node.name,
1497
+ seen,
1379
1498
  )
1380
1499
 
1381
1500
  # How do foreach's work on Argo:
@@ -1509,6 +1628,7 @@ class ArgoWorkflows(object):
1509
1628
  templates,
1510
1629
  dag_tasks,
1511
1630
  parent_foreach,
1631
+ seen,
1512
1632
  )
1513
1633
  # For linear nodes continue traversing to the next node
1514
1634
  if node.type in ("linear", "join", "start"):
@@ -1518,6 +1638,7 @@ class ArgoWorkflows(object):
1518
1638
  templates,
1519
1639
  dag_tasks,
1520
1640
  parent_foreach,
1641
+ seen,
1521
1642
  )
1522
1643
  else:
1523
1644
  raise ArgoWorkflowsException(
@@ -1782,8 +1903,10 @@ class ArgoWorkflows(object):
1782
1903
  # foreach-joins straight out of conditional branches are not yet supported
1783
1904
  if self._is_conditional_join_node(node):
1784
1905
  raise ArgoWorkflowsException(
1785
- "Conditionals steps that transition directly into a join step are not currently supported. "
1786
- "As a workaround, you can add a normal step after the conditional steps that transitions to a join step."
1906
+ "Conditional steps inside a foreach that transition directly into a join step are not currently supported.\n"
1907
+ "As a workaround, add a common step after the conditional steps %s "
1908
+ "that will transition to a join."
1909
+ % ", ".join("*%s*" % f for f in node.in_funcs)
1787
1910
  )
1788
1911
  # Set aggregated input-paths for a for-each join
1789
1912
  foreach_step = next(
@@ -2307,8 +2430,13 @@ class ArgoWorkflows(object):
2307
2430
  )
2308
2431
  )
2309
2432
  else:
2433
+ template_name = self._sanitize(node.name)
2434
+ if self._is_recursive_node(node):
2435
+ # The recursive template has the original step name,
2436
+ # this becomes a template within the recursive ones 'steps'
2437
+ template_name = self._sanitize("recursive-%s" % node.name)
2310
2438
  yield (
2311
- Template(self._sanitize(node.name))
2439
+ Template(template_name)
2312
2440
  # Set @timeout values
2313
2441
  .active_deadline_seconds(run_time_limit)
2314
2442
  # Set service account
@@ -3801,6 +3929,10 @@ class WorkflowStep(object):
3801
3929
  self.payload["template"] = str(template)
3802
3930
  return self
3803
3931
 
3932
+ def arguments(self, arguments):
3933
+ self.payload["arguments"] = arguments.to_json()
3934
+ return self
3935
+
3804
3936
  def when(self, condition):
3805
3937
  self.payload["when"] = str(condition)
3806
3938
  return self
@@ -1369,7 +1369,7 @@ def sanitize_for_argo(text):
1369
1369
  Sanitizes a string so it does not contain characters that are not permitted in
1370
1370
  Argo Workflow resource names.
1371
1371
  """
1372
- return (
1372
+ sanitized = (
1373
1373
  re.compile(r"^[^A-Za-z0-9]+")
1374
1374
  .sub("", text)
1375
1375
  .replace("_", "")
@@ -1377,6 +1377,12 @@ def sanitize_for_argo(text):
1377
1377
  .replace("+", "")
1378
1378
  .lower()
1379
1379
  )
1380
+ # This is added in order to get sanitized and truncated project branch names to adhere to RFC 1123 subdomain requirements
1381
+ # f.ex. after truncation a project flow name might be project.branch-cut-short-.flowname
1382
+ # sanitize around the . separators by removing any non-alphanumeric characters
1383
+ sanitized = re.compile(r"[^a-z0-9]*\.[^a-z0-9]*").sub(".", sanitized)
1384
+
1385
+ return sanitized
1380
1386
 
1381
1387
 
1382
1388
  def remap_status(status):
@@ -208,3 +208,35 @@ def sanitize_batch_tag(key, value):
208
208
  _value = re.sub(RE_NOT_PERMITTED, "", value)[:256]
209
209
 
210
210
  return _key, _value
211
+
212
+
213
+ def validate_aws_tag(key: str, value: str):
214
+ PERMITTED = r"[A-Za-z0-9\s\+\-\=\.\_\:\/\@]"
215
+
216
+ AWS_PREFIX = r"^aws\:" # case-insensitive.
217
+ if re.match(AWS_PREFIX, key, re.IGNORECASE) or re.match(
218
+ AWS_PREFIX, value, re.IGNORECASE
219
+ ):
220
+ raise MetaflowException(
221
+ "'aws:' is not an allowed prefix for either tag keys or values"
222
+ )
223
+
224
+ if len(key) > 128:
225
+ raise MetaflowException(
226
+ "Tag key *%s* is too long. Maximum allowed tag key length is 128." % key
227
+ )
228
+ if len(value) > 256:
229
+ raise MetaflowException(
230
+ "Tag value *%s* is too long. Maximum allowed tag value length is 256."
231
+ % value
232
+ )
233
+
234
+ if not re.match(PERMITTED, key):
235
+ raise MetaflowException(
236
+ "Key *s* is not permitted. Tags must match pattern: %s" % (key, PERMITTED)
237
+ )
238
+ if not re.match(PERMITTED, value):
239
+ raise MetaflowException(
240
+ "Value *%s* is not permitted. Tags must match pattern: %s"
241
+ % (value, PERMITTED)
242
+ )
@@ -199,6 +199,7 @@ class Batch(object):
199
199
  host_volumes=None,
200
200
  efs_volumes=None,
201
201
  use_tmpfs=None,
202
+ aws_batch_tags=None,
202
203
  tmpfs_tempdir=None,
203
204
  tmpfs_size=None,
204
205
  tmpfs_path=None,
@@ -344,6 +345,11 @@ class Batch(object):
344
345
  if key in attrs:
345
346
  k, v = sanitize_batch_tag(key, attrs.get(key))
346
347
  job.tag(k, v)
348
+
349
+ if aws_batch_tags is not None:
350
+ for key, value in aws_batch_tags.items():
351
+ job.tag(key, value)
352
+
347
353
  return job
348
354
 
349
355
  def launch_job(
@@ -371,6 +377,7 @@ class Batch(object):
371
377
  host_volumes=None,
372
378
  efs_volumes=None,
373
379
  use_tmpfs=None,
380
+ aws_batch_tags=None,
374
381
  tmpfs_tempdir=None,
375
382
  tmpfs_size=None,
376
383
  tmpfs_path=None,
@@ -414,6 +421,7 @@ class Batch(object):
414
421
  host_volumes=host_volumes,
415
422
  efs_volumes=efs_volumes,
416
423
  use_tmpfs=use_tmpfs,
424
+ aws_batch_tags=aws_batch_tags,
417
425
  tmpfs_tempdir=tmpfs_tempdir,
418
426
  tmpfs_size=tmpfs_size,
419
427
  tmpfs_path=tmpfs_path,
@@ -12,6 +12,7 @@ from metaflow.metaflow_config import DATASTORE_LOCAL_DIR
12
12
  from metaflow.mflog import TASK_LOG_SOURCE
13
13
  from metaflow.unbounded_foreach import UBF_CONTROL, UBF_TASK
14
14
  from .batch import Batch, BatchKilledException
15
+ from ..aws_utils import validate_aws_tag
15
16
 
16
17
 
17
18
  @click.group()
@@ -47,7 +48,7 @@ def _execute_cmd(func, flow_name, run_id, user, my_runs, echo):
47
48
  func(flow_name, run_id, user, echo)
48
49
 
49
50
 
50
- @batch.command(help="List unfinished AWS Batch tasks of this flow")
51
+ @batch.command("list", help="List unfinished AWS Batch tasks of this flow")
51
52
  @click.option(
52
53
  "--my-runs",
53
54
  default=False,
@@ -61,7 +62,7 @@ def _execute_cmd(func, flow_name, run_id, user, my_runs, echo):
61
62
  help="List unfinished tasks corresponding to the run id.",
62
63
  )
63
64
  @click.pass_context
64
- def list(ctx, run_id, user, my_runs):
65
+ def _list(ctx, run_id, user, my_runs):
65
66
  batch = Batch(ctx.obj.metadata, ctx.obj.environment)
66
67
  _execute_cmd(
67
68
  batch.list_jobs, ctx.obj.flow.name, run_id, user, my_runs, ctx.obj.echo
@@ -147,6 +148,13 @@ def kill(ctx, run_id, user, my_runs):
147
148
  help="Activate designated number of elastic fabric adapter devices. "
148
149
  "EFA driver must be installed and instance type compatible with EFA",
149
150
  )
151
+ @click.option(
152
+ "--aws-batch-tag",
153
+ "aws_batch_tags",
154
+ multiple=True,
155
+ default=None,
156
+ help="AWS tags. Format: key=value, multiple allowed",
157
+ )
150
158
  @click.option("--use-tmpfs", is_flag=True, help="tmpfs requirement for AWS Batch.")
151
159
  @click.option("--tmpfs-tempdir", is_flag=True, help="tmpfs requirement for AWS Batch.")
152
160
  @click.option("--tmpfs-size", help="tmpfs requirement for AWS Batch.")
@@ -203,6 +211,7 @@ def step(
203
211
  swappiness=None,
204
212
  inferentia=None,
205
213
  efa=None,
214
+ aws_batch_tags=None,
206
215
  use_tmpfs=None,
207
216
  tmpfs_tempdir=None,
208
217
  tmpfs_size=None,
@@ -213,7 +222,7 @@ def step(
213
222
  log_driver=None,
214
223
  log_options=None,
215
224
  num_parallel=None,
216
- **kwargs,
225
+ **kwargs
217
226
  ):
218
227
  def echo(msg, stream="stderr", batch_id=None, **kwargs):
219
228
  msg = util.to_unicode(msg)
@@ -277,6 +286,14 @@ def step(
277
286
 
278
287
  env = {"METAFLOW_FLOW_FILENAME": os.path.basename(sys.argv[0])}
279
288
 
289
+ if aws_batch_tags is not None:
290
+ # We do not need to validate these again,
291
+ # as they come supplied by the batch decorator which already performed validation.
292
+ batch_tags = {}
293
+ for item in list(aws_batch_tags):
294
+ key, value = item.split("=")
295
+ batch_tags[key] = value
296
+
280
297
  env_deco = [deco for deco in node.decorators if deco.name == "environment"]
281
298
  if env_deco:
282
299
  env.update(env_deco[0].attributes["vars"])
@@ -341,6 +358,7 @@ def step(
341
358
  host_volumes=host_volumes,
342
359
  efs_volumes=efs_volumes,
343
360
  use_tmpfs=use_tmpfs,
361
+ aws_batch_tags=batch_tags,
344
362
  tmpfs_tempdir=tmpfs_tempdir,
345
363
  tmpfs_size=tmpfs_size,
346
364
  tmpfs_path=tmpfs_path,
@@ -10,6 +10,7 @@ from metaflow.metadata_provider.util import sync_local_metadata_to_datastore
10
10
  from metaflow.metaflow_config import (
11
11
  BATCH_CONTAINER_IMAGE,
12
12
  BATCH_CONTAINER_REGISTRY,
13
+ BATCH_DEFAULT_TAGS,
13
14
  BATCH_JOB_QUEUE,
14
15
  DATASTORE_LOCAL_DIR,
15
16
  ECS_FARGATE_EXECUTION_ROLE,
@@ -24,6 +25,7 @@ from ..aws_utils import (
24
25
  compute_resource_attributes,
25
26
  get_docker_registry,
26
27
  get_ec2_instance_metadata,
28
+ validate_aws_tag,
27
29
  )
28
30
  from .batch import BatchException
29
31
 
@@ -68,6 +70,9 @@ class BatchDecorator(StepDecorator):
68
70
  A swappiness value of 0 causes swapping not to happen unless absolutely
69
71
  necessary. A swappiness value of 100 causes pages to be swapped very
70
72
  aggressively. Accepted values are whole numbers between 0 and 100.
73
+ aws_batch_tags: Dict[str, str], optional, default None
74
+ Sets arbitrary AWS tags on the AWS Batch compute environment.
75
+ Set as string key-value pairs.
71
76
  use_tmpfs : bool, default False
72
77
  This enables an explicit tmpfs mount for this step. Note that tmpfs is
73
78
  not available on Fargate compute environments
@@ -114,6 +119,7 @@ class BatchDecorator(StepDecorator):
114
119
  "host_volumes": None,
115
120
  "efs_volumes": None,
116
121
  "use_tmpfs": False,
122
+ "aws_batch_tags": None,
117
123
  "tmpfs_tempdir": True,
118
124
  "tmpfs_size": None,
119
125
  "tmpfs_path": "/metaflow_temp",
@@ -175,6 +181,29 @@ class BatchDecorator(StepDecorator):
175
181
  if self.attributes["trainium"] is not None:
176
182
  self.attributes["inferentia"] = self.attributes["trainium"]
177
183
 
184
+ if not isinstance(BATCH_DEFAULT_TAGS, dict) and not all(
185
+ isinstance(k, str) and isinstance(v, str)
186
+ for k, v in BATCH_DEFAULT_TAGS.items()
187
+ ):
188
+ raise BatchException(
189
+ "BATCH_DEFAULT_TAGS environment variable must be Dict[str, str]"
190
+ )
191
+
192
+ if self.attributes["aws_batch_tags"] is not None:
193
+ if not isinstance(self.attributes["aws_batch_tags"], dict) and not all(
194
+ isinstance(k, str) and isinstance(v, str)
195
+ for k, v in self.attributes["aws_batch_tags"].items()
196
+ ):
197
+ raise BatchException("aws_batch_tags must be Dict[str, str]")
198
+ else:
199
+ self.attributes["aws_batch_tags"] = {}
200
+
201
+ if BATCH_DEFAULT_TAGS:
202
+ self.attributes["aws_batch_tags"] = {
203
+ **BATCH_DEFAULT_TAGS,
204
+ **self.attributes["aws_batch_tags"],
205
+ }
206
+
178
207
  # clean up the alias attribute so it is not passed on.
179
208
  self.attributes.pop("trainium", None)
180
209
 
@@ -207,6 +236,11 @@ class BatchDecorator(StepDecorator):
207
236
  if self.attributes["tmpfs_path"] and self.attributes["tmpfs_path"][0] != "/":
208
237
  raise BatchException("'tmpfs_path' needs to be an absolute path")
209
238
 
239
+ # Validate Batch tags
240
+ if self.attributes["aws_batch_tags"]:
241
+ for key, val in self.attributes["aws_batch_tags"].items():
242
+ validate_aws_tag(key, val)
243
+
210
244
  def runtime_init(self, flow, graph, package, run_id):
211
245
  # Set some more internal state.
212
246
  self.flow = flow
@@ -231,8 +265,17 @@ class BatchDecorator(StepDecorator):
231
265
  cli_args.command_args.append(self.package_metadata)
232
266
  cli_args.command_args.append(self.package_sha)
233
267
  cli_args.command_args.append(self.package_url)
234
- cli_args.command_options.update(self.attributes)
268
+ # skip certain keys as CLI arguments
269
+ _skip_keys = ["aws_batch_tags"]
270
+ cli_args.command_options.update(
271
+ {k: v for k, v in self.attributes.items() if k not in _skip_keys}
272
+ )
235
273
  cli_args.command_options["run-time-limit"] = self.run_time_limit
274
+
275
+ # Pass the supplied AWS batch tags to the step CLI cmd
276
+ cli_args.command_options["aws-batch-tag"] = [
277
+ "%s=%s" % (k, v) for k, v in self.attributes["aws_batch_tags"].items()
278
+ ]
236
279
  if not R.use_r():
237
280
  cli_args.entrypoint[0] = sys.executable
238
281
 
@@ -50,6 +50,7 @@ class StepFunctions(object):
50
50
  event_logger,
51
51
  monitor,
52
52
  tags=None,
53
+ aws_batch_tags=None,
53
54
  namespace=None,
54
55
  username=None,
55
56
  max_workers=None,
@@ -70,6 +71,7 @@ class StepFunctions(object):
70
71
  self.event_logger = event_logger
71
72
  self.monitor = monitor
72
73
  self.tags = tags
74
+ self.aws_batch_tags = aws_batch_tags or {}
73
75
  self.namespace = namespace
74
76
  self.username = username
75
77
  self.max_workers = max_workers
@@ -194,6 +196,7 @@ class StepFunctions(object):
194
196
  "on AWS Step Functions. Please "
195
197
  "deploy your flow first." % name
196
198
  )
199
+
197
200
  # Dump parameters into `Parameters` input field.
198
201
  input = json.dumps({"Parameters": json.dumps(parameters)})
199
202
  # AWS Step Functions limits input to be 32KiB, but AWS Batch
@@ -852,7 +855,8 @@ class StepFunctions(object):
852
855
  # AWS_BATCH_JOB_ATTEMPT as the job counter.
853
856
  "retry_count": "$((AWS_BATCH_JOB_ATTEMPT-1))",
854
857
  }
855
-
858
+ # merge batch tags supplied through step-fuctions CLI and ones defined in decorator
859
+ batch_tags = {**self.aws_batch_tags, **resources["aws_batch_tags"]}
856
860
  return (
857
861
  Batch(self.metadata, self.environment)
858
862
  .create_job(
@@ -878,6 +882,7 @@ class StepFunctions(object):
878
882
  swappiness=resources["swappiness"],
879
883
  efa=resources["efa"],
880
884
  use_tmpfs=resources["use_tmpfs"],
885
+ aws_batch_tags=batch_tags,
881
886
  tmpfs_tempdir=resources["tmpfs_tempdir"],
882
887
  tmpfs_size=resources["tmpfs_size"],
883
888
  tmpfs_path=resources["tmpfs_path"],