ob-metaflow 2.18.2.1__tar.gz → 2.18.3.2__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.18.2.1/ob_metaflow.egg-info → ob_metaflow-2.18.3.2}/PKG-INFO +2 -2
  2. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/client/core.py +1 -1
  3. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_config.py +5 -0
  4. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_client.py +10 -6
  5. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_workflows.py +222 -42
  6. ob_metaflow-2.18.3.2/metaflow/plugins/argo/conditional_input_paths.py +35 -0
  7. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/batch/batch.py +42 -2
  8. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/step_functions.py +6 -1
  9. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/step_functions_cli.py +11 -0
  10. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/step_functions_deployer.py +3 -0
  11. ob_metaflow-2.18.3.2/metaflow/version.py +1 -0
  12. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2/ob_metaflow.egg-info}/PKG-INFO +2 -2
  13. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/ob_metaflow.egg-info/requires.txt +1 -1
  14. ob_metaflow-2.18.2.1/metaflow/plugins/argo/conditional_input_paths.py +0 -21
  15. ob_metaflow-2.18.2.1/metaflow/version.py +0 -1
  16. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/LICENSE +0 -0
  17. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/MANIFEST.in +0 -0
  18. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/README.md +0 -0
  19. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/devtools/Makefile +0 -0
  20. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/devtools/Tiltfile +0 -0
  21. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/devtools/pick_services.sh +0 -0
  22. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/R.py +0 -0
  23. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/__init__.py +0 -0
  24. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/__init__.py +0 -0
  25. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/__init__.py +0 -0
  26. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/_bashcomplete.py +0 -0
  27. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/_compat.py +0 -0
  28. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/_termui_impl.py +0 -0
  29. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/_textwrap.py +0 -0
  30. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/_unicodefun.py +0 -0
  31. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/_winconsole.py +0 -0
  32. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/core.py +0 -0
  33. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/decorators.py +0 -0
  34. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/exceptions.py +0 -0
  35. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/formatting.py +0 -0
  36. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/globals.py +0 -0
  37. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/parser.py +0 -0
  38. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/termui.py +0 -0
  39. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/testing.py +0 -0
  40. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/types.py +0 -0
  41. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/click/utils.py +0 -0
  42. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/imghdr/__init__.py +0 -0
  43. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/__init__.py +0 -0
  44. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_adapters.py +0 -0
  45. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_collections.py +0 -0
  46. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_compat.py +0 -0
  47. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_functools.py +0 -0
  48. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_itertools.py +0 -0
  49. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_meta.py +0 -0
  50. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/_text.py +0 -0
  51. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/importlib_metadata/py.typed +0 -0
  52. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/__init__.py +0 -0
  53. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/_elffile.py +0 -0
  54. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/_manylinux.py +0 -0
  55. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/_musllinux.py +0 -0
  56. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/_parser.py +0 -0
  57. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/_structures.py +0 -0
  58. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/_tokenizer.py +0 -0
  59. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/markers.py +0 -0
  60. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/py.typed +0 -0
  61. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/requirements.py +0 -0
  62. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/specifiers.py +0 -0
  63. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/tags.py +0 -0
  64. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/utils.py +0 -0
  65. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/packaging/version.py +0 -0
  66. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/__init__.py +0 -0
  67. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_checkers.py +0 -0
  68. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_config.py +0 -0
  69. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_decorators.py +0 -0
  70. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_exceptions.py +0 -0
  71. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_functions.py +0 -0
  72. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_importhook.py +0 -0
  73. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_memo.py +0 -0
  74. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_pytest_plugin.py +0 -0
  75. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_suppression.py +0 -0
  76. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_transformer.py +0 -0
  77. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_union_transformer.py +0 -0
  78. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/_utils.py +0 -0
  79. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typeguard/py.typed +0 -0
  80. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/typing_extensions.py +0 -0
  81. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/__init__.py +0 -0
  82. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/__init__.py +0 -0
  83. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_adapters.py +0 -0
  84. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_collections.py +0 -0
  85. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_compat.py +0 -0
  86. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_functools.py +0 -0
  87. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_itertools.py +0 -0
  88. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_meta.py +0 -0
  89. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/_text.py +0 -0
  90. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/importlib_metadata/py.typed +0 -0
  91. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/typing_extensions.py +0 -0
  92. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_6/zipp.py +0 -0
  93. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/__init__.py +0 -0
  94. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/__init__.py +0 -0
  95. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +0 -0
  96. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_collections.py +0 -0
  97. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_compat.py +0 -0
  98. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_functools.py +0 -0
  99. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +0 -0
  100. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_meta.py +0 -0
  101. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/_text.py +0 -0
  102. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
  103. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/__init__.py +0 -0
  104. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_checkers.py +0 -0
  105. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_config.py +0 -0
  106. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_decorators.py +0 -0
  107. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_exceptions.py +0 -0
  108. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_functions.py +0 -0
  109. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_importhook.py +0 -0
  110. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_memo.py +0 -0
  111. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +0 -0
  112. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_suppression.py +0 -0
  113. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_transformer.py +0 -0
  114. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_union_transformer.py +0 -0
  115. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/_utils.py +0 -0
  116. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
  117. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/typing_extensions.py +0 -0
  118. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/v3_7/zipp.py +0 -0
  119. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/__init__.py +0 -0
  120. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/composer.py +0 -0
  121. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/constructor.py +0 -0
  122. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/cyaml.py +0 -0
  123. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/dumper.py +0 -0
  124. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/emitter.py +0 -0
  125. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/error.py +0 -0
  126. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/events.py +0 -0
  127. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/loader.py +0 -0
  128. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/nodes.py +0 -0
  129. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/parser.py +0 -0
  130. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/reader.py +0 -0
  131. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/representer.py +0 -0
  132. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/resolver.py +0 -0
  133. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/scanner.py +0 -0
  134. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/serializer.py +0 -0
  135. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/yaml/tokens.py +0 -0
  136. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/_vendor/zipp.py +0 -0
  137. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cards.py +0 -0
  138. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli.py +0 -0
  139. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_args.py +0 -0
  140. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_components/__init__.py +0 -0
  141. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_components/dump_cmd.py +0 -0
  142. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_components/init_cmd.py +0 -0
  143. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_components/run_cmds.py +0 -0
  144. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_components/step_cmd.py +0 -0
  145. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cli_components/utils.py +0 -0
  146. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/client/__init__.py +0 -0
  147. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/client/filecache.py +0 -0
  148. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/clone_util.py +0 -0
  149. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/__init__.py +0 -0
  150. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/code/__init__.py +0 -0
  151. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/configure_cmd.py +0 -0
  152. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/develop/__init__.py +0 -0
  153. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/develop/stub_generator.py +0 -0
  154. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/develop/stubs.py +0 -0
  155. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/main_cli.py +0 -0
  156. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/make_wrapper.py +0 -0
  157. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/tutorials_cmd.py +0 -0
  158. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd/util.py +0 -0
  159. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/cmd_with_io.py +0 -0
  160. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/__init__.py +0 -0
  161. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/content_addressed_store.py +0 -0
  162. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/datastore_set.py +0 -0
  163. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/datastore_storage.py +0 -0
  164. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/exceptions.py +0 -0
  165. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/flow_datastore.py +0 -0
  166. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/inputs.py +0 -0
  167. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/datastore/task_datastore.py +0 -0
  168. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/debug.py +0 -0
  169. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/decorators.py +0 -0
  170. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/event_logger.py +0 -0
  171. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/events.py +0 -0
  172. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/exception.py +0 -0
  173. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/extension_support/__init__.py +0 -0
  174. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/extension_support/_empty_file.py +0 -0
  175. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/extension_support/cmd.py +0 -0
  176. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/extension_support/integrations.py +0 -0
  177. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/extension_support/plugins.py +0 -0
  178. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/flowspec.py +0 -0
  179. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/graph.py +0 -0
  180. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/includefile.py +0 -0
  181. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/integrations.py +0 -0
  182. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/lint.py +0 -0
  183. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/meta_files.py +0 -0
  184. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metadata_provider/__init__.py +0 -0
  185. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metadata_provider/heartbeat.py +0 -0
  186. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metadata_provider/metadata.py +0 -0
  187. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metadata_provider/util.py +0 -0
  188. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_config_funcs.py +0 -0
  189. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_current.py +0 -0
  190. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_environment.py +0 -0
  191. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_git.py +0 -0
  192. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_profile.py +0 -0
  193. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/metaflow_version.py +0 -0
  194. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/mflog/__init__.py +0 -0
  195. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/mflog/mflog.py +0 -0
  196. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/mflog/save_logs.py +0 -0
  197. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/mflog/save_logs_periodically.py +0 -0
  198. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/mflog/tee.py +0 -0
  199. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/monitor.py +0 -0
  200. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/multicore_utils.py +0 -0
  201. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/package/__init__.py +0 -0
  202. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/packaging_sys/__init__.py +0 -0
  203. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/packaging_sys/backend.py +0 -0
  204. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/packaging_sys/distribution_support.py +0 -0
  205. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/packaging_sys/tar_backend.py +0 -0
  206. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/packaging_sys/utils.py +0 -0
  207. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/packaging_sys/v1.py +0 -0
  208. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/parameters.py +0 -0
  209. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/__init__.py +0 -0
  210. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/__init__.py +0 -0
  211. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/airflow.py +0 -0
  212. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/airflow_cli.py +0 -0
  213. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/airflow_decorator.py +0 -0
  214. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/airflow_utils.py +0 -0
  215. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/dag.py +0 -0
  216. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/exception.py +0 -0
  217. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/plumbing/__init__.py +0 -0
  218. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/plumbing/set_parameters.py +0 -0
  219. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/sensors/__init__.py +0 -0
  220. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/sensors/base_sensor.py +0 -0
  221. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/sensors/external_task_sensor.py +0 -0
  222. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/airflow/sensors/s3_sensor.py +0 -0
  223. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/__init__.py +0 -0
  224. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_events.py +0 -0
  225. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_workflows_cli.py +0 -0
  226. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_workflows_decorator.py +0 -0
  227. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_workflows_deployer.py +0 -0
  228. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/argo_workflows_deployer_objects.py +0 -0
  229. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/capture_error.py +0 -0
  230. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/exit_hooks.py +0 -0
  231. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/generate_input_paths.py +0 -0
  232. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/argo/jobset_input_paths.py +0 -0
  233. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/__init__.py +0 -0
  234. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/aws_client.py +0 -0
  235. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/aws_utils.py +0 -0
  236. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/batch/__init__.py +0 -0
  237. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/batch/batch_cli.py +0 -0
  238. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/batch/batch_client.py +0 -0
  239. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/batch/batch_decorator.py +0 -0
  240. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/secrets_manager/__init__.py +0 -0
  241. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +0 -0
  242. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/__init__.py +0 -0
  243. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -0
  244. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/event_bridge_client.py +0 -0
  245. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/production_token.py +0 -0
  246. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/schedule_decorator.py +0 -0
  247. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/set_batch_environment.py +0 -0
  248. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/step_functions_client.py +0 -0
  249. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/step_functions_decorator.py +0 -0
  250. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +0 -0
  251. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/__init__.py +0 -0
  252. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/azure_credential.py +0 -0
  253. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/azure_exceptions.py +0 -0
  254. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +0 -0
  255. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/azure_tail.py +0 -0
  256. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/azure_utils.py +0 -0
  257. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/blob_service_client_factory.py +0 -0
  258. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/azure/includefile_support.py +0 -0
  259. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/__init__.py +0 -0
  260. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_cli.py +0 -0
  261. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_client.py +0 -0
  262. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_creator.py +0 -0
  263. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_datastore.py +0 -0
  264. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_decorator.py +0 -0
  265. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/__init__.py +0 -0
  266. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/base.html +0 -0
  267. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/basic.py +0 -0
  268. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/bundle.css +0 -0
  269. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/card.py +0 -0
  270. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/chevron/__init__.py +0 -0
  271. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/chevron/main.py +0 -0
  272. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/chevron/metadata.py +0 -0
  273. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/chevron/renderer.py +0 -0
  274. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/chevron/tokenizer.py +0 -0
  275. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/components.py +0 -0
  276. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/convert_to_native_type.py +0 -0
  277. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/main.css +0 -0
  278. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/main.js +0 -0
  279. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/renderer_tools.py +0 -0
  280. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_modules/test_cards.py +0 -0
  281. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_resolver.py +0 -0
  282. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_server.py +0 -0
  283. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/card_viewer/viewer.html +0 -0
  284. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/component_serializer.py +0 -0
  285. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/exception.py +0 -0
  286. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/cards/metadata.py +0 -0
  287. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/catch_decorator.py +0 -0
  288. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datastores/__init__.py +0 -0
  289. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datastores/azure_storage.py +0 -0
  290. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datastores/gs_storage.py +0 -0
  291. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datastores/local_storage.py +0 -0
  292. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datastores/s3_storage.py +0 -0
  293. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/__init__.py +0 -0
  294. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/local.py +0 -0
  295. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/s3/__init__.py +0 -0
  296. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/s3/s3.py +0 -0
  297. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/s3/s3op.py +0 -0
  298. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/s3/s3tail.py +0 -0
  299. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/datatools/s3/s3util.py +0 -0
  300. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/debug_logger.py +0 -0
  301. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/debug_monitor.py +0 -0
  302. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/__init__.py +0 -0
  303. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/client.py +0 -0
  304. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/client_modules.py +0 -0
  305. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/communication/__init__.py +0 -0
  306. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/communication/bytestream.py +0 -0
  307. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/communication/channel.py +0 -0
  308. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/communication/socket_bytestream.py +0 -0
  309. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/communication/utils.py +0 -0
  310. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/configurations/emulate_test_lib/__init__.py +0 -0
  311. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/configurations/emulate_test_lib/overrides.py +0 -0
  312. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/configurations/emulate_test_lib/server_mappings.py +0 -0
  313. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/configurations/test_lib_impl/__init__.py +0 -0
  314. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/configurations/test_lib_impl/test_lib.py +0 -0
  315. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/consts.py +0 -0
  316. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/data_transferer.py +0 -0
  317. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/exception_transferer.py +0 -0
  318. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/override_decorators.py +0 -0
  319. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/server.py +0 -0
  320. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/stub.py +0 -0
  321. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/env_escape/utils.py +0 -0
  322. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/environment_decorator.py +0 -0
  323. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/events_decorator.py +0 -0
  324. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/exit_hook/__init__.py +0 -0
  325. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/exit_hook/exit_hook_decorator.py +0 -0
  326. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/exit_hook/exit_hook_script.py +0 -0
  327. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/frameworks/__init__.py +0 -0
  328. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/frameworks/pytorch.py +0 -0
  329. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/__init__.py +0 -0
  330. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +0 -0
  331. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/gs_exceptions.py +0 -0
  332. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/gs_storage_client_factory.py +0 -0
  333. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/gs_tail.py +0 -0
  334. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/gs_utils.py +0 -0
  335. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/gcp/includefile_support.py +0 -0
  336. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/__init__.py +0 -0
  337. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kube_utils.py +0 -0
  338. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kubernetes.py +0 -0
  339. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kubernetes_cli.py +0 -0
  340. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kubernetes_client.py +0 -0
  341. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kubernetes_decorator.py +0 -0
  342. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kubernetes_job.py +0 -0
  343. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/kubernetes_jobsets.py +0 -0
  344. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/spot_metadata_cli.py +0 -0
  345. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/kubernetes/spot_monitor_sidecar.py +0 -0
  346. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/logs_cli.py +0 -0
  347. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/metadata_providers/__init__.py +0 -0
  348. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/metadata_providers/local.py +0 -0
  349. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/metadata_providers/service.py +0 -0
  350. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/package_cli.py +0 -0
  351. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/parallel_decorator.py +0 -0
  352. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/project_decorator.py +0 -0
  353. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/__init__.py +0 -0
  354. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/bootstrap.py +0 -0
  355. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/conda_decorator.py +0 -0
  356. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/conda_environment.py +0 -0
  357. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/micromamba.py +0 -0
  358. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/parsers.py +0 -0
  359. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/pip.py +0 -0
  360. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/pypi_decorator.py +0 -0
  361. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/pypi_environment.py +0 -0
  362. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/pypi/utils.py +0 -0
  363. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/resources_decorator.py +0 -0
  364. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/retry_decorator.py +0 -0
  365. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/secrets/__init__.py +0 -0
  366. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/secrets/inline_secrets_provider.py +0 -0
  367. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/secrets/secrets_decorator.py +0 -0
  368. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/secrets/secrets_func.py +0 -0
  369. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/secrets/secrets_spec.py +0 -0
  370. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/secrets/utils.py +0 -0
  371. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/storage_executor.py +0 -0
  372. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/tag_cli.py +0 -0
  373. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/test_unbounded_foreach_decorator.py +0 -0
  374. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/timeout_decorator.py +0 -0
  375. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/uv/__init__.py +0 -0
  376. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/uv/bootstrap.py +0 -0
  377. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/plugins/uv/uv_environment.py +0 -0
  378. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/procpoll.py +0 -0
  379. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/py.typed +0 -0
  380. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/pylint_wrapper.py +0 -0
  381. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/__init__.py +0 -0
  382. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/click_api.py +0 -0
  383. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/deployer.py +0 -0
  384. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/deployer_impl.py +0 -0
  385. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/metaflow_runner.py +0 -0
  386. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/nbdeploy.py +0 -0
  387. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/nbrun.py +0 -0
  388. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/subprocess_manager.py +0 -0
  389. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runner/utils.py +0 -0
  390. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/runtime.py +0 -0
  391. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/sidecar/__init__.py +0 -0
  392. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/sidecar/sidecar.py +0 -0
  393. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/sidecar/sidecar_messages.py +0 -0
  394. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/sidecar/sidecar_subprocess.py +0 -0
  395. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/sidecar/sidecar_worker.py +0 -0
  396. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/system/__init__.py +0 -0
  397. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/system/system_logger.py +0 -0
  398. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/system/system_monitor.py +0 -0
  399. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/system/system_utils.py +0 -0
  400. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tagging_util.py +0 -0
  401. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/task.py +0 -0
  402. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tracing/__init__.py +0 -0
  403. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tracing/propagator.py +0 -0
  404. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tracing/span_exporter.py +0 -0
  405. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tracing/tracing_modules.py +0 -0
  406. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tuple_util.py +0 -0
  407. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/00-helloworld/README.md +0 -0
  408. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/00-helloworld/helloworld.py +0 -0
  409. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/01-playlist/README.md +0 -0
  410. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/01-playlist/movies.csv +0 -0
  411. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/01-playlist/playlist.ipynb +0 -0
  412. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/01-playlist/playlist.py +0 -0
  413. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/02-statistics/README.md +0 -0
  414. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/02-statistics/movies.csv +0 -0
  415. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/02-statistics/stats.ipynb +0 -0
  416. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/02-statistics/stats.py +0 -0
  417. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/03-playlist-redux/README.md +0 -0
  418. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/03-playlist-redux/playlist.py +0 -0
  419. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/04-playlist-plus/README.md +0 -0
  420. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/04-playlist-plus/playlist.py +0 -0
  421. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/05-hello-cloud/README.md +0 -0
  422. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/05-hello-cloud/hello-cloud.ipynb +0 -0
  423. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/05-hello-cloud/hello-cloud.py +0 -0
  424. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/06-statistics-redux/README.md +0 -0
  425. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/06-statistics-redux/stats.ipynb +0 -0
  426. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/07-worldview/README.md +0 -0
  427. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/07-worldview/worldview.ipynb +0 -0
  428. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/08-autopilot/README.md +0 -0
  429. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/tutorials/08-autopilot/autopilot.ipynb +0 -0
  430. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/unbounded_foreach.py +0 -0
  431. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_configs/__init__.py +0 -0
  432. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_configs/config_options.py +0 -0
  433. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_configs/config_parameters.py +0 -0
  434. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_decorators/__init__.py +0 -0
  435. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_decorators/common.py +0 -0
  436. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_decorators/mutable_flow.py +0 -0
  437. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_decorators/mutable_step.py +0 -0
  438. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_decorators/user_flow_decorator.py +0 -0
  439. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/user_decorators/user_step_decorator.py +0 -0
  440. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/util.py +0 -0
  441. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/metaflow/vendor.py +0 -0
  442. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/ob_metaflow.egg-info/SOURCES.txt +0 -0
  443. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/ob_metaflow.egg-info/dependency_links.txt +0 -0
  444. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/ob_metaflow.egg-info/entry_points.txt +0 -0
  445. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/ob_metaflow.egg-info/top_level.txt +0 -0
  446. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/setup.cfg +0 -0
  447. {ob_metaflow-2.18.2.1 → ob_metaflow-2.18.3.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ob-metaflow
3
- Version: 2.18.2.1
3
+ Version: 2.18.3.2
4
4
  Summary: Metaflow: More AI and ML, Less Engineering
5
5
  Author: Netflix, Outerbounds & the Metaflow Community
6
6
  Author-email: help@outerbounds.co
@@ -12,7 +12,7 @@ Requires-Dist: boto3
12
12
  Requires-Dist: pylint
13
13
  Requires-Dist: kubernetes
14
14
  Provides-Extra: stubs
15
- Requires-Dist: metaflow-stubs==2.18.2.1; extra == "stubs"
15
+ Requires-Dist: metaflow-stubs==2.18.3.2; extra == "stubs"
16
16
  Dynamic: author
17
17
  Dynamic: author-email
18
18
  Dynamic: description
@@ -303,7 +303,7 @@ class MetaflowObject(object):
303
303
  # distinguish between "attempt will happen" and "no such
304
304
  # attempt exists".
305
305
 
306
- if pathspec:
306
+ if pathspec and _object is None:
307
307
  ids = pathspec.split("/")
308
308
 
309
309
  if self._NAME == "flow" and len(ids) != 1:
@@ -345,6 +345,8 @@ SFN_S3_DISTRIBUTED_MAP_OUTPUT_PATH = from_conf(
345
345
  else None
346
346
  ),
347
347
  )
