ob-metaflow 2.12.25.1__tar.gz → 2.12.26.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 (360) hide show
  1. {ob_metaflow-2.12.25.1/ob_metaflow.egg-info → ob_metaflow-2.12.26.1}/PKG-INFO +2 -2
  2. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/client/core.py +6 -5
  3. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metaflow_config.py +7 -0
  4. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/__init__.py +5 -0
  5. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/argo_client.py +25 -9
  6. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/argo_workflows.py +4 -2
  7. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/argo_workflows_cli.py +2 -14
  8. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/argo_workflows_deployer.py +100 -0
  9. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/batch/batch_decorator.py +4 -0
  10. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/azure_tail.py +1 -1
  11. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_decorator.py +1 -0
  12. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/gs_tail.py +10 -6
  13. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kubernetes.py +12 -1
  14. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kubernetes_decorator.py +48 -11
  15. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/parallel_decorator.py +5 -4
  16. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/conda_environment.py +12 -4
  17. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/deployer.py +40 -1
  18. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/metaflow_runner.py +2 -13
  19. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/nbdeploy.py +4 -6
  20. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/nbrun.py +4 -6
  21. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/utils.py +0 -5
  22. ob_metaflow-2.12.26.1/metaflow/version.py +1 -0
  23. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1/ob_metaflow.egg-info}/PKG-INFO +2 -2
  24. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/ob_metaflow.egg-info/requires.txt +1 -1
  25. ob_metaflow-2.12.25.1/metaflow/version.py +0 -1
  26. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/LICENSE +0 -0
  27. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/MANIFEST.in +0 -0
  28. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/README.md +0 -0
  29. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/R.py +0 -0
  30. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/__init__.py +0 -0
  31. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/__init__.py +0 -0
  32. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/__init__.py +0 -0
  33. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/_bashcomplete.py +0 -0
  34. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/_compat.py +0 -0
  35. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/_termui_impl.py +0 -0
  36. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/_textwrap.py +0 -0
  37. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/_unicodefun.py +0 -0
  38. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/_winconsole.py +0 -0
  39. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/core.py +0 -0
  40. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/decorators.py +0 -0
  41. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/exceptions.py +0 -0
  42. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/formatting.py +0 -0
  43. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/globals.py +0 -0
  44. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/parser.py +0 -0
  45. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/termui.py +0 -0
  46. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/testing.py +0 -0
  47. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/types.py +0 -0
  48. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/click/utils.py +0 -0
  49. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/__init__.py +0 -0
  50. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_adapters.py +0 -0
  51. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_collections.py +0 -0
  52. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_compat.py +0 -0
  53. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_functools.py +0 -0
  54. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_itertools.py +0 -0
  55. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_meta.py +0 -0
  56. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/_text.py +0 -0
  57. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/importlib_metadata/py.typed +0 -0
  58. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/__init__.py +0 -0
  59. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/_elffile.py +0 -0
  60. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/_manylinux.py +0 -0
  61. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/_musllinux.py +0 -0
  62. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/_parser.py +0 -0
  63. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/_structures.py +0 -0
  64. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/_tokenizer.py +0 -0
  65. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/markers.py +0 -0
  66. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/py.typed +0 -0
  67. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/requirements.py +0 -0
  68. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/specifiers.py +0 -0
  69. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/tags.py +0 -0
  70. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/utils.py +0 -0
  71. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/packaging/version.py +0 -0
  72. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/__init__.py +0 -0
  73. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_checkers.py +0 -0
  74. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_config.py +0 -0
  75. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_decorators.py +0 -0
  76. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_exceptions.py +0 -0
  77. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_functions.py +0 -0
  78. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_importhook.py +0 -0
  79. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_memo.py +0 -0
  80. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_pytest_plugin.py +0 -0
  81. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_suppression.py +0 -0
  82. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_transformer.py +0 -0
  83. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_union_transformer.py +0 -0
  84. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/_utils.py +0 -0
  85. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typeguard/py.typed +0 -0
  86. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/typing_extensions.py +0 -0
  87. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_5/__init__.py +0 -0
  88. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -0
  89. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -0
  90. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_5/zipp.py +0 -0
  91. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/__init__.py +0 -0
  92. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/__init__.py +0 -0
  93. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_adapters.py +0 -0
  94. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_collections.py +0 -0
  95. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_compat.py +0 -0
  96. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_functools.py +0 -0
  97. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_itertools.py +0 -0
  98. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_meta.py +0 -0
  99. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/_text.py +0 -0
  100. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/importlib_metadata/py.typed +0 -0
  101. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/typing_extensions.py +0 -0
  102. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/v3_6/zipp.py +0 -0
  103. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/_vendor/zipp.py +0 -0
  104. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cards.py +0 -0
  105. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cli.py +0 -0
  106. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cli_args.py +0 -0
  107. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/client/__init__.py +0 -0
  108. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/client/filecache.py +0 -0
  109. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/clone_util.py +0 -0
  110. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/__init__.py +0 -0
  111. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/configure_cmd.py +0 -0
  112. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/develop/__init__.py +0 -0
  113. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/develop/stub_generator.py +0 -0
  114. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/develop/stubs.py +0 -0
  115. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/main_cli.py +0 -0
  116. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/tutorials_cmd.py +0 -0
  117. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd/util.py +0 -0
  118. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/cmd_with_io.py +0 -0
  119. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/__init__.py +0 -0
  120. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/content_addressed_store.py +0 -0
  121. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/datastore_set.py +0 -0
  122. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/datastore_storage.py +0 -0
  123. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/exceptions.py +0 -0
  124. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/flow_datastore.py +0 -0
  125. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/inputs.py +0 -0
  126. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/datastore/task_datastore.py +0 -0
  127. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/debug.py +0 -0
  128. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/decorators.py +0 -0
  129. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/event_logger.py +0 -0
  130. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/events.py +0 -0
  131. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/exception.py +0 -0
  132. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/extension_support/__init__.py +0 -0
  133. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/extension_support/_empty_file.py +0 -0
  134. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/extension_support/cmd.py +0 -0
  135. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/extension_support/integrations.py +0 -0
  136. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/extension_support/plugins.py +0 -0
  137. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/flowspec.py +0 -0
  138. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/graph.py +0 -0
  139. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/includefile.py +0 -0
  140. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/info_file.py +0 -0
  141. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/integrations.py +0 -0
  142. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/lint.py +0 -0
  143. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metadata/__init__.py +0 -0
  144. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metadata/heartbeat.py +0 -0
  145. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metadata/metadata.py +0 -0
  146. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metadata/util.py +0 -0
  147. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metaflow_config_funcs.py +0 -0
  148. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metaflow_current.py +0 -0
  149. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metaflow_environment.py +0 -0
  150. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metaflow_profile.py +0 -0
  151. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/metaflow_version.py +0 -0
  152. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/mflog/__init__.py +0 -0
  153. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/mflog/mflog.py +0 -0
  154. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/mflog/save_logs.py +0 -0
  155. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/mflog/save_logs_periodically.py +0 -0
  156. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/mflog/tee.py +0 -0
  157. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/monitor.py +0 -0
  158. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/multicore_utils.py +0 -0
  159. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/package.py +0 -0
  160. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/parameters.py +0 -0
  161. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/__init__.py +0 -0
  162. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/airflow.py +0 -0
  163. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/airflow_cli.py +0 -0
  164. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/airflow_decorator.py +0 -0
  165. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/airflow_utils.py +0 -0
  166. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/dag.py +0 -0
  167. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/exception.py +0 -0
  168. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/plumbing/__init__.py +0 -0
  169. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/plumbing/set_parameters.py +0 -0
  170. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/sensors/__init__.py +0 -0
  171. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/sensors/base_sensor.py +0 -0
  172. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/sensors/external_task_sensor.py +0 -0
  173. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/airflow/sensors/s3_sensor.py +0 -0
  174. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/__init__.py +0 -0
  175. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/argo_events.py +0 -0
  176. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/argo_workflows_decorator.py +0 -0
  177. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/capture_error.py +0 -0
  178. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/generate_input_paths.py +0 -0
  179. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/argo/jobset_input_paths.py +0 -0
  180. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/__init__.py +0 -0
  181. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/aws_client.py +0 -0
  182. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/aws_utils.py +0 -0
  183. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/batch/__init__.py +0 -0
  184. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/batch/batch.py +0 -0
  185. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/batch/batch_cli.py +0 -0
  186. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/batch/batch_client.py +0 -0
  187. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/secrets_manager/__init__.py +0 -0
  188. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +0 -0
  189. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/__init__.py +0 -0
  190. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -0
  191. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/event_bridge_client.py +0 -0
  192. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/production_token.py +0 -0
  193. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/schedule_decorator.py +0 -0
  194. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/set_batch_environment.py +0 -0
  195. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/step_functions.py +0 -0
  196. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/step_functions_cli.py +0 -0
  197. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/step_functions_client.py +0 -0
  198. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/step_functions_decorator.py +0 -0
  199. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/aws/step_functions/step_functions_deployer.py +0 -0
  200. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/__init__.py +0 -0
  201. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/azure_credential.py +0 -0
  202. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/azure_exceptions.py +0 -0
  203. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +0 -0
  204. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/azure_utils.py +0 -0
  205. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/blob_service_client_factory.py +0 -0
  206. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/azure/includefile_support.py +0 -0
  207. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/__init__.py +0 -0
  208. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_cli.py +0 -0
  209. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_client.py +0 -0
  210. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_creator.py +0 -0
  211. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_datastore.py +0 -0
  212. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/__init__.py +0 -0
  213. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/base.html +0 -0
  214. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/basic.py +0 -0
  215. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/bundle.css +0 -0
  216. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/card.py +0 -0
  217. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/chevron/__init__.py +0 -0
  218. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/chevron/main.py +0 -0
  219. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/chevron/metadata.py +0 -0
  220. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/chevron/renderer.py +0 -0
  221. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/chevron/tokenizer.py +0 -0
  222. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/components.py +0 -0
  223. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/convert_to_native_type.py +0 -0
  224. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/main.js +0 -0
  225. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/renderer_tools.py +0 -0
  226. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_modules/test_cards.py +0 -0
  227. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_resolver.py +0 -0
  228. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_server.py +0 -0
  229. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/card_viewer/viewer.html +0 -0
  230. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/component_serializer.py +0 -0
  231. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/cards/exception.py +0 -0
  232. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/catch_decorator.py +0 -0
  233. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datastores/__init__.py +0 -0
  234. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datastores/azure_storage.py +0 -0
  235. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datastores/gs_storage.py +0 -0
  236. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datastores/local_storage.py +0 -0
  237. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datastores/s3_storage.py +0 -0
  238. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/__init__.py +0 -0
  239. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/local.py +0 -0
  240. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/s3/__init__.py +0 -0
  241. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/s3/s3.py +0 -0
  242. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/s3/s3op.py +0 -0
  243. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/s3/s3tail.py +0 -0
  244. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/datatools/s3/s3util.py +0 -0
  245. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/debug_logger.py +0 -0
  246. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/debug_monitor.py +0 -0
  247. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/__init__.py +0 -0
  248. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/client.py +0 -0
  249. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/client_modules.py +0 -0
  250. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/communication/__init__.py +0 -0
  251. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/communication/bytestream.py +0 -0
  252. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/communication/channel.py +0 -0
  253. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/communication/socket_bytestream.py +0 -0
  254. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/communication/utils.py +0 -0
  255. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/configurations/emulate_test_lib/__init__.py +0 -0
  256. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/configurations/emulate_test_lib/overrides.py +0 -0
  257. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/configurations/emulate_test_lib/server_mappings.py +0 -0
  258. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/configurations/test_lib_impl/__init__.py +0 -0
  259. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/configurations/test_lib_impl/test_lib.py +0 -0
  260. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/consts.py +0 -0
  261. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/data_transferer.py +0 -0
  262. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/exception_transferer.py +0 -0
  263. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/override_decorators.py +0 -0
  264. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/server.py +0 -0
  265. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/stub.py +0 -0
  266. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/env_escape/utils.py +0 -0
  267. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/environment_decorator.py +0 -0
  268. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/events_decorator.py +0 -0
  269. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/frameworks/__init__.py +0 -0
  270. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/frameworks/pytorch.py +0 -0
  271. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/__init__.py +0 -0
  272. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +0 -0
  273. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/gs_exceptions.py +0 -0
  274. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/gs_storage_client_factory.py +0 -0
  275. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/gs_utils.py +0 -0
  276. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/gcp/includefile_support.py +0 -0
  277. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/__init__.py +0 -0
  278. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kube_utils.py +0 -0
  279. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kubernetes_cli.py +0 -0
  280. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kubernetes_client.py +0 -0
  281. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kubernetes_job.py +0 -0
  282. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/kubernetes/kubernetes_jobsets.py +0 -0
  283. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/logs_cli.py +0 -0
  284. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/metadata/__init__.py +0 -0
  285. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/metadata/local.py +0 -0
  286. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/metadata/service.py +0 -0
  287. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/package_cli.py +0 -0
  288. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/project_decorator.py +0 -0
  289. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/__init__.py +0 -0
  290. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/bootstrap.py +0 -0
  291. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/conda_decorator.py +0 -0
  292. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/micromamba.py +0 -0
  293. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/pip.py +0 -0
  294. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/pypi_decorator.py +0 -0
  295. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/pypi_environment.py +0 -0
  296. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/pypi/utils.py +0 -0
  297. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/resources_decorator.py +0 -0
  298. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/retry_decorator.py +0 -0
  299. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/secrets/__init__.py +0 -0
  300. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/secrets/inline_secrets_provider.py +0 -0
  301. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/secrets/secrets_decorator.py +0 -0
  302. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/storage_executor.py +0 -0
  303. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/tag_cli.py +0 -0
  304. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/test_unbounded_foreach_decorator.py +0 -0
  305. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/plugins/timeout_decorator.py +0 -0
  306. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/procpoll.py +0 -0
  307. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/py.typed +0 -0
  308. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/pylint_wrapper.py +0 -0
  309. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/__init__.py +0 -0
  310. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/click_api.py +0 -0
  311. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runner/subprocess_manager.py +0 -0
  312. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/runtime.py +0 -0
  313. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/sidecar/__init__.py +0 -0
  314. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/sidecar/sidecar.py +0 -0
  315. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/sidecar/sidecar_messages.py +0 -0
  316. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/sidecar/sidecar_subprocess.py +0 -0
  317. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/sidecar/sidecar_worker.py +0 -0
  318. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/system/__init__.py +0 -0
  319. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/system/system_logger.py +0 -0
  320. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/system/system_monitor.py +0 -0
  321. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/system/system_utils.py +0 -0
  322. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tagging_util.py +0 -0
  323. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/task.py +0 -0
  324. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tracing/__init__.py +0 -0
  325. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tracing/propagator.py +0 -0
  326. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tracing/span_exporter.py +0 -0
  327. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tracing/tracing_modules.py +0 -0
  328. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tuple_util.py +0 -0
  329. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/00-helloworld/README.md +0 -0
  330. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/00-helloworld/helloworld.py +0 -0
  331. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/01-playlist/README.md +0 -0
  332. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/01-playlist/movies.csv +0 -0
  333. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/01-playlist/playlist.ipynb +0 -0
  334. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/01-playlist/playlist.py +0 -0
  335. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/02-statistics/README.md +0 -0
  336. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/02-statistics/movies.csv +0 -0
  337. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/02-statistics/stats.ipynb +0 -0
  338. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/02-statistics/stats.py +0 -0
  339. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/03-playlist-redux/README.md +0 -0
  340. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/03-playlist-redux/playlist.py +0 -0
  341. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/04-playlist-plus/README.md +0 -0
  342. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/04-playlist-plus/playlist.py +0 -0
  343. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/05-hello-cloud/README.md +0 -0
  344. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/05-hello-cloud/hello-cloud.ipynb +0 -0
  345. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/05-hello-cloud/hello-cloud.py +0 -0
  346. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/06-statistics-redux/README.md +0 -0
  347. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/06-statistics-redux/stats.ipynb +0 -0
  348. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/07-worldview/README.md +0 -0
  349. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/07-worldview/worldview.ipynb +0 -0
  350. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/08-autopilot/README.md +0 -0
  351. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/tutorials/08-autopilot/autopilot.ipynb +0 -0
  352. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/unbounded_foreach.py +0 -0
  353. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/util.py +0 -0
  354. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/metaflow/vendor.py +0 -0
  355. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/ob_metaflow.egg-info/SOURCES.txt +0 -0
  356. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/ob_metaflow.egg-info/dependency_links.txt +0 -0
  357. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/ob_metaflow.egg-info/entry_points.txt +0 -0
  358. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/ob_metaflow.egg-info/top_level.txt +0 -0
  359. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/setup.cfg +0 -0
  360. {ob_metaflow-2.12.25.1 → ob_metaflow-2.12.26.1}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ob-metaflow