348
+ # Toggle for step command being part of the Step Function payload, or if it should be offloaded to S3
349
+ SFN_COMPRESS_STATE_MACHINE = from_conf("SFN_COMPRESS_STATE_MACHINE", False)
348
350
  ###
349
351
  # Kubernetes configuration
350
352
  ###
@@ -410,6 +412,9 @@ ARGO_EVENTS_INTERNAL_WEBHOOK_URL = from_conf(
410
412
  "ARGO_EVENTS_INTERNAL_WEBHOOK_URL", ARGO_EVENTS_WEBHOOK_URL
411
413
  )
412
414
  ARGO_EVENTS_WEBHOOK_AUTH = from_conf("ARGO_EVENTS_WEBHOOK_AUTH", "none")
415
+ ARGO_EVENTS_SENSOR_NAMESPACE = from_conf(
416
+ "ARGO_EVENTS_SENSOR_NAMESPACE", KUBERNETES_NAMESPACE
417
+ )
413
418
 
414
419
  ARGO_WORKFLOWS_UI_URL = from_conf("ARGO_WORKFLOWS_UI_URL")
415
420
 
@@ -1,5 +1,6 @@
1
1
  import json
2
2
 
3
+ from metaflow.metaflow_config import ARGO_EVENTS_SENSOR_NAMESPACE
3
4
  from metaflow.exception import MetaflowException
4
5
  from metaflow.plugins.kubernetes.kubernetes_client import KubernetesClient
5
6
 
@@ -377,12 +378,15 @@ class ArgoClient(object):
377
378
  json.loads(e.body)["message"] if e.body is not None else e.reason
378
379
  )
379
380
 
380
- def register_sensor(self, name, sensor=None):
381
+ def register_sensor(
382
+ self, name, sensor=None, sensor_namespace=ARGO_EVENTS_SENSOR_NAMESPACE
383
+ ):
381
384
  if sensor is None:
382
385
  sensor = {}
383
386
  # Unfortunately, Kubernetes client does not handle optimistic
384
387
  # concurrency control by itself unlike kubectl
385
388
  client = self._client.get()
389
+
386
390
  if not sensor:
387
391
  sensor["metadata"] = {}
388
392
 
@@ -392,7 +396,7 @@ class ArgoClient(object):
392
396
  ] = client.CustomObjectsApi().get_namespaced_custom_object(
393
397
  group=self._group,
394
398
  version=self._version,
395
- namespace=self._namespace,
399
+ namespace=sensor_namespace,
396
400
  plural="sensors",
397
401
  name=name,
398
402
  )[
@@ -407,7 +411,7 @@ class ArgoClient(object):
407
411
  return client.CustomObjectsApi().create_namespaced_custom_object(
408
412
  group=self._group,
409
413
  version=self._version,
410
- namespace=self._namespace,
414
+ namespace=sensor_namespace,
411
415
  plural="sensors",
412
416
  body=sensor,
413
417
  )
@@ -425,7 +429,7 @@ class ArgoClient(object):
425
429
  return client.CustomObjectsApi().replace_namespaced_custom_object(
426
430
  group=self._group,
427
431
  version=self._version,
428
- namespace=self._namespace,
432
+ namespace=sensor_namespace,
429
433
  plural="sensors",
430
434
  body=sensor,
431
435
  name=name,
@@ -435,7 +439,7 @@ class ArgoClient(object):
435
439
  json.loads(e.body)["message"] if e.body is not None else e.reason
436
440
  )
437
441
 
438
- def delete_sensor(self, name):
442
+ def delete_sensor(self, name, sensor_namespace):
439
443
  """
440
444
  Issues an API call for deleting a sensor
441
445
 
@@ -447,7 +451,7 @@ class ArgoClient(object):
447
451
  return client.CustomObjectsApi().delete_namespaced_custom_object(
448
452
  group=self._group,
449
453
  version=self._version,
450
- namespace=self._namespace,
454
+ namespace=sensor_namespace,
451
455
  plural="sensors",
452
456
  name=name,
453
457
  )
@@ -19,6 +19,7 @@ from metaflow.metaflow_config import (
19
19
  ARGO_EVENTS_EVENT_BUS,
20
20
  ARGO_EVENTS_EVENT_SOURCE,
21
21
  ARGO_EVENTS_INTERNAL_WEBHOOK_URL,
22
+ ARGO_EVENTS_SENSOR_NAMESPACE,
22
23
  ARGO_EVENTS_SERVICE_ACCOUNT,
23
24
  ARGO_EVENTS_WEBHOOK_AUTH,
24
25
  ARGO_WORKFLOWS_CAPTURE_ERROR_SCRIPT,
@@ -74,6 +75,10 @@ class ArgoWorkflowsException(MetaflowException):
74
75
  headline = "Argo Workflows error"
75
76
 
76
77
 
78
+ class ArgoWorkflowsSensorCleanupException(MetaflowException):
79
+ headline = "Argo Workflows sensor clean up error"
80
+
81
+
77
82
  class ArgoWorkflowsSchedulingException(MetaflowException):
78
83
  headline = "Argo Workflows scheduling error"
79
84
 
@@ -195,6 +200,7 @@ class ArgoWorkflows(object):
195
200
  return str(self._workflow_template)
196
201
 
197
202
  def deploy(self):
203
+ self.cleanup_previous_sensors()
198
204
  try:
199
205
  # Register workflow template.
200
206
  ArgoClient(namespace=KUBERNETES_NAMESPACE).register_workflow_template(
@@ -203,6 +209,37 @@ class ArgoWorkflows(object):
203
209
  except Exception as e:
204
210
  raise ArgoWorkflowsException(str(e))
205
211
 
212
+ def cleanup_previous_sensors(self):
213
+ try:
214
+ client = ArgoClient(namespace=KUBERNETES_NAMESPACE)
215
+ # Check for existing deployment and do cleanup
216
+ old_template = client.get_workflow_template(self.name)
217
+ if not old_template:
218
+ return None
219
+ # Clean up old sensors
220
+ old_sensor_namespace = old_template["metadata"]["annotations"].get(
221
+ "metaflow/sensor_namespace"
222
+ )
223
+
224
+ if old_sensor_namespace is None:
225
+ # This workflow was created before sensor annotations
226
+ # and may have a sensor in the default namespace
227
+ # we will delete it and it'll get recreated if need be
228
+ old_sensor_name = ArgoWorkflows._sensor_name(self.name)
229
+ client.delete_sensor(old_sensor_name, client._namespace)
230
+ else:
231
+ # delete old sensor only if it was somewhere else, otherwise it'll get replaced
232
+ old_sensor_name = old_template["metadata"]["annotations"][
233
+ "metaflow/sensor_name"
234
+ ]
235
+ if (
236
+ not self._sensor
237
+ or old_sensor_namespace != ARGO_EVENTS_SENSOR_NAMESPACE
238
+ ):
239
+ client.delete_sensor(old_sensor_name, old_sensor_namespace)
240
+ except Exception as e:
241
+ raise ArgoWorkflowsSensorCleanupException(str(e))
242
+
206
243
  @staticmethod
207
244
  def _sanitize(name):
208
245
  # Metaflow allows underscores in node names, which are disallowed in Argo
@@ -230,6 +267,20 @@ class ArgoWorkflows(object):
230
267
  def delete(name):
231
268
  client = ArgoClient(namespace=KUBERNETES_NAMESPACE)
232
269
 
270
+ # the workflow template might not exist, but we still want to try clean up associated sensors and schedules.
271
+ workflow_template = client.get_workflow_template(name) or {}
272
+ workflow_annotations = workflow_template.get("metadata", {}).get(
273
+ "annotations", {}
274
+ )
275
+
276
+ sensor_name = ArgoWorkflows._sensor_name(
277
+ workflow_annotations.get("metaflow/sensor_name", name)
278
+ )
279
+ # if below is missing then it was deployed before custom sensor namespaces
280
+ sensor_namespace = workflow_annotations.get(
281
+ "metaflow/sensor_namespace", KUBERNETES_NAMESPACE
282
+ )
283
+
233
284
  # Always try to delete the schedule. Failure in deleting the schedule should not
234
285
  # be treated as an error, due to any of the following reasons
235
286
  # - there might not have been a schedule, or it was deleted by some other means
@@ -239,7 +290,7 @@ class ArgoWorkflows(object):
239
290
 
240
291
  # The workflow might have sensors attached to it, which consume actual resources.
241
292
  # Try to delete these as well.
242
- sensor_deleted = client.delete_sensor(ArgoWorkflows._sensor_name(name))
293
+ sensor_deleted = client.delete_sensor(sensor_name, sensor_namespace)
243
294
 
244
295
  # After cleaning up related resources, delete the workflow in question.
245
296
  # Failure in deleting is treated as critical and will be made visible to the user
@@ -408,11 +459,10 @@ class ArgoWorkflows(object):
408
459
  # Metaflow will overwrite any existing sensor.
409
460
  sensor_name = ArgoWorkflows._sensor_name(self.name)
410
461
  if self._sensor:
411
- argo_client.register_sensor(sensor_name, self._sensor.to_json())
412
- else:
413
- # Since sensors occupy real resources, delete existing sensor if needed
414
- # Deregister sensors that might have existed before this deployment
415
- argo_client.delete_sensor(sensor_name)
462
+ # The new sensor will go into the sensor namespace specified
463
+ ArgoClient(namespace=ARGO_EVENTS_SENSOR_NAMESPACE).register_sensor(
464
+ sensor_name, self._sensor.to_json(), ARGO_EVENTS_SENSOR_NAMESPACE
465
+ )
416
466
  except Exception as e:
417
467
  raise ArgoWorkflowsSchedulingException(str(e))
418
468
 
@@ -739,6 +789,7 @@ class ArgoWorkflows(object):
739
789
  # references to them within the DAGTask.
740
790
 
741
791
  annotations = {}
792
+
742
793
  if self._schedule is not None:
743
794
  # timezone is an optional field and json dumps on None will result in null
744
795
  # hence configuring it to an empty string
@@ -761,7 +812,9 @@ class ArgoWorkflows(object):
761
812
  {key: trigger.get(key) for key in ["name", "type"]}
762
813
  for trigger in self.triggers
763
814
  ]
764
- )
815
+ ),
816
+ "metaflow/sensor_name": ArgoWorkflows._sensor_name(self.name),
817
+ "metaflow/sensor_namespace": ARGO_EVENTS_SENSOR_NAMESPACE,
765
818
  }
766
819
  )
767
820
  if self.notify_on_error:
@@ -940,7 +993,7 @@ class ArgoWorkflows(object):
940
993
  node_conditional_parents = {}
941
994
  node_conditional_branches = {}
942
995
 
943
- def _visit(node, seen, conditional_branch, conditional_parents=None):
996
+ def _visit(node, conditional_branch, conditional_parents=None):
944
997
  if not node.type == "split-switch" and not (
945
998
  conditional_branch and conditional_parents
946
999
  ):
@@ -949,7 +1002,10 @@ class ArgoWorkflows(object):
949
1002
 
950
1003
  if node.type == "split-switch":
951
1004
  conditional_branch = conditional_branch + [node.name]
952
- node_conditional_branches[node.name] = conditional_branch
1005
+ c_br = node_conditional_branches.get(node.name, [])
1006
+ node_conditional_branches[node.name] = c_br + [
1007
+ b for b in conditional_branch if b not in c_br
1008
+ ]
953
1009
 
954
1010
  conditional_parents = (
955
1011
  [node.name]
@@ -967,21 +1023,36 @@ class ArgoWorkflows(object):
967
1023
  if conditional_parents and not node.type == "split-switch":
968
1024
  node_conditional_parents[node.name] = conditional_parents
969
1025
  conditional_branch = conditional_branch + [node.name]
970
- node_conditional_branches[node.name] = conditional_branch
1026
+ c_br = node_conditional_branches.get(node.name, [])
1027
+ node_conditional_branches[node.name] = c_br + [
1028
+ b for b in conditional_branch if b not in c_br
1029
+ ]
971
1030
 
972
1031
  self.conditional_nodes.add(node.name)
973
1032
 
974
1033
  if conditional_branch and conditional_parents:
975
1034
  for n in node.out_funcs:
976
1035
  child = self.graph[n]
977
- if n not in seen:
978
- _visit(
979
- child, seen + [n], conditional_branch, conditional_parents
980
- )
1036
+ if child.name == node.name:
1037
+ continue
1038
+ _visit(child, conditional_branch, conditional_parents)
981
1039
 
982
1040
  # First we visit all nodes to determine conditional parents and branches
983
1041
  for n in self.graph:
984
- _visit(n, [], [])
1042
+ _visit(n, [])
1043
+
1044
+ # helper to clean up conditional info for all children of a node, until a new split-switch is encountered.
1045
+ def _cleanup_conditional_status(node_name, seen):
1046
+ if self.graph[node_name].type == "split-switch":
1047
+ # stop recursive cleanup if we hit a new split-switch
1048
+ return
1049
+ if node_name in self.conditional_nodes:
1050
+ self.conditional_nodes.remove(node_name)
1051
+ node_conditional_parents[node_name] = []
1052
+ node_conditional_branches[node_name] = []
1053
+ for p in self.graph[node_name].out_funcs:
1054
+ if p not in seen:
1055
+ _cleanup_conditional_status(p, seen + [p])
985
1056
 
986
1057
  # Then we traverse again in order to determine conditional join nodes, and matching conditional join info
987
1058
  for node in self.graph:
@@ -1014,14 +1085,44 @@ class ArgoWorkflows(object):
1014
1085
  last_conditional_split_nodes = self.graph[
1015
1086
  last_split_switch
1016
1087
  ].out_funcs
1017
- # p needs to be in at least one conditional_branch for it to be closed.
1018
- if all(
1019
- any(
1020
- p in node_conditional_branches.get(in_func, [])
1021
- for in_func in conditional_in_funcs
1088
+ # NOTE: How do we define a conditional join step?
1089
+ # The idea here is that we check if the conditional branches(e.g. chains of conditional steps leading to) of all the in_funcs
1090
+ # manage to tick off every step name that follows a split-switch
1091
+ # For example, consider the following structure
1092
+ # switch_step -> A, B, C
1093
+ # A -> A2 -> A3 -> A4 -> B2
1094
+ # B -> B2 -> B3 -> C3
1095
+ # C -> C2 -> C3 -> end
1096
+ #
1097
+ # if we look at the in_funcs for C3, they are (C2, B3)
1098
+ # B3 closes off branches started by A and B
1099
+ # C3 closes off branches started by C
1100
+ # therefore C3 is a conditional join step for the 'switch_step'
1101
+ # NOTE: Then what about a skip step?
1102
+ # some switch cases might not introduce any distinct steps of their own, opting to instead skip ahead to a later common step.
1103
+ # Example:
1104
+ # switch_step -> A, B, C
1105
+ # A -> A1 -> B2 -> C
1106
+ # B -> B1 -> B2 -> C
1107
+ #
1108
+ # In this case, C is a skip step as it does not add any conditional branching of its own.
1109
+ # C is also a conditional join, as it closes all branches started by 'switch_step'
1110
+
1111
+ closes_branches = all(
1112
+ (
1113
+ # branch_root_node_name needs to be in at least one conditional_branch for it to be closed.
1114
+ any(
1115
+ branch_root_node_name
1116
+ in node_conditional_branches.get(in_func, [])
1117
+ for in_func in conditional_in_funcs
1118
+ )
1119
+ # need to account for a switch case skipping completely, not having a conditional-branch of its own.
1120
+ if branch_root_node_name != node.name
1121
+ else True
1022
1122
  )
1023
- for p in last_conditional_split_nodes
1024
- ):
1123
+ for branch_root_node_name in last_conditional_split_nodes
1124
+ )
1125
+ if closes_branches:
1025
1126
  closed_conditional_parents.append(last_split_switch)
1026
1127
 
1027
1128
  self.conditional_join_nodes.add(node.name)
@@ -1035,25 +1136,45 @@ class ArgoWorkflows(object):
1035
1136
  for p in node_conditional_parents.get(node.name, [])
1036
1137
  if p not in closed_conditional_parents
1037
1138
  ]:
1038
- if node.name in self.conditional_nodes:
1039
- self.conditional_nodes.remove(node.name)
1040
- node_conditional_parents[node.name] = []
1041
- for p in node.out_funcs:
1042
- if p in self.conditional_nodes:
1043
- self.conditional_nodes.remove(p)
1044
- node_conditional_parents[p] = []
1139
+ _cleanup_conditional_status(node.name, [])
1045
1140
 
1046
1141
  def _is_conditional_node(self, node):
1047
1142
  return node.name in self.conditional_nodes
1048
1143
 
1144
+ def _is_conditional_skip_node(self, node):
1145
+ return (
1146
+ self._is_conditional_node(node)
1147
+ and any(
1148
+ self.graph[in_func].type == "split-switch" for in_func in node.in_funcs
1149
+ )
1150
+ and len(
1151
+ [
1152
+ in_func
1153
+ for in_func in node.in_funcs
1154
+ if self._is_conditional_node(self.graph[in_func])
1155
+ or self.graph[in_func].type == "split-switch"
1156
+ ]
1157
+ )
1158
+ > 1
1159
+ )
1160
+
1049
1161
  def _is_conditional_join_node(self, node):
1050
1162
  return node.name in self.conditional_join_nodes
1051
1163
 
1164
+ def _many_in_funcs_all_conditional(self, node):
1165
+ cond_in_funcs = [
1166
+ in_func
1167
+ for in_func in node.in_funcs
1168
+ if self._is_conditional_node(self.graph[in_func])
1169
+ ]
1170
+ return len(cond_in_funcs) > 1 and len(cond_in_funcs) == len(node.in_funcs)
1171
+
1052
1172
  def _is_recursive_node(self, node):
1053
1173
  return node.name in self.recursive_nodes
1054
1174
 
1055
1175
  def _matching_conditional_join(self, node):
1056
- return self.matching_conditional_join_dict.get(node.name, None)
1176
+ # If no earlier conditional join step is found during parsing, then 'end' is always one.
1177
+ return self.matching_conditional_join_dict.get(node.name, "end")
1057
1178
 
1058
1179
  # Visit every node and yield the uber DAGTemplate(s).
1059
1180
  def _dag_templates(self):
@@ -1233,12 +1354,24 @@ class ArgoWorkflows(object):
1233
1354
  "%s.Succeeded" % self._sanitize(in_func)
1234
1355
  for in_func in node.in_funcs
1235
1356
  if self._is_conditional_node(self.graph[in_func])
1357
+ or self.graph[in_func].type == "split-switch"
1236
1358
  ]
1237
1359
  required_deps = [
1238
1360
  "%s.Succeeded" % self._sanitize(in_func)
1239
1361
  for in_func in node.in_funcs
1240
1362
  if not self._is_conditional_node(self.graph[in_func])
1363
+ and self.graph[in_func].type != "split-switch"
1241
1364
  ]
1365
+ if self._is_conditional_skip_node(
1366
+ node
1367
+ ) or self._many_in_funcs_all_conditional(node):
1368
+ # skip nodes need unique condition handling
1369
+ conditional_deps = [
1370
+ "%s.Succeeded" % self._sanitize(in_func)
1371
+ for in_func in node.in_funcs
1372
+ ]
1373
+ required_deps = []
1374
+
1242
1375
  both_conditions = required_deps and conditional_deps
1243
1376
 
1244
1377
  depends_str = "{required}{_and}{conditional}".format(
@@ -1256,15 +1389,45 @@ class ArgoWorkflows(object):
1256
1389
  )
1257
1390
 
1258
1391
  # Add conditional if this is the first step in a conditional branch
1392
+ switch_in_funcs = [
1393
+ in_func
1394
+ for in_func in node.in_funcs
1395
+ if self.graph[in_func].type == "split-switch"
1396
+ ]
1259
1397
  if (
1260
1398
  self._is_conditional_node(node)
1261
- and self.graph[node.in_funcs[0]].type == "split-switch"
1262
- ):
1263
- in_func = node.in_funcs[0]
1264
- dag_task.when(
1265
- "{{tasks.%s.outputs.parameters.switch-step}}==%s"
1266
- % (self._sanitize(in_func), node.name)
1399
+ or self._is_conditional_skip_node(node)
1400
+ or self._is_conditional_join_node(node)
1401
+ ) and switch_in_funcs:
1402
+ conditional_when = "||".join(
1403
+ [
1404
+ "{{tasks.%s.outputs.parameters.switch-step}}==%s"
1405
+ % (self._sanitize(switch_in_func), node.name)
1406
+ for switch_in_func in switch_in_funcs
1407
+ ]
1408
+ )
1409
+
1410
+ non_switch_in_funcs = [
1411
+ in_func
1412
+ for in_func in node.in_funcs
1413
+ if in_func not in switch_in_funcs
1414
+ ]
1415
+ status_when = ""
1416
+ if non_switch_in_funcs:
1417
+ status_when = "||".join(
1418
+ [
1419
+ "{{tasks.%s.status}}==Succeeded"
1420
+ % self._sanitize(in_func)
1421
+ for in_func in non_switch_in_funcs
1422
+ ]
1423
+ )
1424
+
1425
+ total_when = (
1426
+ f"({status_when}) || ({conditional_when})"
1427
+ if status_when
1428
+ else conditional_when
1267
1429
  )
1430
+ dag_task.when(total_when)
1268
1431
 
1269
1432
  dag_tasks.append(dag_task)
1270
1433
  # End the workflow if we have reached the end of the flow
@@ -1708,7 +1871,11 @@ class ArgoWorkflows(object):
1708
1871
  input_paths_expr = (
1709
1872
  "export INPUT_PATHS={{inputs.parameters.input-paths}}"
1710
1873
  )
1711
- if self._is_conditional_join_node(node):
1874
+ if (
1875
+ self._is_conditional_join_node(node)
1876
+ or self._many_in_funcs_all_conditional(node)
1877
+ or self._is_conditional_skip_node(node)
1878
+ ):
1712
1879
  # NOTE: Argo template expressions that fail to resolve, output the expression itself as a value.
1713
1880
  # With conditional steps, some of the input-paths are therefore 'broken' due to containing a nil expression
1714
1881
  # e.g. "{{ tasks['A'].outputs.parameters.task-id }}" when task A never executed.
@@ -1888,20 +2055,33 @@ class ArgoWorkflows(object):
1888
2055
  )
1889
2056
  input_paths = "%s/_parameters/%s" % (run_id, task_id_params)
1890
2057
  # Only for static joins and conditional_joins
1891
- elif self._is_conditional_join_node(node) and not (
2058
+ elif (
2059
+ self._is_conditional_join_node(node)
2060
+ or self._many_in_funcs_all_conditional(node)
2061
+ or self._is_conditional_skip_node(node)
2062
+ ) and not (
1892
2063
  node.type == "join"
1893
2064
  and self.graph[node.split_parents[-1]].type == "foreach"
1894
2065
  ):
2066
+ # we need to pass in the set of conditional in_funcs to the pathspec generating script as in the case of split-switch skipping cases,
2067
+ # non-conditional input-paths need to be ignored in favour of conditional ones when they have executed.
2068
+ skippable_input_steps = ",".join(
2069
+ [
2070
+ in_func
2071
+ for in_func in node.in_funcs
2072
+ if self.graph[in_func].type == "split-switch"
2073
+ ]
2074
+ )
1895
2075
  input_paths = (
1896
- "$(python -m metaflow.plugins.argo.conditional_input_paths %s)"
1897
- % input_paths
2076
+ "$(python -m metaflow.plugins.argo.conditional_input_paths %s %s)"
2077
+ % (input_paths, skippable_input_steps)
1898
2078
  )
1899
2079
  elif (
1900
2080
  node.type == "join"
1901
2081
  and self.graph[node.split_parents[-1]].type == "foreach"
1902
2082
  ):
1903
2083
  # foreach-joins straight out of conditional branches are not yet supported
1904
- if self._is_conditional_join_node(node):
2084
+ if self._is_conditional_join_node(node) and len(node.in_funcs) > 1:
1905
2085
  raise ArgoWorkflowsException(
1906
2086
  "Conditional steps inside a foreach that transition directly into a join step are not currently supported.\n"
1907
2087
  "As a workaround, add a common step after the conditional steps %s "
@@ -3572,7 +3752,7 @@ class ArgoWorkflows(object):
3572
3752
  # Sensor metadata.
3573
3753
  ObjectMeta()
3574
3754
  .name(ArgoWorkflows._sensor_name(self.name))
3575
- .namespace(KUBERNETES_NAMESPACE)
3755
+ .namespace(ARGO_EVENTS_SENSOR_NAMESPACE)
3576
3756
  .labels(self._base_labels)
3577
3757
  .label("app.kubernetes.io/name", "metaflow-sensor")
3578
3758
  .annotations(self._base_annotations)
@@ -0,0 +1,35 @@
1
+ from math import inf
2
+ import sys
3
+ from metaflow.util import decompress_list, compress_list
4
+ import base64
5
+
6
+
7
+ def generate_input_paths(input_paths, skippable_steps):
8
+ # => run_id/step/:foo,bar
9
+ # input_paths are base64 encoded due to Argo shenanigans
10
+ decoded = base64.b64decode(input_paths).decode("utf-8")
11
+ paths = decompress_list(decoded)
12
+
13
+ # some of the paths are going to be malformed due to never having executed per conditional.
14
+ # strip these out of the list.
15
+
16
+ # all pathspecs of leading steps that executed.
17
+ trimmed = [path for path in paths if not "{{" in path]
18
+
19
+ # pathspecs of leading steps that are conditional, and should be used instead of non-conditional ones
20
+ # e.g. the case of skipping switches: start -> case_step -> conditional_a or end
21
+ conditionals = [
22
+ path for path in trimmed if not any(step in path for step in skippable_steps)
23
+ ]
24
+ pathspecs_to_use = conditionals if conditionals else trimmed
25
+ return compress_list(pathspecs_to_use, zlibmin=inf)
26
+
27
+
28
+ if __name__ == "__main__":
29
+ input_paths = sys.argv[1]
30
+ try:
31
+ skippable_steps = sys.argv[2].split(",")
32
+ except IndexError:
33
+ skippable_steps = []
34
+
35
+ print(generate_input_paths(input_paths, skippable_steps))
@@ -53,9 +53,10 @@ class BatchKilledException(MetaflowException):
53
53
 
54
54
 
55
55
  class Batch(object):
56
- def __init__(self, metadata, environment):
56
+ def __init__(self, metadata, environment, flow_datastore=None):
57
57
  self.metadata = metadata
58
58
  self.environment = environment
59
+ self.flow_datastore = flow_datastore
59
60
  self._client = BatchClient()
60
61
  atexit.register(lambda: self.job.kill() if hasattr(self, "job") else None)
61
62
 
@@ -67,6 +68,7 @@ class Batch(object):
67
68
  step_name,
68
69
  step_cmds,
69
70
  task_spec,
71
+ offload_command_to_s3,
70
72
  ):
71
73
  mflog_expr = export_mflog_env_vars(
72
74
  datastore_type="s3",
@@ -104,7 +106,43 @@ class Batch(object):
104
106
  # We lose the last logs in this scenario (although they are visible
105
107
  # still through AWS CloudWatch console).
106
108
  cmd_str += "c=$?; %s; exit $c" % BASH_SAVE_LOGS
107
- return shlex.split('bash -c "%s"' % cmd_str)
109
+ command = shlex.split('bash -c "%s"' % cmd_str)
110
+
111
+ if not offload_command_to_s3:
112
+ return command
113
+
114
+ # If S3 upload is enabled, we need to modify the command after it's created
115
+ if self.flow_datastore is None:
116
+ raise MetaflowException(
117
+ "Can not offload Batch command to S3 without a datastore configured."
118
+ )
119
+
120
+ from metaflow.plugins.aws.aws_utils import parse_s3_full_path
121
+
122
+ # Get the command that was created
123
+ # Upload the command to S3 during deployment
124
+ try:
125
+ command_bytes = cmd_str.encode("utf-8")
126
+ result_paths = self.flow_datastore.save_data([command_bytes], len_hint=1)
127
+ s3_path, _key = result_paths[0]
128
+
129
+ bucket, s3_object = parse_s3_full_path(s3_path)
130
+ download_script = "{python} -c '{script}'".format(
131
+ python=self.environment._python(),
132
+ script='import boto3, os; ep=os.getenv(\\"METAFLOW_S3_ENDPOINT_URL\\"); boto3.client(\\"s3\\", **({\\"endpoint_url\\":ep} if ep else {})).download_file(\\"%s\\", \\"%s\\", \\"/tmp/step_command.sh\\")'
133
+ % (bucket, s3_object),
134
+ )
135
+ download_cmd = (
136
+ f"{self.environment._get_install_dependencies_cmd('s3')} && " # required for boto3 due to the original dependencies cmd getting packaged, and not being downloaded in time.
137
+ f"{download_script} && "
138
+ f"chmod +x /tmp/step_command.sh && "
139
+ f"bash /tmp/step_command.sh"
140
+ )
141
+ new_cmd = shlex.split('bash -c "%s"' % download_cmd)
142
+ return new_cmd
143
+ except Exception as e:
144
+ print(f"Warning: Failed to upload command to S3: {e}")
145
+ print("Falling back to inline command")
108
146
 
109
147
  def _search_jobs(self, flow_name, run_id, user):
110
148
  if user is None:
@@ -207,6 +245,7 @@ class Batch(object):
207
245
  ephemeral_storage=None,
208
246
  log_driver=None,
209
247
  log_options=None,
248
+ offload_command_to_s3=False,
210
249
  ):
211
250
  job_name = self._job_name(
212
251
  attrs.get("metaflow.user"),
@@ -228,6 +267,7 @@ class Batch(object):
228
267
  step_name,
229
268
  [step_cli],
230
269
  task_spec,
270
+ offload_command_to_s3,
231
271
  )
232
272
  )
233
273
  .image(image)