3
- Version: 2.12.25.1
3
+ Version: 2.12.26.1
4
4
  Summary: Metaflow: More Data Science, 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.12.25.1; extra == "stubs"
15
+ Requires-Dist: metaflow-stubs==2.12.26.1; extra == "stubs"
16
16
 
17
17
  ![Metaflow_Logo_Horizontal_FullColor_Ribbon_Dark_RGB](https://user-images.githubusercontent.com/763451/89453116-96a57e00-d713-11ea-9fa6-82b29d4d6eff.png)
18
18
 
@@ -670,7 +670,7 @@ class MetaflowObject(object):
670
670
  origin_pathspec = None
671
671
  if self._NAME == "run":
672
672
  latest_step = next(self.steps())
673
- if latest_step:
673
+ if latest_step and latest_step.task:
674
674
  # If we had a step
675
675
  task = latest_step.task
676
676
  origin_run_id = [
@@ -1888,9 +1888,10 @@ class Run(MetaflowObject):
1888
1888
  # TODO: A more optimized way of figuring out if a run has remote steps (and thus a codepackage) available.
1889
1889
  # This might require changes to the metadata-service as well.
1890
1890
  for step in self:
1891
- code = step.task.code
1892
- if code:
1893
- return code
1891
+ if step.task:
1892
+ code = step.task.code
1893
+ if code:
1894
+ return code
1894
1895
 
1895
1896
  @property
1896
1897
  def data(self) -> Optional[MetaflowData]:
@@ -2152,7 +2153,7 @@ class Run(MetaflowObject):
2152
2153
  Trigger, optional
2153
2154
  Container of triggering events
2154
2155
  """
2155
- if "start" in self:
2156
+ if "start" in self and self["start"].task:
2156
2157
  meta = self["start"].task.metadata_dict.get("execution-triggers")
2157
2158
  if meta:
2158
2159
  return Trigger(json.loads(meta))
@@ -411,6 +411,13 @@ AIRFLOW_KUBERNETES_KUBECONFIG_CONTEXT = from_conf(
411
411
  )
412
412
 
413
413
 
414
+ ###
415
+ # From Deployment configuration
416
+ ###
417
+ # From Deployment Configuration for DeployedFlow
418
+ FROM_DEPLOYMENT_IMPL = from_conf("FROM_DEPLOYMENT_IMPL", "argo-workflows")
419
+
420
+
414
421
  ###
415
422
  # Conda configuration
416
423
  ###
@@ -156,6 +156,11 @@ def get_plugin_cli():
156
156
  return resolve_plugins("cli")
157
157
 
158
158
 
159
+ # just a normal dictionary, not a plugin since there is no class..
160
+ FROM_DEPLOYMENT_PROVIDERS = {
161
+ "argo-workflows": "metaflow.plugins.argo.argo_workflows_deployer",
162
+ }
163
+
159
164
  STEP_DECORATORS = resolve_plugins("step_decorator")
160
165
  FLOW_DECORATORS = resolve_plugins("flow_decorator")
161
166
  ENVIRONMENTS = resolve_plugins("environment")
@@ -10,6 +10,14 @@ class ArgoClientException(MetaflowException):
10
10
  headline = "Argo Client error"
11
11
 
12
12
 
13
+ class ArgoResourceNotFound(MetaflowException):
14
+ headline = "Resource not found"
15
+
16
+
17
+ class ArgoNotPermitted(MetaflowException):
18
+ headline = "Operation not permitted"
19
+
20
+
13
21
  class ArgoClient(object):
14
22
  def __init__(self, namespace=None):
15
23
  self._client = KubernetesClient()
@@ -140,9 +148,7 @@ class ArgoClient(object):
140
148
  if e.status == 404:
141
149
  return None
142
150
  else:
143
- raise ArgoClientException(
144
- json.loads(e.body)["message"] if e.body is not None else e.reason
145
- )
151
+ raise wrap_api_error(e)
146
152
 
147
153
  def delete_workflow_template(self, name):
148
154
  """
@@ -164,9 +170,7 @@ class ArgoClient(object):
164
170
  if e.status == 404:
165
171
  return None
166
172
  else:
167
- raise ArgoClientException(
168
- json.loads(e.body)["message"] if e.body is not None else e.reason
169
- )
173
+ raise wrap_api_error(e)
170
174
 
171
175
  def terminate_workflow(self, name):
172
176
  client = self._client.get()
@@ -428,6 +432,18 @@ class ArgoClient(object):
428
432
  except client.rest.ApiException as e:
429
433
  if e.status == 404:
430
434
  return None
431
- raise ArgoClientException(
432
- json.loads(e.body)["message"] if e.body is not None else e.reason
433
- )
435
+ raise wrap_api_error(e)
436
+
437
+
438
+ def wrap_api_error(error):
439
+ message = (
440
+ json.loads(error.body)["message"] if error.body is not None else error.reason
441
+ )
442
+ # catch all
443
+ ex = ArgoClientException(message)
444
+ if error.status == 404:
445
+ # usually handled outside this function as most cases want to return None instead.
446
+ ex = ArgoResourceNotFound(message)
447
+ if error.status == 403:
448
+ ex = ArgoNotPermitted(message)
449
+ return ex
@@ -2311,7 +2311,9 @@ class ArgoWorkflows(object):
2311
2311
  and k not in set(ARGO_WORKFLOWS_ENV_VARS_TO_SKIP.split(","))
2312
2312
  }
2313
2313
  return [
2314
- Template("error-msg-capture-hook").container(
2314
+ Template("error-msg-capture-hook")
2315
+ .service_account_name(resources["service_account"])
2316
+ .container(
2315
2317
  to_camelcase(
2316
2318
  kubernetes_sdk.V1Container(
2317
2319
  name="main",
@@ -2462,7 +2464,7 @@ class ArgoWorkflows(object):
2462
2464
  Use Slack's Block Kit to add general information about the environment and
2463
2465
  execution metadata, including a link to the UI and an optional message.
2464
2466
  """
2465
- ui_link = "%s%s/argo-{{workflow.name}}" % (UI_URL, self.flow.name)
2467
+ ui_link = "%s/%s/argo-{{workflow.name}}" % (UI_URL.rstrip("/"), self.flow.name)
2466
2468
  # fmt: off
2467
2469
  if getattr(current, "project_name", None):
2468
2470
  # Add @project metadata when available.
@@ -1016,13 +1016,7 @@ def validate_run_id(
1016
1016
 
1017
1017
  if project_name is not None:
1018
1018
  # Verify we are operating on the correct project.
1019
- # Perform match with separators to avoid substrings matching
1020
- # e.g. 'test_proj' and 'test_project' should count as a mismatch.
1021
- project_part = "%s." % sanitize_for_argo(project_name)
1022
- if (
1023
- current.get("project_name") != project_name
1024
- and project_part not in workflow_name
1025
- ):
1019
+ if current.get("project_name") != project_name:
1026
1020
  raise RunIdMismatch(
1027
1021
  "The workflow belongs to the project *%s*. "
1028
1022
  "Please use the project decorator or --name to target the correct project"
@@ -1030,13 +1024,7 @@ def validate_run_id(
1030
1024
  )
1031
1025
 
1032
1026
  # Verify we are operating on the correct branch.
1033
- # Perform match with separators to avoid substrings matching.
1034
- # e.g. 'user.tes' and 'user.test' should count as a mismatch.
1035
- branch_part = ".%s." % sanitize_for_argo(branch_name)
1036
- if (
1037
- current.get("branch_name") != branch_name
1038
- and branch_part not in workflow_name
1039
- ):
1027
+ if current.get("branch_name") != branch_name:
1040
1028
  raise RunIdMismatch(
1041
1029
  "The workflow belongs to the branch *%s*. "
1042
1030
  "Please use --branch, --production or --name to target the correct branch"
@@ -1,9 +1,15 @@
1
1
  import sys
2
+ import json
2
3
  import tempfile
3
4
  from typing import Optional, ClassVar
4
5
 
6
+ from metaflow.client.core import get_metadata
7
+ from metaflow.exception import MetaflowException
8
+ from metaflow.plugins.argo.argo_client import ArgoClient
9
+ from metaflow.metaflow_config import KUBERNETES_NAMESPACE
5
10
  from metaflow.plugins.argo.argo_workflows import ArgoWorkflows
6
11
  from metaflow.runner.deployer import (
12
+ Deployer,
7
13
  DeployerImpl,
8
14
  DeployedFlow,
9
15
  TriggeredRun,
@@ -12,6 +18,100 @@ from metaflow.runner.deployer import (
12
18
  )
13
19
 
14
20
 
21
+ def generate_fake_flow_file_contents(
22
+ flow_name: str, param_info: dict, project_name: Optional[str] = None
23
+ ):
24
+ params_code = ""
25
+ for _, param_details in param_info.items():
26
+ param_name = param_details["name"]
27
+ param_type = param_details["type"]
28
+ param_help = param_details["description"]
29
+ param_required = param_details["is_required"]
30
+
31
+ if param_type == "JSON":
32
+ params_code += f" {param_name} = Parameter('{param_name}', type=JSONType, help='{param_help}', required={param_required})\n"
33
+ elif param_type == "FilePath":
34
+ is_text = param_details.get("is_text", True)
35
+ encoding = param_details.get("encoding", "utf-8")
36
+ params_code += f" {param_name} = IncludeFile('{param_name}', is_text={is_text}, encoding='{encoding}', help='{param_help}', required={param_required})\n"
37
+ else:
38
+ params_code += f" {param_name} = Parameter('{param_name}', type={param_type}, help='{param_help}', required={param_required})\n"
39
+
40
+ project_decorator = f"@project(name='{project_name}')\n" if project_name else ""
41
+
42
+ contents = f"""\
43
+ from metaflow import FlowSpec, Parameter, IncludeFile, JSONType, step, project
44
+ {project_decorator}class {flow_name}(FlowSpec):
45
+ {params_code}
46
+ @step
47
+ def start(self):
48
+ self.next(self.end)
49
+ @step
50
+ def end(self):
51
+ pass
52
+ if __name__ == '__main__':
53
+ {flow_name}()
54
+ """
55
+ return contents
56
+
57
+
58
+ def from_deployment(identifier: str, metadata: Optional[str] = None):
59
+ client = ArgoClient(namespace=KUBERNETES_NAMESPACE)
60
+ workflow_template = client.get_workflow_template(identifier)
61
+
62
+ if workflow_template is None:
63
+ raise MetaflowException("No deployed flow found for: %s" % identifier)
64
+
65
+ metadata_annotations = workflow_template.get("metadata", {}).get("annotations", {})
66
+
67
+ flow_name = metadata_annotations.get("metaflow/flow_name", "")
68
+ username = metadata_annotations.get("metaflow/owner", "")
69
+ parameters = json.loads(metadata_annotations.get("metaflow/parameters", {}))
70
+
71
+ # these two only exist if @project decorator is used..
72
+ branch_name = metadata_annotations.get("metaflow/branch_name", None)
73
+ project_name = metadata_annotations.get("metaflow/project_name", None)
74
+
75
+ project_kwargs = {}
76
+ if branch_name is not None:
77
+ if branch_name.startswith("prod."):
78
+ project_kwargs["production"] = True
79
+ project_kwargs["branch"] = branch_name[len("prod.") :]
80
+ elif branch_name.startswith("test."):
81
+ project_kwargs["branch"] = branch_name[len("test.") :]
82
+ elif branch_name == "prod":
83
+ project_kwargs["production"] = True
84
+
85
+ fake_flow_file_contents = generate_fake_flow_file_contents(
86
+ flow_name=flow_name, param_info=parameters, project_name=project_name
87
+ )
88
+
89
+ with tempfile.NamedTemporaryFile(suffix=".py", delete=False) as fake_flow_file:
90
+ with open(fake_flow_file.name, "w") as fp:
91
+ fp.write(fake_flow_file_contents)
92
+
93
+ if branch_name is not None:
94
+ d = Deployer(
95
+ fake_flow_file.name, env={"METAFLOW_USER": username}, **project_kwargs
96
+ ).argo_workflows()
97
+ else:
98
+ d = Deployer(
99
+ fake_flow_file.name, env={"METAFLOW_USER": username}
100
+ ).argo_workflows(name=identifier)
101
+
102
+ d.name = identifier
103
+ d.flow_name = flow_name
104
+ if metadata is None:
105
+ d.metadata = get_metadata()
106
+ else:
107
+ d.metadata = metadata
108
+
109
+ df = DeployedFlow(deployer=d)
110
+ d._enrich_deployed_flow(df)
111
+
112
+ return df
113
+
114
+
15
115
  def suspend(instance: TriggeredRun, **kwargs):
16
116
  """
17
117
  Suspend the running workflow.
@@ -134,6 +134,10 @@ class BatchDecorator(StepDecorator):
134
134
  package_sha = None
135
135
  run_time_limit = None
136
136
 
137
+ # Conda environment support
138
+ supports_conda_environment = True
139
+ target_platform = "linux-64"
140
+
137
141
  def __init__(self, attributes=None, statically_defined=False):
138
142
  super(BatchDecorator, self).__init__(attributes, statically_defined)
139
143
 
@@ -70,7 +70,7 @@ class AzureTail(object):
70
70
  if data is None:
71
71
  return None
72
72
  if data:
73
- buf = BytesIO(data)
73
+ buf = BytesIO(self._tail + data)
74
74
  self._pos += len(data)
75
75
  self._tail = b""
76
76
  return buf
@@ -117,6 +117,7 @@ class CardDecorator(StepDecorator):
117
117
  # `'%s-%s'%(evt_name,step_name)` ensures that we capture this once per @card per @step.
118
118
  # Since there can be many steps checking if event is registered for `evt_name` will only make it check it once for all steps.
119
119
  # Hence, we have `_is_event_registered('%s-%s'%(evt_name,step_name))`
120
+ self._is_runtime_card = False
120
121
  evt = "%s-%s" % (evt_name, step_name)
121
122
  if not self._is_event_registered(evt):
122
123
  # We set the total count of decorators so that we can use it for
@@ -11,15 +11,15 @@ from metaflow.plugins.gcp.gs_utils import parse_gs_full_path
11
11
  class GSTail(object):
12
12
  def __init__(self, blob_full_uri):
13
13
  """Location should be something like gs://<bucket_name>/blob"""
14
- bucket_name, blob_name = parse_gs_full_path(blob_full_uri)
15
- if not blob_name:
14
+ self.bucket_name, self.blob_name = parse_gs_full_path(blob_full_uri)
15
+ if not self.blob_name:
16
16
  raise MetaflowException(
17
17
  msg="Failed to parse blob_full_uri into gs://<bucket_name>/<blob_name> (got %s)"
18
18
  % blob_full_uri
19
19
  )
20
20
  client = get_gs_storage_client()
21
- bucket = client.bucket(bucket_name)
22
- self._blob_client = bucket.blob(blob_name)
21
+ self.bucket = client.bucket(self.bucket_name)
22
+ self._blob_client = self.bucket.blob(self.blob_name)
23
23
  self._pos = 0
24
24
  self._tail = b""
25
25
 
@@ -46,7 +46,11 @@ class GSTail(object):
46
46
  def _make_range_request(self):
47
47
  try:
48
48
  # Yes we read to the end... memory blow up is possible. We can improve by specifying length param
49
- return self._blob_client.download_as_bytes(start=self._pos)
49
+ # NOTE: We must re-instantiate the whole client here due to a behavior with the GS library,
50
+ # otherwise download_as_bytes will simply return the same content for consecutive requests with the same attributes,
51
+ # even if the blob has grown in size.
52
+ blob_client = self.bucket.blob(self.blob_name)
53
+ return blob_client.download_as_bytes(start=self._pos)
50
54
  except NotFound:
51
55
  return None
52
56
  except ClientError as e:
@@ -63,7 +67,7 @@ class GSTail(object):
63
67
  if data is None:
64
68
  return None
65
69
  if data:
66
- buf = BytesIO(data)
70
+ buf = BytesIO(self._tail + data)
67
71
  self._pos += len(data)
68
72
  self._tail = b""
69
73
  return buf
@@ -726,12 +726,23 @@ class Kubernetes(object):
726
726
  wait_for_launch(self._job)
727
727
 
728
728
  # 2) Tail logs until the job has finished
729
+ self._output_final_logs = False
730
+
731
+ def _has_updates():
732
+ if self._job.is_running:
733
+ return True
734
+ # Make sure to output final tail for a job that has finished.
735
+ if not self._output_final_logs:
736
+ self._output_final_logs = True
737
+ return True
738
+ return False
739
+
729
740
  tail_logs(
730
741
  prefix=prefix(),
731
742
  stdout_tail=stdout_tail,
732
743
  stderr_tail=stderr_tail,
733
744
  echo=echo,
734
- has_log_updates=lambda: self._job.is_running,
745
+ has_log_updates=_has_updates,
735
746
  )
736
747
  # 3) Fetch remaining logs
737
748
  #
@@ -2,6 +2,7 @@ import json
2
2
  import os
3
3
  import platform
4
4
  import sys
5
+ import time
5
6
 
6
7
  from metaflow import current
7
8
  from metaflow.decorators import StepDecorator
@@ -106,6 +107,9 @@ class KubernetesDecorator(StepDecorator):
106
107
  compute_pool : str, optional, default None
107
108
  Compute pool to be used for for this step.
108
109
  If not specified, any accessible compute pool within the perimeter is used.
110
+ hostname_resolution_timeout: int, default 10 * 60
111
+ Timeout in seconds for the workers tasks in the gang scheduled cluster to resolve the hostname of control task.
112
+ Only applicable when @parallel is used.
109
113
  """
110
114
 
111
115
  name = "kubernetes"
@@ -132,11 +136,16 @@ class KubernetesDecorator(StepDecorator):
132
136
  "port": None,
133
137
  "compute_pool": None,
134
138
  "executable": None,
139
+ "hostname_resolution_timeout": 10 * 60,
135
140
  }
136
141
  package_url = None
137
142
  package_sha = None
138
143
  run_time_limit = None
139
144
 
145
+ # Conda environment support
146
+ supports_conda_environment = True
147
+ target_platform = "linux-64"
148
+
140
149
  def __init__(self, attributes=None, statically_defined=False):
141
150
  super(KubernetesDecorator, self).__init__(attributes, statically_defined)
142
151
 
@@ -401,7 +410,7 @@ class KubernetesDecorator(StepDecorator):
401
410
  cli_args.command_args.append(self.package_url)
402
411
 
403
412
  # skip certain keys as CLI arguments
404
- _skip_keys = ["compute_pool"]
413
+ _skip_keys = ["compute_pool", "hostname_resolution_timeout"]
405
414
  # --namespace is used to specify Metaflow namespace (a different
406
415
  # concept from k8s namespace).
407
416
  for k, v in self.attributes.items():
@@ -493,7 +502,9 @@ class KubernetesDecorator(StepDecorator):
493
502
  num_parallel = flow._parallel_ubf_iter.num_parallel
494
503
 
495
504
  if num_parallel and num_parallel > 1:
496
- _setup_multinode_environment()
505
+ _setup_multinode_environment(
506
+ ubf_context, self.attributes["hostname_resolution_timeout"]
507
+ )
497
508
  # current.parallel.node_index will be correctly available over here.
498
509
  meta.update({"parallel-node-index": current.parallel.node_index})
499
510
  if ubf_context == UBF_CONTROL:
@@ -557,18 +568,44 @@ class KubernetesDecorator(StepDecorator):
557
568
 
558
569
 
559
570
  # TODO: Unify this method with the multi-node setup in @batch
560
- def _setup_multinode_environment():
561
- # TODO [FIXME SOON]
562
- # Even if Kubernetes may deploy control pods before worker pods, there is always a
563
- # possibility that the worker pods may start before the control. In the case that this happens,
564
- # the worker pods will not be able to resolve the control pod's IP address and this will cause
565
- # the worker pods to fail. This function should account for this in the near future.
571
+ def _setup_multinode_environment(ubf_context, hostname_resolution_timeout):
566
572
  import socket
567
573
 
574
+ def _wait_for_hostname_resolution(max_wait_timeout=10 * 60):
575
+ """
576
+ keep trying to resolve the hostname of the control task until the hostname is resolved
577
+ or the max_wait_timeout is reached. This is a workaround for the issue where the control
578
+ task is not scheduled before the worker task and the worker task fails because it cannot
579
+ resolve the hostname of the control task.
580
+ """
581
+ start_time = time.time()
582
+ while True:
583
+ try:
584
+ return socket.gethostbyname(os.environ["MF_MASTER_ADDR"])
585
+ except socket.gaierror:
586
+ if time.time() - start_time > max_wait_timeout:
587
+ raise MetaflowException(
588
+ "Failed to get host by name for MF_MASTER_ADDR after waiting for {} seconds.".format(
589
+ max_wait_timeout
590
+ )
591
+ )
592
+ time.sleep(1)
593
+
568
594
  try:
569
- os.environ["MF_PARALLEL_MAIN_IP"] = socket.gethostbyname(
570
- os.environ["MF_MASTER_ADDR"]
571
- )
595
+ # Even if Kubernetes may deploy control pods before worker pods, there is always a
596
+ # possibility that the worker pods may start before the control. In the case that this happens,
597
+ # the worker pods will not be able to resolve the control pod's IP address and this will cause
598
+ # the worker pods to fail. So if the worker pods are requesting a hostname resolution, we will
599
+ # make it wait for the name to be resolved within a reasonable timeout period.
600
+ if ubf_context != UBF_CONTROL:
601
+ os.environ["MF_PARALLEL_MAIN_IP"] = _wait_for_hostname_resolution(
602
+ hostname_resolution_timeout
603
+ )
604
+ else:
605
+ os.environ["MF_PARALLEL_MAIN_IP"] = socket.gethostbyname(
606
+ os.environ["MF_MASTER_ADDR"]
607
+ )
608
+
572
609
  os.environ["MF_PARALLEL_NUM_NODES"] = os.environ["MF_WORLD_SIZE"]
573
610
  os.environ["MF_PARALLEL_NODE_INDEX"] = (
574
611
  str(0)
@@ -13,18 +13,19 @@ class ParallelDecorator(StepDecorator):
13
13
  MF Add To Current
14
14
  -----------------
15
15
  parallel -> metaflow.metaflow_current.Parallel
16
+ Returns a namedtuple with relevant information about the parallel task.
16
17
 
17
18
  @@ Returns
18
19
  -------
19
20
  Parallel
20
21
  `namedtuple` with the following fields:
21
- - main_ip : str
22
+ - main_ip (`str`)
22
23
  The IP address of the control task.
23
- - num_nodes : int
24
+ - num_nodes (`int`)
24
25
  The total number of tasks created by @parallel
25
- - node_index : int
26
+ - node_index (`int`)
26
27
  The index of the current task in all the @parallel tasks.
27
- - control_task_id : Optional[str]
28
+ - control_task_id (`Optional[str]`)
28
29
  The task ID of the control task. Available to all tasks.
29
30
 
30
31
  is_parallel -> bool
@@ -269,11 +269,19 @@ class CondaEnvironment(MetaflowEnvironment):
269
269
  # Resolve `linux-64` Conda environments if @batch or @kubernetes are in play
270
270
  target_platform = conda_platform()
271
271
  for decorator in step.decorators:
272
- # TODO: rather than relying on decorator names, rely on attributes
273
- # to make them extensible.
274
- if decorator.name in ["batch", "kubernetes", "nvidia", "snowpark", "slurm"]:
272
+ # NOTE: Keep the list of supported decorator names for backward compatibility purposes.
273
+ # Older versions did not implement the 'support_conda_environment' attribute.
274
+ if getattr(
275
+ decorator, "supports_conda_environment", False
276
+ ) or decorator.name in [
277
+ "batch",
278
+ "kubernetes",
279
+ "nvidia",
280
+ "snowpark",
281
+ "slurm",
282
+ ]:
275
283
  # TODO: Support arm architectures
276
- target_platform = "linux-64"
284
+ target_platform = getattr(decorator, "target_platform", "linux-64")
277
285
  break
278
286
 
279
287
  environment["conda"]["platforms"] = [target_platform]
@@ -214,7 +214,43 @@ class TriggeredRun(object):
214
214
  return None
215
215
 
216
216
 
217
- class DeployedFlow(object):
217
+ class LazyDeploymentMethod:
218
+ def __init__(self, module_path, func_name):
219
+ self.module_path = module_path
220
+ self.func_name = func_name
221
+ self.func = None
222
+
223
+ def __call__(self, *args, **kwargs):
224
+ if self.func is None:
225
+ module = importlib.import_module(self.module_path)
226
+ self.func = getattr(module, self.func_name)
227
+ return self.func(*args, **kwargs)
228
+
229
+
230
+ class DeploymentMethodsMeta(type):
231
+ from metaflow.plugins import FROM_DEPLOYMENT_PROVIDERS
232
+ from metaflow.metaflow_config import FROM_DEPLOYMENT_IMPL
233
+
234
+ def __new__(mcs, name, bases, dct):
235
+ cls = super().__new__(mcs, name, bases, dct)
236
+
237
+ def from_deployment(identifier, metadata=None, impl=None):
238
+ if impl is None:
239
+ impl = mcs.FROM_DEPLOYMENT_IMPL
240
+
241
+ if impl not in mcs.FROM_DEPLOYMENT_PROVIDERS:
242
+ raise ValueError("This method is not available for: %s" % impl)
243
+
244
+ module_path = mcs.FROM_DEPLOYMENT_PROVIDERS[impl]
245
+ lazy_method = LazyDeploymentMethod(module_path, "from_deployment")
246
+ return lazy_method(identifier=identifier, metadata=metadata)
247
+
248
+ setattr(cls, "from_deployment", staticmethod(from_deployment))
249
+
250
+ return cls
251
+
252
+
253
+ class DeployedFlow(metaclass=DeploymentMethodsMeta):
218
254
  """
219
255
  DeployedFlow class represents a flow that has been deployed.
220
256
 
@@ -226,6 +262,9 @@ class DeployedFlow(object):
226
262
 
227
263
  def __init__(self, deployer: "DeployerImpl"):
228
264
  self.deployer = deployer
265
+ self.name = self.deployer.name
266
+ self.flow_name = self.deployer.flow_name
267
+ self.metadata = self.deployer.metadata
229
268
 
230
269
  def _enrich_object(self, env):
231
270
  """
@@ -8,7 +8,7 @@ from typing import Dict, Iterator, Optional, Tuple
8
8
 
9
9
  from metaflow import Run, metadata
10
10
 
11
- from .utils import handle_timeout, clear_and_set_os_environ
11
+ from .utils import handle_timeout
12
12
  from .subprocess_manager import CommandManager, SubprocessManager
13
13
 
14
14
 
@@ -249,8 +249,7 @@ class Runner(object):
249
249
  self.flow_file = flow_file
250
250
  self.show_output = show_output
251
251
 
252
- self.old_env = os.environ.copy()
253
- self.env_vars = self.old_env.copy()
252
+ self.env_vars = os.environ.copy()
254
253
  self.env_vars.update(env or {})
255
254
  if profile:
256
255
  self.env_vars["METAFLOW_PROFILE"] = profile
@@ -268,22 +267,12 @@ class Runner(object):
268
267
  return self
269
268
 
270
269
  def __get_executing_run(self, tfp_runner_attribute, command_obj):
271
- # When two 'Runner' executions are done sequentially i.e. one after the other
272
- # the 2nd run kinda uses the 1st run's previously set metadata and
273
- # environment variables.
274
-
275
- # It is thus necessary to set them to correct values before we return
276
- # the Run object.
277
-
278
270
  content = handle_timeout(
279
271
  tfp_runner_attribute, command_obj, self.file_read_timeout
280
272
  )
281
273
  content = json.loads(content)
282
274
  pathspec = "%s/%s" % (content.get("flow_name"), content.get("run_id"))
283
275
 
284
- # Set the environment variables to what they were before the run executed.
285
- clear_and_set_os_environ(self.old_env)
286
-
287
276
  # Set the correct metadata from the runner_attribute file corresponding to this run.
288
277
  metadata_for_flow = content.get("metadata")
289
278
  metadata(metadata_for_flow)