ob-metaflow-stubs 6.0.10.9__py2.py3-none-any.whl → 6.0.10.10__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ob-metaflow-stubs might be problematic. Click here for more details.

Files changed (262) hide show
  1. metaflow-stubs/__init__.pyi +1172 -1048
  2. metaflow-stubs/cards.pyi +1 -1
  3. metaflow-stubs/cli.pyi +1 -1
  4. metaflow-stubs/cli_components/__init__.pyi +1 -1
  5. metaflow-stubs/cli_components/utils.pyi +1 -1
  6. metaflow-stubs/client/__init__.pyi +1 -1
  7. metaflow-stubs/client/core.pyi +3 -3
  8. metaflow-stubs/client/filecache.pyi +1 -1
  9. metaflow-stubs/events.pyi +1 -1
  10. metaflow-stubs/exception.pyi +1 -1
  11. metaflow-stubs/flowspec.pyi +4 -4
  12. metaflow-stubs/generated_for.txt +1 -1
  13. metaflow-stubs/includefile.pyi +2 -2
  14. metaflow-stubs/meta_files.pyi +1 -1
  15. metaflow-stubs/metadata_provider/__init__.pyi +1 -1
  16. metaflow-stubs/metadata_provider/heartbeat.pyi +1 -1
  17. metaflow-stubs/metadata_provider/metadata.pyi +1 -1
  18. metaflow-stubs/metadata_provider/util.pyi +1 -1
  19. metaflow-stubs/metaflow_config.pyi +1 -1
  20. metaflow-stubs/metaflow_current.pyi +80 -80
  21. metaflow-stubs/metaflow_git.pyi +1 -1
  22. metaflow-stubs/mf_extensions/__init__.pyi +1 -1
  23. metaflow-stubs/mf_extensions/obcheckpoint/__init__.pyi +1 -1
  24. metaflow-stubs/mf_extensions/obcheckpoint/plugins/__init__.pyi +1 -1
  25. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/__init__.pyi +1 -1
  26. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/card_utils/__init__.pyi +1 -1
  27. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/card_utils/async_cards.pyi +2 -2
  28. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/card_utils/deco_injection_mixin.pyi +1 -1
  29. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/card_utils/extra_components.pyi +2 -2
  30. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/__init__.pyi +1 -1
  31. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/cards/__init__.pyi +1 -1
  32. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/cards/checkpoint_lister.pyi +3 -3
  33. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/cards/lineage_card.pyi +1 -1
  34. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/checkpoint_storage.pyi +2 -2
  35. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/constructors.pyi +1 -1
  36. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/core.pyi +1 -1
  37. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/decorator.pyi +3 -3
  38. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/exceptions.pyi +1 -1
  39. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/final_api.pyi +1 -1
  40. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/checkpoints/lineage.pyi +1 -1
  41. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/__init__.pyi +1 -1
  42. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/context.pyi +2 -2
  43. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/core.pyi +2 -2
  44. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/decorator.pyi +1 -1
  45. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/exceptions.pyi +1 -1
  46. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/task_utils.pyi +2 -2
  47. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastore/utils.pyi +1 -1
  48. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/datastructures.pyi +1 -1
  49. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/exceptions.pyi +1 -1
  50. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/hf_hub/__init__.pyi +1 -1
  51. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/hf_hub/decorator.pyi +1 -1
  52. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/modeling_utils/__init__.pyi +1 -1
  53. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/modeling_utils/core.pyi +2 -2
  54. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/modeling_utils/exceptions.pyi +1 -1
  55. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/modeling_utils/model_storage.pyi +2 -2
  56. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/__init__.pyi +1 -1
  57. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/flowspec_utils.pyi +1 -1
  58. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/general.pyi +1 -1
  59. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/identity_utils.pyi +2 -2
  60. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/serialization_handler/__init__.pyi +1 -1
  61. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/serialization_handler/base.pyi +1 -1
  62. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/serialization_handler/tar.pyi +1 -1
  63. metaflow-stubs/mf_extensions/obcheckpoint/plugins/machine_learning_utilities/utils/tar_utils.pyi +1 -1
  64. metaflow-stubs/mf_extensions/outerbounds/__init__.pyi +1 -1
  65. metaflow-stubs/mf_extensions/outerbounds/plugins/__init__.pyi +1 -1
  66. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/__init__.pyi +1 -1
  67. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/__init__.pyi +1 -1
  68. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/_state_machine.pyi +1 -1
  69. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/_vendor/__init__.pyi +1 -1
  70. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/_vendor/spinner/__init__.pyi +1 -1
  71. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/_vendor/spinner/spinners.pyi +1 -1
  72. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/app_cli.pyi +1 -1
  73. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/app_config.pyi +2 -2
  74. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/capsule.pyi +3 -3
  75. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/click_importer.pyi +1 -1
  76. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/code_package/__init__.pyi +1 -1
  77. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/code_package/code_packager.pyi +2 -2
  78. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/config/__init__.pyi +1 -1
  79. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/config/cli_generator.pyi +1 -1
  80. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/config/config_utils.pyi +2 -2
  81. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/config/schema_export.pyi +1 -1
  82. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/config/typed_configs.pyi +2 -2
  83. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/config/unified_config.pyi +1 -1
  84. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/dependencies.pyi +2 -2
  85. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/deployer.pyi +4 -4
  86. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/experimental/__init__.pyi +1 -1
  87. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/perimeters.pyi +1 -1
  88. metaflow-stubs/mf_extensions/outerbounds/plugins/apps/core/utils.pyi +3 -3
  89. metaflow-stubs/mf_extensions/outerbounds/plugins/aws/__init__.pyi +1 -1
  90. metaflow-stubs/mf_extensions/outerbounds/plugins/aws/assume_role_decorator.pyi +2 -2
  91. metaflow-stubs/mf_extensions/outerbounds/plugins/card_utilities/__init__.pyi +1 -1
  92. metaflow-stubs/mf_extensions/outerbounds/plugins/card_utilities/async_cards.pyi +2 -2
  93. metaflow-stubs/mf_extensions/outerbounds/plugins/card_utilities/injector.pyi +1 -1
  94. metaflow-stubs/mf_extensions/outerbounds/plugins/checkpoint_datastores/__init__.pyi +1 -1
  95. metaflow-stubs/mf_extensions/outerbounds/plugins/checkpoint_datastores/coreweave.pyi +1 -1
  96. metaflow-stubs/mf_extensions/outerbounds/plugins/checkpoint_datastores/nebius.pyi +1 -1
  97. metaflow-stubs/mf_extensions/outerbounds/plugins/fast_bakery/__init__.pyi +1 -1
  98. metaflow-stubs/mf_extensions/outerbounds/plugins/fast_bakery/baker.pyi +2 -2
  99. metaflow-stubs/mf_extensions/outerbounds/plugins/fast_bakery/docker_environment.pyi +1 -1
  100. metaflow-stubs/mf_extensions/outerbounds/plugins/fast_bakery/fast_bakery.pyi +1 -1
  101. metaflow-stubs/mf_extensions/outerbounds/plugins/kubernetes/__init__.pyi +1 -1
  102. metaflow-stubs/mf_extensions/outerbounds/plugins/kubernetes/pod_killer.pyi +1 -1
  103. metaflow-stubs/mf_extensions/outerbounds/plugins/ollama/__init__.pyi +1 -1
  104. metaflow-stubs/mf_extensions/outerbounds/plugins/ollama/constants.pyi +1 -1
  105. metaflow-stubs/mf_extensions/outerbounds/plugins/ollama/exceptions.pyi +1 -1
  106. metaflow-stubs/mf_extensions/outerbounds/plugins/ollama/ollama.pyi +1 -1
  107. metaflow-stubs/mf_extensions/outerbounds/plugins/ollama/status_card.pyi +1 -1
  108. metaflow-stubs/mf_extensions/outerbounds/plugins/snowflake/__init__.pyi +1 -1
  109. metaflow-stubs/mf_extensions/outerbounds/plugins/snowflake/snowflake.pyi +1 -1
  110. metaflow-stubs/mf_extensions/outerbounds/profilers/__init__.pyi +1 -1
  111. metaflow-stubs/mf_extensions/outerbounds/profilers/gpu.pyi +1 -1
  112. metaflow-stubs/mf_extensions/outerbounds/remote_config.pyi +1 -1
  113. metaflow-stubs/mf_extensions/outerbounds/toplevel/__init__.pyi +1 -1
  114. metaflow-stubs/mf_extensions/outerbounds/toplevel/global_aliases_for_metaflow_package.pyi +57 -1
  115. metaflow-stubs/mf_extensions/outerbounds/toplevel/s3_proxy.pyi +1 -1
  116. metaflow-stubs/multicore_utils.pyi +1 -1
  117. metaflow-stubs/ob_internal.pyi +1 -1
  118. metaflow-stubs/packaging_sys/__init__.pyi +5 -5
  119. metaflow-stubs/packaging_sys/backend.pyi +3 -3
  120. metaflow-stubs/packaging_sys/distribution_support.pyi +3 -3
  121. metaflow-stubs/packaging_sys/tar_backend.pyi +4 -4
  122. metaflow-stubs/packaging_sys/utils.pyi +1 -1
  123. metaflow-stubs/packaging_sys/v1.pyi +2 -2
  124. metaflow-stubs/parameters.pyi +2 -2
  125. metaflow-stubs/plugins/__init__.pyi +14 -14
  126. metaflow-stubs/plugins/airflow/__init__.pyi +1 -1
  127. metaflow-stubs/plugins/airflow/airflow_utils.pyi +1 -1
  128. metaflow-stubs/plugins/airflow/exception.pyi +1 -1
  129. metaflow-stubs/plugins/airflow/sensors/__init__.pyi +1 -1
  130. metaflow-stubs/plugins/airflow/sensors/base_sensor.pyi +1 -1
  131. metaflow-stubs/plugins/airflow/sensors/external_task_sensor.pyi +1 -1
  132. metaflow-stubs/plugins/airflow/sensors/s3_sensor.pyi +1 -1
  133. metaflow-stubs/plugins/argo/__init__.pyi +1 -1
  134. metaflow-stubs/plugins/argo/argo_client.pyi +1 -1
  135. metaflow-stubs/plugins/argo/argo_events.pyi +1 -1
  136. metaflow-stubs/plugins/argo/argo_workflows.pyi +2 -2
  137. metaflow-stubs/plugins/argo/argo_workflows_decorator.pyi +3 -3
  138. metaflow-stubs/plugins/argo/argo_workflows_deployer.pyi +2 -2
  139. metaflow-stubs/plugins/argo/argo_workflows_deployer_objects.pyi +2 -2
  140. metaflow-stubs/plugins/argo/exit_hooks.pyi +1 -1
  141. metaflow-stubs/plugins/aws/__init__.pyi +1 -1
  142. metaflow-stubs/plugins/aws/aws_client.pyi +1 -1
  143. metaflow-stubs/plugins/aws/aws_utils.pyi +1 -1
  144. metaflow-stubs/plugins/aws/batch/__init__.pyi +1 -1
  145. metaflow-stubs/plugins/aws/batch/batch.pyi +1 -1
  146. metaflow-stubs/plugins/aws/batch/batch_client.pyi +1 -1
  147. metaflow-stubs/plugins/aws/batch/batch_decorator.pyi +1 -1
  148. metaflow-stubs/plugins/aws/secrets_manager/__init__.pyi +1 -1
  149. metaflow-stubs/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.pyi +4 -4
  150. metaflow-stubs/plugins/aws/step_functions/__init__.pyi +1 -1
  151. metaflow-stubs/plugins/aws/step_functions/event_bridge_client.pyi +1 -1
  152. metaflow-stubs/plugins/aws/step_functions/schedule_decorator.pyi +1 -1
  153. metaflow-stubs/plugins/aws/step_functions/step_functions.pyi +1 -1
  154. metaflow-stubs/plugins/aws/step_functions/step_functions_client.pyi +1 -1
  155. metaflow-stubs/plugins/aws/step_functions/step_functions_deployer.pyi +2 -2
  156. metaflow-stubs/plugins/aws/step_functions/step_functions_deployer_objects.pyi +1 -1
  157. metaflow-stubs/plugins/azure/__init__.pyi +1 -1
  158. metaflow-stubs/plugins/azure/azure_credential.pyi +1 -1
  159. metaflow-stubs/plugins/azure/azure_exceptions.pyi +1 -1
  160. metaflow-stubs/plugins/azure/azure_secret_manager_secrets_provider.pyi +4 -4
  161. metaflow-stubs/plugins/azure/azure_utils.pyi +1 -1
  162. metaflow-stubs/plugins/azure/blob_service_client_factory.pyi +1 -1
  163. metaflow-stubs/plugins/azure/includefile_support.pyi +1 -1
  164. metaflow-stubs/plugins/cards/__init__.pyi +1 -1
  165. metaflow-stubs/plugins/cards/card_client.pyi +2 -2
  166. metaflow-stubs/plugins/cards/card_creator.pyi +1 -1
  167. metaflow-stubs/plugins/cards/card_datastore.pyi +1 -1
  168. metaflow-stubs/plugins/cards/card_decorator.pyi +1 -1
  169. metaflow-stubs/plugins/cards/card_modules/__init__.pyi +1 -1
  170. metaflow-stubs/plugins/cards/card_modules/basic.pyi +2 -2
  171. metaflow-stubs/plugins/cards/card_modules/card.pyi +1 -1
  172. metaflow-stubs/plugins/cards/card_modules/components.pyi +3 -3
  173. metaflow-stubs/plugins/cards/card_modules/convert_to_native_type.pyi +1 -1
  174. metaflow-stubs/plugins/cards/card_modules/renderer_tools.pyi +1 -1
  175. metaflow-stubs/plugins/cards/card_modules/test_cards.pyi +1 -1
  176. metaflow-stubs/plugins/cards/card_resolver.pyi +1 -1
  177. metaflow-stubs/plugins/cards/component_serializer.pyi +1 -1
  178. metaflow-stubs/plugins/cards/exception.pyi +1 -1
  179. metaflow-stubs/plugins/catch_decorator.pyi +2 -2
  180. metaflow-stubs/plugins/datatools/__init__.pyi +1 -1
  181. metaflow-stubs/plugins/datatools/local.pyi +1 -1
  182. metaflow-stubs/plugins/datatools/s3/__init__.pyi +1 -1
  183. metaflow-stubs/plugins/datatools/s3/s3.pyi +3 -3
  184. metaflow-stubs/plugins/datatools/s3/s3tail.pyi +1 -1
  185. metaflow-stubs/plugins/datatools/s3/s3util.pyi +1 -1
  186. metaflow-stubs/plugins/debug_logger.pyi +1 -1
  187. metaflow-stubs/plugins/debug_monitor.pyi +1 -1
  188. metaflow-stubs/plugins/environment_decorator.pyi +1 -1
  189. metaflow-stubs/plugins/events_decorator.pyi +1 -1
  190. metaflow-stubs/plugins/exit_hook/__init__.pyi +1 -1
  191. metaflow-stubs/plugins/exit_hook/exit_hook_decorator.pyi +1 -1
  192. metaflow-stubs/plugins/frameworks/__init__.pyi +1 -1
  193. metaflow-stubs/plugins/frameworks/pytorch.pyi +1 -1
  194. metaflow-stubs/plugins/gcp/__init__.pyi +1 -1
  195. metaflow-stubs/plugins/gcp/gcp_secret_manager_secrets_provider.pyi +4 -4
  196. metaflow-stubs/plugins/gcp/gs_exceptions.pyi +1 -1
  197. metaflow-stubs/plugins/gcp/gs_storage_client_factory.pyi +1 -1
  198. metaflow-stubs/plugins/gcp/gs_utils.pyi +1 -1
  199. metaflow-stubs/plugins/gcp/includefile_support.pyi +1 -1
  200. metaflow-stubs/plugins/kubernetes/__init__.pyi +1 -1
  201. metaflow-stubs/plugins/kubernetes/kube_utils.pyi +1 -1
  202. metaflow-stubs/plugins/kubernetes/kubernetes.pyi +1 -1
  203. metaflow-stubs/plugins/kubernetes/kubernetes_client.pyi +1 -1
  204. metaflow-stubs/plugins/kubernetes/kubernetes_decorator.pyi +1 -1
  205. metaflow-stubs/plugins/kubernetes/kubernetes_jobsets.pyi +1 -1
  206. metaflow-stubs/plugins/kubernetes/spot_monitor_sidecar.pyi +1 -1
  207. metaflow-stubs/plugins/ollama/__init__.pyi +1 -1
  208. metaflow-stubs/plugins/optuna/__init__.pyi +1 -1
  209. metaflow-stubs/plugins/parallel_decorator.pyi +1 -1
  210. metaflow-stubs/plugins/perimeters.pyi +1 -1
  211. metaflow-stubs/plugins/project_decorator.pyi +1 -1
  212. metaflow-stubs/plugins/pypi/__init__.pyi +2 -2
  213. metaflow-stubs/plugins/pypi/conda_decorator.pyi +1 -1
  214. metaflow-stubs/plugins/pypi/conda_environment.pyi +5 -5
  215. metaflow-stubs/plugins/pypi/parsers.pyi +1 -1
  216. metaflow-stubs/plugins/pypi/pypi_decorator.pyi +1 -1
  217. metaflow-stubs/plugins/pypi/pypi_environment.pyi +1 -1
  218. metaflow-stubs/plugins/pypi/utils.pyi +1 -1
  219. metaflow-stubs/plugins/resources_decorator.pyi +1 -1
  220. metaflow-stubs/plugins/retry_decorator.pyi +1 -1
  221. metaflow-stubs/plugins/secrets/__init__.pyi +2 -2
  222. metaflow-stubs/plugins/secrets/inline_secrets_provider.pyi +3 -3
  223. metaflow-stubs/plugins/secrets/secrets_decorator.pyi +1 -1
  224. metaflow-stubs/plugins/secrets/secrets_func.pyi +1 -1
  225. metaflow-stubs/plugins/secrets/secrets_spec.pyi +1 -1
  226. metaflow-stubs/plugins/secrets/utils.pyi +1 -1
  227. metaflow-stubs/plugins/snowflake/__init__.pyi +1 -1
  228. metaflow-stubs/plugins/storage_executor.pyi +1 -1
  229. metaflow-stubs/plugins/test_unbounded_foreach_decorator.pyi +1 -1
  230. metaflow-stubs/plugins/timeout_decorator.pyi +2 -2
  231. metaflow-stubs/plugins/torchtune/__init__.pyi +1 -1
  232. metaflow-stubs/plugins/uv/__init__.pyi +1 -1
  233. metaflow-stubs/plugins/uv/uv_environment.pyi +1 -1
  234. metaflow-stubs/profilers/__init__.pyi +1 -1
  235. metaflow-stubs/pylint_wrapper.pyi +1 -1
  236. metaflow-stubs/runner/__init__.pyi +1 -1
  237. metaflow-stubs/runner/deployer.pyi +4 -4
  238. metaflow-stubs/runner/deployer_impl.pyi +2 -2
  239. metaflow-stubs/runner/metaflow_runner.pyi +2 -2
  240. metaflow-stubs/runner/nbdeploy.pyi +1 -1
  241. metaflow-stubs/runner/nbrun.pyi +1 -1
  242. metaflow-stubs/runner/subprocess_manager.pyi +1 -1
  243. metaflow-stubs/runner/utils.pyi +2 -2
  244. metaflow-stubs/system/__init__.pyi +1 -1
  245. metaflow-stubs/system/system_logger.pyi +2 -2
  246. metaflow-stubs/system/system_monitor.pyi +1 -1
  247. metaflow-stubs/tagging_util.pyi +1 -1
  248. metaflow-stubs/tuple_util.pyi +1 -1
  249. metaflow-stubs/user_configs/__init__.pyi +1 -1
  250. metaflow-stubs/user_configs/config_options.pyi +2 -2
  251. metaflow-stubs/user_configs/config_parameters.pyi +6 -6
  252. metaflow-stubs/user_decorators/__init__.pyi +1 -1
  253. metaflow-stubs/user_decorators/common.pyi +1 -1
  254. metaflow-stubs/user_decorators/mutable_flow.pyi +5 -5
  255. metaflow-stubs/user_decorators/mutable_step.pyi +5 -5
  256. metaflow-stubs/user_decorators/user_flow_decorator.pyi +3 -3
  257. metaflow-stubs/user_decorators/user_step_decorator.pyi +4 -4
  258. {ob_metaflow_stubs-6.0.10.9.dist-info → ob_metaflow_stubs-6.0.10.10.dist-info}/METADATA +1 -1
  259. ob_metaflow_stubs-6.0.10.10.dist-info/RECORD +262 -0
  260. ob_metaflow_stubs-6.0.10.9.dist-info/RECORD +0 -262
  261. {ob_metaflow_stubs-6.0.10.9.dist-info → ob_metaflow_stubs-6.0.10.10.dist-info}/WHEEL +0 -0
  262. {ob_metaflow_stubs-6.0.10.9.dist-info → ob_metaflow_stubs-6.0.10.10.dist-info}/top_level.txt +0 -0
@@ -1,15 +1,15 @@
1
1
  ######################################################################################################
2
2
  # Auto-generated Metaflow stub file #
3
3
  # MF version: 2.18.7.5+obcheckpoint(0.2.7);ob(v1) #
4
- # Generated on 2025-09-23T00:18:02.202668 #
4
+ # Generated on 2025-09-23T01:34:30.897811 #
5
5
  ######################################################################################################
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
9
  import typing
10
10
  if typing.TYPE_CHECKING:
11
- import typing
12
11
  import datetime
12
+ import typing
13
13
  FlowSpecDerived = typing.TypeVar("FlowSpecDerived", bound="FlowSpec", contravariant=False, covariant=False)
14
14
  StepFlag = typing.NewType("StepFlag", bool)
15
15
 
@@ -39,18 +39,18 @@ from .user_decorators.user_step_decorator import UserStepDecorator as UserStepDe
39
39
  from .user_decorators.user_step_decorator import StepMutator as StepMutator
40
40
  from .user_decorators.user_step_decorator import user_step_decorator as user_step_decorator
41
41
  from .user_decorators.user_flow_decorator import FlowMutator as FlowMutator
42
+ from . import tuple_util as tuple_util
42
43
  from . import cards as cards
43
- from . import events as events
44
44
  from . import metaflow_git as metaflow_git
45
- from . import tuple_util as tuple_util
45
+ from . import events as events
46
46
  from . import runner as runner
47
47
  from . import plugins as plugins
48
48
  from .mf_extensions.outerbounds.toplevel.global_aliases_for_metaflow_package import S3 as S3
49
49
  from . import includefile as includefile
50
50
  from .includefile import IncludeFile as IncludeFile
51
- from .plugins.pypi.parsers import requirements_txt_parser as requirements_txt_parser
52
51
  from .plugins.pypi.parsers import pyproject_toml_parser as pyproject_toml_parser
53
52
  from .plugins.pypi.parsers import conda_environment_yml_parser as conda_environment_yml_parser
53
+ from .plugins.pypi.parsers import requirements_txt_parser as requirements_txt_parser
54
54
  from . import client as client
55
55
  from .client.core import namespace as namespace
56
56
  from .client.core import get_namespace as get_namespace
@@ -77,6 +77,7 @@ from .mf_extensions.outerbounds.toplevel.s3_proxy import get_S3_with_s3_proxy as
77
77
  from .mf_extensions.outerbounds.toplevel.global_aliases_for_metaflow_package import set_s3_proxy_config as set_s3_proxy_config
78
78
  from .mf_extensions.outerbounds.toplevel.global_aliases_for_metaflow_package import clear_s3_proxy_config as clear_s3_proxy_config
79
79
  from .mf_extensions.outerbounds.toplevel.global_aliases_for_metaflow_package import get_s3_proxy_config as get_s3_proxy_config
80
+ from .mf_extensions.outerbounds.toplevel.global_aliases_for_metaflow_package import get_s3_proxy_config_from_env as get_s3_proxy_config_from_env
80
81
  from .mf_extensions.outerbounds.toplevel.global_aliases_for_metaflow_package import get_aws_client as get_aws_client
81
82
  from .mf_extensions.outerbounds.plugins.snowflake.snowflake import Snowflake as Snowflake
82
83
  from .mf_extensions.outerbounds.plugins.checkpoint_datastores.nebius import nebius_checkpoints as nebius_checkpoints
@@ -186,232 +187,232 @@ def test_append_card(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag]
186
187
  """
187
188
  ...
188
189
 
189
- def ollama(*, models: list, backend: str, force_pull: bool, cache_update_policy: str, force_cache_update: bool, debug: bool, circuit_breaker_config: dict, timeout_config: dict) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
190
+ @typing.overload
191
+ def model(*, load: typing.Union[typing.List[str], str, typing.List[typing.Tuple[str, typing.Optional[str]]]] = None, temp_dir_root: str = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
190
192
  """
191
- This decorator is used to run Ollama APIs as Metaflow task sidecars.
193
+ Enables loading / saving of models within a step.
192
194
 
193
- User code call
194
- --------------
195
- @ollama(
196
- models=[...],
197
- ...
198
- )
195
+ > Examples
196
+ - Saving Models
197
+ ```python
198
+ @model
199
+ @step
200
+ def train(self):
201
+ # current.model.save returns a dictionary reference to the model saved
202
+ self.my_model = current.model.save(
203
+ path_to_my_model,
204
+ label="my_model",
205
+ metadata={
206
+ "epochs": 10,
207
+ "batch-size": 32,
208
+ "learning-rate": 0.001,
209
+ }
210
+ )
211
+ self.next(self.test)
199
212
 
200
- Valid backend options
201
- ---------------------
202
- - 'local': Run as a separate process on the local task machine.
203
- - (TODO) 'managed': Outerbounds hosts and selects compute provider.
204
- - (TODO) 'remote': Spin up separate instance to serve Ollama models.
213
+ @model(load="my_model")
214
+ @step
215
+ def test(self):
216
+ # `current.model.loaded` returns a dictionary of the loaded models
217
+ # where the key is the name of the artifact and the value is the path to the model
218
+ print(os.listdir(current.model.loaded["my_model"]))
219
+ self.next(self.end)
220
+ ```
205
221
 
206
- Valid model options
207
- -------------------
208
- Any model here https://ollama.com/search, e.g. 'llama3.2', 'llama3.3'
222
+ - Loading models
223
+ ```python
224
+ @step
225
+ def train(self):
226
+ # current.model.load returns the path to the model loaded
227
+ checkpoint_path = current.model.load(
228
+ self.checkpoint_key,
229
+ )
230
+ model_path = current.model.load(
231
+ self.model,
232
+ )
233
+ self.next(self.test)
234
+ ```
209
235
 
210
236
 
211
237
  Parameters
212
238
  ----------
213
- models: list[str]
214
- List of Ollama containers running models in sidecars.
215
- backend: str
216
- Determines where and how to run the Ollama process.
217
- force_pull: bool
218
- Whether to run `ollama pull` no matter what, or first check the remote cache in Metaflow datastore for this model key.
219
- cache_update_policy: str
220
- Cache update policy: "auto", "force", or "never".
221
- force_cache_update: bool
222
- Simple override for "force" cache update policy.
223
- debug: bool
224
- Whether to turn on verbose debugging logs.
225
- circuit_breaker_config: dict
226
- Configuration for circuit breaker protection. Keys: failure_threshold, recovery_timeout, reset_timeout.
227
- timeout_config: dict
228
- Configuration for various operation timeouts. Keys: pull, stop, health_check, install, server_startup.
239
+ load : Union[List[str],str,List[Tuple[str,Union[str,None]]]], default: None
240
+ Artifact name/s referencing the models/checkpoints to load. Artifact names refer to the names of the instance variables set to `self`.
241
+ These artifact names give to `load` be reference objects or reference `key` string's from objects created by `current.checkpoint` / `current.model` / `current.huggingface_hub`.
242
+ If a list of tuples is provided, the first element is the artifact name and the second element is the path the artifact needs be unpacked on
243
+ the local filesystem. If the second element is None, the artifact will be unpacked in the current working directory.
244
+ If a string is provided, then the artifact corresponding to that name will be loaded in the current working directory.
245
+
246
+ temp_dir_root : str, default: None
247
+ The root directory under which `current.model.loaded` will store loaded models
229
248
  """
230
249
  ...
231
250
 
232
- def vllm(*, model: str, backend: str, openai_api_server: bool, debug: bool, card_refresh_interval: int, max_retries: int, retry_alert_frequency: int, engine_args: dict) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
251
+ @typing.overload
252
+ def model(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
253
+ ...
254
+
255
+ @typing.overload
256
+ def model(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
257
+ ...
258
+
259
+ def model(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, load: typing.Union[typing.List[str], str, typing.List[typing.Tuple[str, typing.Optional[str]]]] = None, temp_dir_root: str = None):
233
260
  """
234
- This decorator is used to run vllm APIs as Metaflow task sidecars.
235
-
236
- User code call
237
- --------------
238
- @vllm(
239
- model="...",
240
- ...
241
- )
261
+ Enables loading / saving of models within a step.
242
262
 
243
- Valid backend options
244
- ---------------------
245
- - 'local': Run as a separate process on the local task machine.
263
+ > Examples
264
+ - Saving Models
265
+ ```python
266
+ @model
267
+ @step
268
+ def train(self):
269
+ # current.model.save returns a dictionary reference to the model saved
270
+ self.my_model = current.model.save(
271
+ path_to_my_model,
272
+ label="my_model",
273
+ metadata={
274
+ "epochs": 10,
275
+ "batch-size": 32,
276
+ "learning-rate": 0.001,
277
+ }
278
+ )
279
+ self.next(self.test)
246
280
 
247
- Valid model options
248
- -------------------
249
- Any HuggingFace model identifier, e.g. 'meta-llama/Llama-3.2-1B'
281
+ @model(load="my_model")
282
+ @step
283
+ def test(self):
284
+ # `current.model.loaded` returns a dictionary of the loaded models
285
+ # where the key is the name of the artifact and the value is the path to the model
286
+ print(os.listdir(current.model.loaded["my_model"]))
287
+ self.next(self.end)
288
+ ```
250
289
 
251
- NOTE: vLLM's OpenAI-compatible server serves ONE model per server instance.
252
- If you need multiple models, you must create multiple @vllm decorators.
290
+ - Loading models
291
+ ```python
292
+ @step
293
+ def train(self):
294
+ # current.model.load returns the path to the model loaded
295
+ checkpoint_path = current.model.load(
296
+ self.checkpoint_key,
297
+ )
298
+ model_path = current.model.load(
299
+ self.model,
300
+ )
301
+ self.next(self.test)
302
+ ```
253
303
 
254
304
 
255
305
  Parameters
256
306
  ----------
257
- model: str
258
- HuggingFace model identifier to be served by vLLM.
259
- backend: str
260
- Determines where and how to run the vLLM process.
261
- openai_api_server: bool
262
- Whether to use OpenAI-compatible API server mode (subprocess) instead of native engine.
263
- Default is False (uses native engine).
264
- Set to True for backward compatibility with existing code.
265
- debug: bool
266
- Whether to turn on verbose debugging logs.
267
- card_refresh_interval: int
268
- Interval in seconds for refreshing the vLLM status card.
269
- Only used when openai_api_server=True.
270
- max_retries: int
271
- Maximum number of retries checking for vLLM server startup.
272
- Only used when openai_api_server=True.
273
- retry_alert_frequency: int
274
- Frequency of alert logs for vLLM server startup retries.
275
- Only used when openai_api_server=True.
276
- engine_args : dict
277
- Additional keyword arguments to pass to the vLLM engine.
278
- For example, `tensor_parallel_size=2`.
279
- """
280
- ...
281
-
282
- @typing.overload
283
- def coreweave_s3_proxy(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
284
- """
285
- CoreWeave-specific S3 Proxy decorator for routing S3 requests through a local proxy service.
286
- It exists to make it easier for users to know that this decorator should only be used with
287
- a Neo Cloud like CoreWeave.
307
+ load : Union[List[str],str,List[Tuple[str,Union[str,None]]]], default: None
308
+ Artifact name/s referencing the models/checkpoints to load. Artifact names refer to the names of the instance variables set to `self`.
309
+ These artifact names give to `load` be reference objects or reference `key` string's from objects created by `current.checkpoint` / `current.model` / `current.huggingface_hub`.
310
+ If a list of tuples is provided, the first element is the artifact name and the second element is the path the artifact needs be unpacked on
311
+ the local filesystem. If the second element is None, the artifact will be unpacked in the current working directory.
312
+ If a string is provided, then the artifact corresponding to that name will be loaded in the current working directory.
313
+
314
+ temp_dir_root : str, default: None
315
+ The root directory under which `current.model.loaded` will store loaded models
288
316
  """
289
317
  ...
290
318
 
291
319
  @typing.overload
292
- def coreweave_s3_proxy(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
293
- ...
294
-
295
- def coreweave_s3_proxy(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
320
+ def environment(*, vars: typing.Dict[str, str] = {}) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
296
321
  """
297
- CoreWeave-specific S3 Proxy decorator for routing S3 requests through a local proxy service.
298
- It exists to make it easier for users to know that this decorator should only be used with
299
- a Neo Cloud like CoreWeave.
322
+ Specifies environment variables to be set prior to the execution of a step.
323
+
324
+
325
+ Parameters
326
+ ----------
327
+ vars : Dict[str, str], default {}
328
+ Dictionary of environment variables to set.
300
329
  """
301
330
  ...
302
331
 
303
332
  @typing.overload
304
- def parallel(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
305
- """
306
- Decorator prototype for all step decorators. This function gets specialized
307
- and imported for all decorators types by _import_plugin_decorators().
308
- """
333
+ def environment(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
309
334
  ...
310
335
 
311
336
  @typing.overload
312
- def parallel(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
313
- ...
314
-
315
- def parallel(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
316
- """
317
- Decorator prototype for all step decorators. This function gets specialized
318
- and imported for all decorators types by _import_plugin_decorators().
319
- """
337
+ def environment(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
320
338
  ...
321
339
 
322
- def nvct(*, gpu: int, gpu_type: str) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
340
+ def environment(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, vars: typing.Dict[str, str] = {}):
323
341
  """
324
- Specifies that this step should execute on DGX cloud.
342
+ Specifies environment variables to be set prior to the execution of a step.
325
343
 
326
344
 
327
345
  Parameters
328
346
  ----------
329
- gpu : int
330
- Number of GPUs to use.
331
- gpu_type : str
332
- Type of Nvidia GPU to use.
347
+ vars : Dict[str, str], default {}
348
+ Dictionary of environment variables to set.
333
349
  """
334
350
  ...
335
351
 
336
352
  @typing.overload
337
- def card(*, type: str = 'default', id: typing.Optional[str] = None, options: typing.Dict[str, typing.Any] = {}, timeout: int = 45) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
353
+ def catch(*, var: typing.Optional[str] = None, print_exception: bool = True) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
338
354
  """
339
- Creates a human-readable report, a Metaflow Card, after this step completes.
355
+ Specifies that the step will success under all circumstances.
340
356
 
341
- Note that you may add multiple `@card` decorators in a step with different parameters.
357
+ The decorator will create an optional artifact, specified by `var`, which
358
+ contains the exception raised. You can use it to detect the presence
359
+ of errors, indicating that all happy-path artifacts produced by the step
360
+ are missing.
342
361
 
343
362
 
344
363
  Parameters
345
364
  ----------
346
- type : str, default 'default'
347
- Card type.
348
- id : str, optional, default None
349
- If multiple cards are present, use this id to identify this card.
350
- options : Dict[str, Any], default {}
351
- Options passed to the card. The contents depend on the card type.
352
- timeout : int, default 45
353
- Interrupt reporting if it takes more than this many seconds.
365
+ var : str, optional, default None
366
+ Name of the artifact in which to store the caught exception.
367
+ If not specified, the exception is not stored.
368
+ print_exception : bool, default True
369
+ Determines whether or not the exception is printed to
370
+ stdout when caught.
354
371
  """
355
372
  ...
356
373
 
357
374
  @typing.overload
358
- def card(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
375
+ def catch(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
359
376
  ...
360
377
 
361
378
  @typing.overload
362
- def card(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
379
+ def catch(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
363
380
  ...
364
381
 
365
- def card(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, type: str = 'default', id: typing.Optional[str] = None, options: typing.Dict[str, typing.Any] = {}, timeout: int = 45):
382
+ def catch(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, var: typing.Optional[str] = None, print_exception: bool = True):
366
383
  """
367
- Creates a human-readable report, a Metaflow Card, after this step completes.
368
-
369
- Note that you may add multiple `@card` decorators in a step with different parameters.
370
-
384
+ Specifies that the step will success under all circumstances.
371
385
 
372
- Parameters
373
- ----------
374
- type : str, default 'default'
375
- Card type.
376
- id : str, optional, default None
377
- If multiple cards are present, use this id to identify this card.
378
- options : Dict[str, Any], default {}
379
- Options passed to the card. The contents depend on the card type.
380
- timeout : int, default 45
381
- Interrupt reporting if it takes more than this many seconds.
382
- """
383
- ...
384
-
385
- @typing.overload
386
- def environment(*, vars: typing.Dict[str, str] = {}) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
387
- """
388
- Specifies environment variables to be set prior to the execution of a step.
386
+ The decorator will create an optional artifact, specified by `var`, which
387
+ contains the exception raised. You can use it to detect the presence
388
+ of errors, indicating that all happy-path artifacts produced by the step
389
+ are missing.
389
390
 
390
391
 
391
392
  Parameters
392
393
  ----------
393
- vars : Dict[str, str], default {}
394
- Dictionary of environment variables to set.
394
+ var : str, optional, default None
395
+ Name of the artifact in which to store the caught exception.
396
+ If not specified, the exception is not stored.
397
+ print_exception : bool, default True
398
+ Determines whether or not the exception is printed to
399
+ stdout when caught.
395
400
  """
396
401
  ...
397
402
 
398
- @typing.overload
399
- def environment(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
400
- ...
401
-
402
- @typing.overload
403
- def environment(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
404
- ...
405
-
406
- def environment(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, vars: typing.Dict[str, str] = {}):
403
+ def nvidia(*, gpu: int, gpu_type: str, queue_timeout: int) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
407
404
  """
408
- Specifies environment variables to be set prior to the execution of a step.
405
+ Specifies that this step should execute on DGX cloud.
409
406
 
410
407
 
411
408
  Parameters
412
409
  ----------
413
- vars : Dict[str, str], default {}
414
- Dictionary of environment variables to set.
410
+ gpu : int
411
+ Number of GPUs to use.
412
+ gpu_type : str
413
+ Type of Nvidia GPU to use.
414
+ queue_timeout : int
415
+ Time to keep the job in NVCF's queue.
415
416
  """
416
417
  ...
417
418
 
@@ -471,394 +472,219 @@ def retry(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], ty
471
472
  ...
472
473
 
473
474
  @typing.overload
474
- def secrets(*, sources: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], role: typing.Optional[str] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
475
+ def checkpoint(*, load_policy: str = 'fresh', temp_dir_root: str = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
475
476
  """
476
- Specifies secrets to be retrieved and injected as environment variables prior to
477
- the execution of a step.
477
+ Enables checkpointing for a step.
478
+
479
+ > Examples
480
+
481
+ - Saving Checkpoints
482
+
483
+ ```python
484
+ @checkpoint
485
+ @step
486
+ def train(self):
487
+ model = create_model(self.parameters, checkpoint_path = None)
488
+ for i in range(self.epochs):
489
+ # some training logic
490
+ loss = model.train(self.dataset)
491
+ if i % 10 == 0:
492
+ model.save(
493
+ current.checkpoint.directory,
494
+ )
495
+ # saves the contents of the `current.checkpoint.directory` as a checkpoint
496
+ # and returns a reference dictionary to the checkpoint saved in the datastore
497
+ self.latest_checkpoint = current.checkpoint.save(
498
+ name="epoch_checkpoint",
499
+ metadata={
500
+ "epoch": i,
501
+ "loss": loss,
502
+ }
503
+ )
504
+ ```
505
+
506
+ - Using Loaded Checkpoints
507
+
508
+ ```python
509
+ @retry(times=3)
510
+ @checkpoint
511
+ @step
512
+ def train(self):
513
+ # Assume that the task has restarted and the previous attempt of the task
514
+ # saved a checkpoint
515
+ checkpoint_path = None
516
+ if current.checkpoint.is_loaded: # Check if a checkpoint is loaded
517
+ print("Loaded checkpoint from the previous attempt")
518
+ checkpoint_path = current.checkpoint.directory
519
+
520
+ model = create_model(self.parameters, checkpoint_path = checkpoint_path)
521
+ for i in range(self.epochs):
522
+ ...
523
+ ```
478
524
 
479
525
 
480
526
  Parameters
481
527
  ----------
482
- sources : List[Union[str, Dict[str, Any]]], default: []
483
- List of secret specs, defining how the secrets are to be retrieved
484
- role : str, optional, default: None
485
- Role to use for fetching secrets
528
+ load_policy : str, default: "fresh"
529
+ The policy for loading the checkpoint. The following policies are supported:
530
+ - "eager": Loads the the latest available checkpoint within the namespace.
531
+ With this mode, the latest checkpoint written by any previous task (can be even a different run) of the step
532
+ will be loaded at the start of the task.
533
+ - "none": Do not load any checkpoint
534
+ - "fresh": Loads the lastest checkpoint created within the running Task.
535
+ This mode helps loading checkpoints across various retry attempts of the same task.
536
+ With this mode, no checkpoint will be loaded at the start of a task but any checkpoints
537
+ created within the task will be loaded when the task is retries execution on failure.
538
+
539
+ temp_dir_root : str, default: None
540
+ The root directory under which `current.checkpoint.directory` will be created.
486
541
  """
487
542
  ...
488
543
 
489
544
  @typing.overload
490
- def secrets(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
545
+ def checkpoint(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
491
546
  ...
492
547
 
493
548
  @typing.overload
494
- def secrets(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
549
+ def checkpoint(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
495
550
  ...
496
551
 
497
- def secrets(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, sources: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], role: typing.Optional[str] = None):
552
+ def checkpoint(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, load_policy: str = 'fresh', temp_dir_root: str = None):
498
553
  """
499
- Specifies secrets to be retrieved and injected as environment variables prior to
500
- the execution of a step.
554
+ Enables checkpointing for a step.
501
555
 
556
+ > Examples
502
557
 
503
- Parameters
504
- ----------
505
- sources : List[Union[str, Dict[str, Any]]], default: []
506
- List of secret specs, defining how the secrets are to be retrieved
507
- role : str, optional, default: None
508
- Role to use for fetching secrets
509
- """
510
- ...
511
-
512
- @typing.overload
513
- def conda(*, packages: typing.Dict[str, str] = {}, libraries: typing.Dict[str, str] = {}, python: typing.Optional[str] = None, disabled: bool = False) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
514
- """
515
- Specifies the Conda environment for the step.
558
+ - Saving Checkpoints
516
559
 
517
- Information in this decorator will augment any
518
- attributes set in the `@conda_base` flow-level decorator. Hence,
519
- you can use `@conda_base` to set packages required by all
520
- steps and use `@conda` to specify step-specific overrides.
560
+ ```python
561
+ @checkpoint
562
+ @step
563
+ def train(self):
564
+ model = create_model(self.parameters, checkpoint_path = None)
565
+ for i in range(self.epochs):
566
+ # some training logic
567
+ loss = model.train(self.dataset)
568
+ if i % 10 == 0:
569
+ model.save(
570
+ current.checkpoint.directory,
571
+ )
572
+ # saves the contents of the `current.checkpoint.directory` as a checkpoint
573
+ # and returns a reference dictionary to the checkpoint saved in the datastore
574
+ self.latest_checkpoint = current.checkpoint.save(
575
+ name="epoch_checkpoint",
576
+ metadata={
577
+ "epoch": i,
578
+ "loss": loss,
579
+ }
580
+ )
581
+ ```
582
+
583
+ - Using Loaded Checkpoints
584
+
585
+ ```python
586
+ @retry(times=3)
587
+ @checkpoint
588
+ @step
589
+ def train(self):
590
+ # Assume that the task has restarted and the previous attempt of the task
591
+ # saved a checkpoint
592
+ checkpoint_path = None
593
+ if current.checkpoint.is_loaded: # Check if a checkpoint is loaded
594
+ print("Loaded checkpoint from the previous attempt")
595
+ checkpoint_path = current.checkpoint.directory
596
+
597
+ model = create_model(self.parameters, checkpoint_path = checkpoint_path)
598
+ for i in range(self.epochs):
599
+ ...
600
+ ```
521
601
 
522
602
 
523
603
  Parameters
524
604
  ----------
525
- packages : Dict[str, str], default {}
526
- Packages to use for this step. The key is the name of the package
527
- and the value is the version to use.
528
- libraries : Dict[str, str], default {}
529
- Supported for backward compatibility. When used with packages, packages will take precedence.
530
- python : str, optional, default None
531
- Version of Python to use, e.g. '3.7.4'. A default value of None implies
532
- that the version used will correspond to the version of the Python interpreter used to start the run.
533
- disabled : bool, default False
534
- If set to True, disables @conda.
605
+ load_policy : str, default: "fresh"
606
+ The policy for loading the checkpoint. The following policies are supported:
607
+ - "eager": Loads the the latest available checkpoint within the namespace.
608
+ With this mode, the latest checkpoint written by any previous task (can be even a different run) of the step
609
+ will be loaded at the start of the task.
610
+ - "none": Do not load any checkpoint
611
+ - "fresh": Loads the lastest checkpoint created within the running Task.
612
+ This mode helps loading checkpoints across various retry attempts of the same task.
613
+ With this mode, no checkpoint will be loaded at the start of a task but any checkpoints
614
+ created within the task will be loaded when the task is retries execution on failure.
615
+
616
+ temp_dir_root : str, default: None
617
+ The root directory under which `current.checkpoint.directory` will be created.
535
618
  """
536
619
  ...
537
620
 
538
- @typing.overload
539
- def conda(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
540
- ...
541
-
542
- @typing.overload
543
- def conda(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
544
- ...
545
-
546
- def conda(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, packages: typing.Dict[str, str] = {}, libraries: typing.Dict[str, str] = {}, python: typing.Optional[str] = None, disabled: bool = False):
621
+ def nebius_s3_proxy(*, integration_name: typing.Optional[str] = None, write_mode: typing.Optional[str] = None, debug: typing.Optional[bool] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
547
622
  """
548
- Specifies the Conda environment for the step.
623
+ `@nebius_s3_proxy` is a Nebius-specific S3 Proxy decorator for routing S3 requests through a local proxy service.
624
+ It exists to make it easier for users to know that this decorator should only be used with
625
+ a Neo Cloud like Nebius. The underlying mechanics of the decorator is the same as the `@s3_proxy`:
549
626
 
550
- Information in this decorator will augment any
551
- attributes set in the `@conda_base` flow-level decorator. Hence,
552
- you can use `@conda_base` to set packages required by all
553
- steps and use `@conda` to specify step-specific overrides.
627
+
628
+ Set up an S3 proxy that caches objects in an external, S3‑compatible bucket
629
+ for S3 read and write requests.
630
+
631
+ This decorator requires an integration in the Outerbounds platform that
632
+ points to an external bucket. It affects S3 operations performed via
633
+ Metaflow's `get_aws_client` and `S3` within a `@step`.
634
+
635
+ Read operations
636
+ ---------------
637
+ All read operations pass through the proxy. If an object does not already
638
+ exist in the external bucket, it is cached there. For example, if code reads
639
+ from buckets `FOO` and `BAR` using the `S3` interface, objects from both
640
+ buckets are cached in the external bucket.
641
+
642
+ During task execution, all S3‑related read requests are routed through the
643
+ proxy:
644
+ - If the object is present in the external object store, the proxy
645
+ streams it directly from there without accessing the requested origin
646
+ bucket.
647
+ - If the object is not present in the external storage, the proxy
648
+ fetches it from the requested bucket, caches it in the external
649
+ storage, and streams the response from the origin bucket.
650
+
651
+ Warning
652
+ -------
653
+ All READ operations (e.g., GetObject, HeadObject) pass through the external
654
+ bucket regardless of the bucket specified in user code. Even
655
+ `S3(run=self)` and `S3(s3root="mybucketfoo")` requests go through the
656
+ external bucket cache.
657
+
658
+ Write operations
659
+ ----------------
660
+ Write behavior is controlled by the `write_mode` parameter, which determines
661
+ whether writes also persist objects in the cache.
662
+
663
+ `write_mode` values:
664
+ - `origin-and-cache`: objects are written both to the cache and to their
665
+ intended origin bucket.
666
+ - `origin`: objects are written only to their intended origin bucket.
554
667
 
555
668
 
556
669
  Parameters
557
670
  ----------
558
- packages : Dict[str, str], default {}
559
- Packages to use for this step. The key is the name of the package
560
- and the value is the version to use.
561
- libraries : Dict[str, str], default {}
562
- Supported for backward compatibility. When used with packages, packages will take precedence.
563
- python : str, optional, default None
564
- Version of Python to use, e.g. '3.7.4'. A default value of None implies
565
- that the version used will correspond to the version of the Python interpreter used to start the run.
566
- disabled : bool, default False
567
- If set to True, disables @conda.
671
+ integration_name : str, optional
672
+ [Outerbounds integration name](https://docs.outerbounds.com/outerbounds/configuring-secrets/#integrations-view)
673
+ that holds the configuration for the external, S3‑compatible object
674
+ storage bucket. If not specified, the only available S3 proxy
675
+ integration in the namespace is used (fails if multiple exist).
676
+ write_mode : str, optional
677
+ Controls whether writes also go to the external bucket.
678
+ - `origin` (default)
679
+ - `origin-and-cache`
680
+ debug : bool, optional
681
+ Enables debug logging for proxy operations.
568
682
  """
569
683
  ...
570
684
 
571
- @typing.overload
572
- def catch(*, var: typing.Optional[str] = None, print_exception: bool = True) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
685
+ def kubernetes(*, cpu: int = 1, memory: int = 4096, disk: int = 10240, image: typing.Optional[str] = None, image_pull_policy: str = 'KUBERNETES_IMAGE_PULL_POLICY', image_pull_secrets: typing.List[str] = [], service_account: str = 'METAFLOW_KUBERNETES_SERVICE_ACCOUNT', secrets: typing.Optional[typing.List[str]] = None, node_selector: typing.Union[typing.Dict[str, str], str, None] = None, namespace: str = 'METAFLOW_KUBERNETES_NAMESPACE', gpu: typing.Optional[int] = None, gpu_vendor: str = 'KUBERNETES_GPU_VENDOR', tolerations: typing.List[typing.Dict[str, str]] = [], labels: typing.Dict[str, str] = 'METAFLOW_KUBERNETES_LABELS', annotations: typing.Dict[str, str] = 'METAFLOW_KUBERNETES_ANNOTATIONS', use_tmpfs: bool = False, tmpfs_tempdir: bool = True, tmpfs_size: typing.Optional[int] = None, tmpfs_path: typing.Optional[str] = '/metaflow_temp', persistent_volume_claims: typing.Optional[typing.Dict[str, str]] = None, shared_memory: typing.Optional[int] = None, port: typing.Optional[int] = None, compute_pool: typing.Optional[str] = None, hostname_resolution_timeout: int = 600, qos: str = 'Burstable', security_context: typing.Optional[typing.Dict[str, typing.Any]] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
573
686
  """
574
- Specifies that the step will success under all circumstances.
575
-
576
- The decorator will create an optional artifact, specified by `var`, which
577
- contains the exception raised. You can use it to detect the presence
578
- of errors, indicating that all happy-path artifacts produced by the step
579
- are missing.
580
-
581
-
582
- Parameters
583
- ----------
584
- var : str, optional, default None
585
- Name of the artifact in which to store the caught exception.
586
- If not specified, the exception is not stored.
587
- print_exception : bool, default True
588
- Determines whether or not the exception is printed to
589
- stdout when caught.
590
- """
591
- ...
592
-
593
- @typing.overload
594
- def catch(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
595
- ...
596
-
597
- @typing.overload
598
- def catch(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
599
- ...
600
-
601
- def catch(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, var: typing.Optional[str] = None, print_exception: bool = True):
602
- """
603
- Specifies that the step will success under all circumstances.
604
-
605
- The decorator will create an optional artifact, specified by `var`, which
606
- contains the exception raised. You can use it to detect the presence
607
- of errors, indicating that all happy-path artifacts produced by the step
608
- are missing.
609
-
610
-
611
- Parameters
612
- ----------
613
- var : str, optional, default None
614
- Name of the artifact in which to store the caught exception.
615
- If not specified, the exception is not stored.
616
- print_exception : bool, default True
617
- Determines whether or not the exception is printed to
618
- stdout when caught.
619
- """
620
- ...
621
-
622
- @typing.overload
623
- def app_deploy(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
624
- """
625
- Decorator prototype for all step decorators. This function gets specialized
626
- and imported for all decorators types by _import_plugin_decorators().
627
- """
628
- ...
629
-
630
- @typing.overload
631
- def app_deploy(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
632
- ...
633
-
634
- def app_deploy(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
635
- """
636
- Decorator prototype for all step decorators. This function gets specialized
637
- and imported for all decorators types by _import_plugin_decorators().
638
- """
639
- ...
640
-
641
- @typing.overload
642
- def pypi(*, packages: typing.Dict[str, str] = {}, python: typing.Optional[str] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
643
- """
644
- Specifies the PyPI packages for the step.
645
-
646
- Information in this decorator will augment any
647
- attributes set in the `@pyi_base` flow-level decorator. Hence,
648
- you can use `@pypi_base` to set packages required by all
649
- steps and use `@pypi` to specify step-specific overrides.
650
-
651
-
652
- Parameters
653
- ----------
654
- packages : Dict[str, str], default: {}
655
- Packages to use for this step. The key is the name of the package
656
- and the value is the version to use.
657
- python : str, optional, default: None
658
- Version of Python to use, e.g. '3.7.4'. A default value of None implies
659
- that the version used will correspond to the version of the Python interpreter used to start the run.
660
- """
661
- ...
662
-
663
- @typing.overload
664
- def pypi(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
665
- ...
666
-
667
- @typing.overload
668
- def pypi(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
669
- ...
670
-
671
- def pypi(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, packages: typing.Dict[str, str] = {}, python: typing.Optional[str] = None):
672
- """
673
- Specifies the PyPI packages for the step.
674
-
675
- Information in this decorator will augment any
676
- attributes set in the `@pyi_base` flow-level decorator. Hence,
677
- you can use `@pypi_base` to set packages required by all
678
- steps and use `@pypi` to specify step-specific overrides.
679
-
680
-
681
- Parameters
682
- ----------
683
- packages : Dict[str, str], default: {}
684
- Packages to use for this step. The key is the name of the package
685
- and the value is the version to use.
686
- python : str, optional, default: None
687
- Version of Python to use, e.g. '3.7.4'. A default value of None implies
688
- that the version used will correspond to the version of the Python interpreter used to start the run.
689
- """
690
- ...
691
-
692
- @typing.overload
693
- def model(*, load: typing.Union[typing.List[str], str, typing.List[typing.Tuple[str, typing.Optional[str]]]] = None, temp_dir_root: str = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
694
- """
695
- Enables loading / saving of models within a step.
696
-
697
- > Examples
698
- - Saving Models
699
- ```python
700
- @model
701
- @step
702
- def train(self):
703
- # current.model.save returns a dictionary reference to the model saved
704
- self.my_model = current.model.save(
705
- path_to_my_model,
706
- label="my_model",
707
- metadata={
708
- "epochs": 10,
709
- "batch-size": 32,
710
- "learning-rate": 0.001,
711
- }
712
- )
713
- self.next(self.test)
714
-
715
- @model(load="my_model")
716
- @step
717
- def test(self):
718
- # `current.model.loaded` returns a dictionary of the loaded models
719
- # where the key is the name of the artifact and the value is the path to the model
720
- print(os.listdir(current.model.loaded["my_model"]))
721
- self.next(self.end)
722
- ```
723
-
724
- - Loading models
725
- ```python
726
- @step
727
- def train(self):
728
- # current.model.load returns the path to the model loaded
729
- checkpoint_path = current.model.load(
730
- self.checkpoint_key,
731
- )
732
- model_path = current.model.load(
733
- self.model,
734
- )
735
- self.next(self.test)
736
- ```
737
-
738
-
739
- Parameters
740
- ----------
741
- load : Union[List[str],str,List[Tuple[str,Union[str,None]]]], default: None
742
- Artifact name/s referencing the models/checkpoints to load. Artifact names refer to the names of the instance variables set to `self`.
743
- These artifact names give to `load` be reference objects or reference `key` string's from objects created by `current.checkpoint` / `current.model` / `current.huggingface_hub`.
744
- If a list of tuples is provided, the first element is the artifact name and the second element is the path the artifact needs be unpacked on
745
- the local filesystem. If the second element is None, the artifact will be unpacked in the current working directory.
746
- If a string is provided, then the artifact corresponding to that name will be loaded in the current working directory.
747
-
748
- temp_dir_root : str, default: None
749
- The root directory under which `current.model.loaded` will store loaded models
750
- """
751
- ...
752
-
753
- @typing.overload
754
- def model(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
755
- ...
756
-
757
- @typing.overload
758
- def model(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
759
- ...
760
-
761
- def model(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, load: typing.Union[typing.List[str], str, typing.List[typing.Tuple[str, typing.Optional[str]]]] = None, temp_dir_root: str = None):
762
- """
763
- Enables loading / saving of models within a step.
764
-
765
- > Examples
766
- - Saving Models
767
- ```python
768
- @model
769
- @step
770
- def train(self):
771
- # current.model.save returns a dictionary reference to the model saved
772
- self.my_model = current.model.save(
773
- path_to_my_model,
774
- label="my_model",
775
- metadata={
776
- "epochs": 10,
777
- "batch-size": 32,
778
- "learning-rate": 0.001,
779
- }
780
- )
781
- self.next(self.test)
782
-
783
- @model(load="my_model")
784
- @step
785
- def test(self):
786
- # `current.model.loaded` returns a dictionary of the loaded models
787
- # where the key is the name of the artifact and the value is the path to the model
788
- print(os.listdir(current.model.loaded["my_model"]))
789
- self.next(self.end)
790
- ```
791
-
792
- - Loading models
793
- ```python
794
- @step
795
- def train(self):
796
- # current.model.load returns the path to the model loaded
797
- checkpoint_path = current.model.load(
798
- self.checkpoint_key,
799
- )
800
- model_path = current.model.load(
801
- self.model,
802
- )
803
- self.next(self.test)
804
- ```
805
-
806
-
807
- Parameters
808
- ----------
809
- load : Union[List[str],str,List[Tuple[str,Union[str,None]]]], default: None
810
- Artifact name/s referencing the models/checkpoints to load. Artifact names refer to the names of the instance variables set to `self`.
811
- These artifact names give to `load` be reference objects or reference `key` string's from objects created by `current.checkpoint` / `current.model` / `current.huggingface_hub`.
812
- If a list of tuples is provided, the first element is the artifact name and the second element is the path the artifact needs be unpacked on
813
- the local filesystem. If the second element is None, the artifact will be unpacked in the current working directory.
814
- If a string is provided, then the artifact corresponding to that name will be loaded in the current working directory.
815
-
816
- temp_dir_root : str, default: None
817
- The root directory under which `current.model.loaded` will store loaded models
818
- """
819
- ...
820
-
821
- @typing.overload
822
- def nebius_s3_proxy(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
823
- """
824
- Nebius-specific S3 Proxy decorator for routing S3 requests through a local proxy service.
825
- It exists to make it easier for users to know that this decorator should only be used with
826
- a Neo Cloud like Nebius.
827
- """
828
- ...
829
-
830
- @typing.overload
831
- def nebius_s3_proxy(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
832
- ...
833
-
834
- def nebius_s3_proxy(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
835
- """
836
- Nebius-specific S3 Proxy decorator for routing S3 requests through a local proxy service.
837
- It exists to make it easier for users to know that this decorator should only be used with
838
- a Neo Cloud like Nebius.
839
- """
840
- ...
841
-
842
- @typing.overload
843
- def fast_bakery_internal(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
844
- """
845
- Internal decorator to support Fast bakery
846
- """
847
- ...
848
-
849
- @typing.overload
850
- def fast_bakery_internal(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
851
- ...
852
-
853
- def fast_bakery_internal(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
854
- """
855
- Internal decorator to support Fast bakery
856
- """
857
- ...
858
-
859
- def kubernetes(*, cpu: int = 1, memory: int = 4096, disk: int = 10240, image: typing.Optional[str] = None, image_pull_policy: str = 'KUBERNETES_IMAGE_PULL_POLICY', image_pull_secrets: typing.List[str] = [], service_account: str = 'METAFLOW_KUBERNETES_SERVICE_ACCOUNT', secrets: typing.Optional[typing.List[str]] = None, node_selector: typing.Union[typing.Dict[str, str], str, None] = None, namespace: str = 'METAFLOW_KUBERNETES_NAMESPACE', gpu: typing.Optional[int] = None, gpu_vendor: str = 'KUBERNETES_GPU_VENDOR', tolerations: typing.List[typing.Dict[str, str]] = [], labels: typing.Dict[str, str] = 'METAFLOW_KUBERNETES_LABELS', annotations: typing.Dict[str, str] = 'METAFLOW_KUBERNETES_ANNOTATIONS', use_tmpfs: bool = False, tmpfs_tempdir: bool = True, tmpfs_size: typing.Optional[int] = None, tmpfs_path: typing.Optional[str] = '/metaflow_temp', persistent_volume_claims: typing.Optional[typing.Dict[str, str]] = None, shared_memory: typing.Optional[int] = None, port: typing.Optional[int] = None, compute_pool: typing.Optional[str] = None, hostname_resolution_timeout: int = 600, qos: str = 'Burstable', security_context: typing.Optional[typing.Dict[str, typing.Any]] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
860
- """
861
- Specifies that this step should execute on Kubernetes.
687
+ Specifies that this step should execute on Kubernetes.
862
688
 
863
689
 
864
690
  Parameters
@@ -945,82 +771,62 @@ def kubernetes(*, cpu: int = 1, memory: int = 4096, disk: int = 10240, image: ty
945
771
  """
946
772
  ...
947
773
 
948
- @typing.overload
949
- def resources(*, cpu: int = 1, gpu: typing.Optional[int] = None, disk: typing.Optional[int] = None, memory: int = 4096, shared_memory: typing.Optional[int] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
950
- """
951
- Specifies the resources needed when executing this step.
952
-
953
- Use `@resources` to specify the resource requirements
954
- independently of the specific compute layer (`@batch`, `@kubernetes`).
955
-
956
- You can choose the compute layer on the command line by executing e.g.
957
- ```
958
- python myflow.py run --with batch
959
- ```
960
- or
961
- ```
962
- python myflow.py run --with kubernetes
963
- ```
964
- which executes the flow on the desired system using the
965
- requirements specified in `@resources`.
966
-
967
-
968
- Parameters
969
- ----------
970
- cpu : int, default 1
971
- Number of CPUs required for this step.
972
- gpu : int, optional, default None
973
- Number of GPUs required for this step.
974
- disk : int, optional, default None
975
- Disk size (in MB) required for this step. Only applies on Kubernetes.
976
- memory : int, default 4096
977
- Memory size (in MB) required for this step.
978
- shared_memory : int, optional, default None
979
- The value for the size (in MiB) of the /dev/shm volume for this step.
980
- This parameter maps to the `--shm-size` option in Docker.
981
- """
982
- ...
983
-
984
- @typing.overload
985
- def resources(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
986
- ...
987
-
988
- @typing.overload
989
- def resources(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
990
- ...
991
-
992
- def resources(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, cpu: int = 1, gpu: typing.Optional[int] = None, disk: typing.Optional[int] = None, memory: int = 4096, shared_memory: typing.Optional[int] = None):
774
+ def s3_proxy(*, integration_name: typing.Optional[str] = None, write_mode: typing.Optional[str] = None, debug: typing.Optional[bool] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
993
775
  """
994
- Specifies the resources needed when executing this step.
776
+ Set up an S3 proxy that caches objects in an external, S3‑compatible bucket
777
+ for S3 read and write requests.
778
+
779
+ This decorator requires an integration in the Outerbounds platform that
780
+ points to an external bucket. It affects S3 operations performed via
781
+ Metaflow's `get_aws_client` and `S3` within a `@step`.
782
+
783
+ Read operations
784
+ ---------------
785
+ All read operations pass through the proxy. If an object does not already
786
+ exist in the external bucket, it is cached there. For example, if code reads
787
+ from buckets `FOO` and `BAR` using the `S3` interface, objects from both
788
+ buckets are cached in the external bucket.
789
+
790
+ During task execution, all S3‑related read requests are routed through the
791
+ proxy:
792
+ - If the object is present in the external object store, the proxy
793
+ streams it directly from there without accessing the requested origin
794
+ bucket.
795
+ - If the object is not present in the external storage, the proxy
796
+ fetches it from the requested bucket, caches it in the external
797
+ storage, and streams the response from the origin bucket.
798
+
799
+ Warning
800
+ -------
801
+ All READ operations (e.g., GetObject, HeadObject) pass through the external
802
+ bucket regardless of the bucket specified in user code. Even
803
+ `S3(run=self)` and `S3(s3root="mybucketfoo")` requests go through the
804
+ external bucket cache.
995
805
 
996
- Use `@resources` to specify the resource requirements
997
- independently of the specific compute layer (`@batch`, `@kubernetes`).
806
+ Write operations
807
+ ----------------
808
+ Write behavior is controlled by the `write_mode` parameter, which determines
809
+ whether writes also persist objects in the cache.
998
810
 
999
- You can choose the compute layer on the command line by executing e.g.
1000
- ```
1001
- python myflow.py run --with batch
1002
- ```
1003
- or
1004
- ```
1005
- python myflow.py run --with kubernetes
1006
- ```
1007
- which executes the flow on the desired system using the
1008
- requirements specified in `@resources`.
811
+ `write_mode` values:
812
+ - `origin-and-cache`: objects are written both to the cache and to their
813
+ intended origin bucket.
814
+ - `origin`: objects are written only to their intended origin bucket.
1009
815
 
1010
816
 
1011
817
  Parameters
1012
818
  ----------
1013
- cpu : int, default 1
1014
- Number of CPUs required for this step.
1015
- gpu : int, optional, default None
1016
- Number of GPUs required for this step.
1017
- disk : int, optional, default None
1018
- Disk size (in MB) required for this step. Only applies on Kubernetes.
1019
- memory : int, default 4096
1020
- Memory size (in MB) required for this step.
1021
- shared_memory : int, optional, default None
1022
- The value for the size (in MiB) of the /dev/shm volume for this step.
1023
- This parameter maps to the `--shm-size` option in Docker.
819
+ integration_name : str, optional
820
+ [Outerbounds integration name](https://docs.outerbounds.com/outerbounds/configuring-secrets/#integrations-view)
821
+ that holds the configuration for the external, S3‑compatible object
822
+ storage bucket. If not specified, the only available S3 proxy
823
+ integration in the namespace is used (fails if multiple exist).
824
+ write_mode : str, optional
825
+ Controls whether writes also go to the external bucket.
826
+ - `origin` (default)
827
+ - `origin-and-cache`
828
+ debug : bool, optional
829
+ Enables debug logging for proxy operations.
1024
830
  """
1025
831
  ...
1026
832
 
@@ -1109,35 +915,265 @@ def huggingface_hub(*, temp_dir_root: typing.Optional[str] = None, cache_scope:
1109
915
  i.e., the cached path is derived solely from the flow name.
1110
916
  When to use this mode: (1) Multiple users are executing the same flow and want shared access to the repos cached by the decorator. (2) Multiple versions of a flow are deployed, all needing access to the same repos cached by the decorator.
1111
917
 
1112
- - `global`: All repos are cached under a globally static path.
1113
- i.e., the base path of the cache is static and all repos are stored under it.
1114
- When to use this mode:
1115
- - All repos from the Hugging Face Hub need to be shared by users across all flow executions.
1116
- - Each caching scope comes with its own trade-offs:
1117
- - `checkpoint`:
1118
- - Has explicit control over when caches are populated (controlled by the same flow that has the `@huggingface_hub` decorator) but ends up hitting the Hugging Face Hub more often if there are many users/namespaces/steps.
1119
- - Since objects are written on a `namespace/flow/step` basis, the blast radius of a bad checkpoint is limited to a particular flow in a namespace.
1120
- - `flow`:
1121
- - Has less control over when caches are populated (can be written by any execution instance of a flow from any namespace) but results in more cache hits.
1122
- - The blast radius of a bad checkpoint is limited to all runs of a particular flow.
1123
- - It doesn't promote cache reuse across flows.
1124
- - `global`:
1125
- - Has no control over when caches are populated (can be written by any flow execution) but has the highest cache hit rate.
1126
- - It promotes cache reuse across flows.
1127
- - The blast radius of a bad checkpoint spans every flow that could be using a particular repo.
918
+ - `global`: All repos are cached under a globally static path.
919
+ i.e., the base path of the cache is static and all repos are stored under it.
920
+ When to use this mode:
921
+ - All repos from the Hugging Face Hub need to be shared by users across all flow executions.
922
+ - Each caching scope comes with its own trade-offs:
923
+ - `checkpoint`:
924
+ - Has explicit control over when caches are populated (controlled by the same flow that has the `@huggingface_hub` decorator) but ends up hitting the Hugging Face Hub more often if there are many users/namespaces/steps.
925
+ - Since objects are written on a `namespace/flow/step` basis, the blast radius of a bad checkpoint is limited to a particular flow in a namespace.
926
+ - `flow`:
927
+ - Has less control over when caches are populated (can be written by any execution instance of a flow from any namespace) but results in more cache hits.
928
+ - The blast radius of a bad checkpoint is limited to all runs of a particular flow.
929
+ - It doesn't promote cache reuse across flows.
930
+ - `global`:
931
+ - Has no control over when caches are populated (can be written by any flow execution) but has the highest cache hit rate.
932
+ - It promotes cache reuse across flows.
933
+ - The blast radius of a bad checkpoint spans every flow that could be using a particular repo.
934
+
935
+ load: Union[List[str], List[Tuple[Dict, str]], List[Tuple[str, str]], List[Dict], None]
936
+ The list of repos (models/datasets) to load.
937
+
938
+ Loaded repos can be accessed via `current.huggingface_hub.loaded`. If load is set, then the following happens:
939
+
940
+ - If repo (model/dataset) is not found in the datastore:
941
+ - Downloads the repo from Hugging Face Hub to a temporary directory (or uses specified path) for local access
942
+ - Stores it in Metaflow's datastore (s3/gcs/azure etc.) with a unique name based on repo_type/repo_id
943
+ - All HF models loaded for a `@step` will be cached separately under flow/step/namespace.
944
+
945
+ - If repo is found in the datastore:
946
+ - Loads it directly from datastore to local path (can be temporary directory or specified path)
947
+ """
948
+ ...
949
+
950
+ @typing.overload
951
+ def fast_bakery_internal(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
952
+ """
953
+ Internal decorator to support Fast bakery
954
+ """
955
+ ...
956
+
957
+ @typing.overload
958
+ def fast_bakery_internal(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
959
+ ...
960
+
961
+ def fast_bakery_internal(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
962
+ """
963
+ Internal decorator to support Fast bakery
964
+ """
965
+ ...
966
+
967
+ def coreweave_s3_proxy(*, integration_name: typing.Optional[str] = None, write_mode: typing.Optional[str] = None, debug: typing.Optional[bool] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
968
+ """
969
+ `@coreweave_s3_proxy` is a CoreWeave-specific S3 Proxy decorator for routing S3 requests through a local proxy service.
970
+ It exists to make it easier for users to know that this decorator should only be used with
971
+ a Neo Cloud like CoreWeave. The underlying mechanics of the decorator is the same as the `@s3_proxy`:
972
+
973
+
974
+ Set up an S3 proxy that caches objects in an external, S3‑compatible bucket
975
+ for S3 read and write requests.
976
+
977
+ This decorator requires an integration in the Outerbounds platform that
978
+ points to an external bucket. It affects S3 operations performed via
979
+ Metaflow's `get_aws_client` and `S3` within a `@step`.
980
+
981
+ Read operations
982
+ ---------------
983
+ All read operations pass through the proxy. If an object does not already
984
+ exist in the external bucket, it is cached there. For example, if code reads
985
+ from buckets `FOO` and `BAR` using the `S3` interface, objects from both
986
+ buckets are cached in the external bucket.
987
+
988
+ During task execution, all S3‑related read requests are routed through the
989
+ proxy:
990
+ - If the object is present in the external object store, the proxy
991
+ streams it directly from there without accessing the requested origin
992
+ bucket.
993
+ - If the object is not present in the external storage, the proxy
994
+ fetches it from the requested bucket, caches it in the external
995
+ storage, and streams the response from the origin bucket.
996
+
997
+ Warning
998
+ -------
999
+ All READ operations (e.g., GetObject, HeadObject) pass through the external
1000
+ bucket regardless of the bucket specified in user code. Even
1001
+ `S3(run=self)` and `S3(s3root="mybucketfoo")` requests go through the
1002
+ external bucket cache.
1003
+
1004
+ Write operations
1005
+ ----------------
1006
+ Write behavior is controlled by the `write_mode` parameter, which determines
1007
+ whether writes also persist objects in the cache.
1008
+
1009
+ `write_mode` values:
1010
+ - `origin-and-cache`: objects are written both to the cache and to their
1011
+ intended origin bucket.
1012
+ - `origin`: objects are written only to their intended origin bucket.
1013
+
1014
+
1015
+ Parameters
1016
+ ----------
1017
+ integration_name : str, optional
1018
+ [Outerbounds integration name](https://docs.outerbounds.com/outerbounds/configuring-secrets/#integrations-view)
1019
+ that holds the configuration for the external, S3‑compatible object
1020
+ storage bucket. If not specified, the only available S3 proxy
1021
+ integration in the namespace is used (fails if multiple exist).
1022
+ write_mode : str, optional
1023
+ Controls whether writes also go to the external bucket.
1024
+ - `origin` (default)
1025
+ - `origin-and-cache`
1026
+ debug : bool, optional
1027
+ Enables debug logging for proxy operations.
1028
+ """
1029
+ ...
1030
+
1031
+ @typing.overload
1032
+ def app_deploy(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1033
+ """
1034
+ Decorator prototype for all step decorators. This function gets specialized
1035
+ and imported for all decorators types by _import_plugin_decorators().
1036
+ """
1037
+ ...
1038
+
1039
+ @typing.overload
1040
+ def app_deploy(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1041
+ ...
1042
+
1043
+ def app_deploy(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
1044
+ """
1045
+ Decorator prototype for all step decorators. This function gets specialized
1046
+ and imported for all decorators types by _import_plugin_decorators().
1047
+ """
1048
+ ...
1049
+
1050
+ @typing.overload
1051
+ def resources(*, cpu: int = 1, gpu: typing.Optional[int] = None, disk: typing.Optional[int] = None, memory: int = 4096, shared_memory: typing.Optional[int] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1052
+ """
1053
+ Specifies the resources needed when executing this step.
1054
+
1055
+ Use `@resources` to specify the resource requirements
1056
+ independently of the specific compute layer (`@batch`, `@kubernetes`).
1057
+
1058
+ You can choose the compute layer on the command line by executing e.g.
1059
+ ```
1060
+ python myflow.py run --with batch
1061
+ ```
1062
+ or
1063
+ ```
1064
+ python myflow.py run --with kubernetes
1065
+ ```
1066
+ which executes the flow on the desired system using the
1067
+ requirements specified in `@resources`.
1068
+
1069
+
1070
+ Parameters
1071
+ ----------
1072
+ cpu : int, default 1
1073
+ Number of CPUs required for this step.
1074
+ gpu : int, optional, default None
1075
+ Number of GPUs required for this step.
1076
+ disk : int, optional, default None
1077
+ Disk size (in MB) required for this step. Only applies on Kubernetes.
1078
+ memory : int, default 4096
1079
+ Memory size (in MB) required for this step.
1080
+ shared_memory : int, optional, default None
1081
+ The value for the size (in MiB) of the /dev/shm volume for this step.
1082
+ This parameter maps to the `--shm-size` option in Docker.
1083
+ """
1084
+ ...
1085
+
1086
+ @typing.overload
1087
+ def resources(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1088
+ ...
1089
+
1090
+ @typing.overload
1091
+ def resources(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1092
+ ...
1093
+
1094
+ def resources(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, cpu: int = 1, gpu: typing.Optional[int] = None, disk: typing.Optional[int] = None, memory: int = 4096, shared_memory: typing.Optional[int] = None):
1095
+ """
1096
+ Specifies the resources needed when executing this step.
1097
+
1098
+ Use `@resources` to specify the resource requirements
1099
+ independently of the specific compute layer (`@batch`, `@kubernetes`).
1100
+
1101
+ You can choose the compute layer on the command line by executing e.g.
1102
+ ```
1103
+ python myflow.py run --with batch
1104
+ ```
1105
+ or
1106
+ ```
1107
+ python myflow.py run --with kubernetes
1108
+ ```
1109
+ which executes the flow on the desired system using the
1110
+ requirements specified in `@resources`.
1111
+
1112
+
1113
+ Parameters
1114
+ ----------
1115
+ cpu : int, default 1
1116
+ Number of CPUs required for this step.
1117
+ gpu : int, optional, default None
1118
+ Number of GPUs required for this step.
1119
+ disk : int, optional, default None
1120
+ Disk size (in MB) required for this step. Only applies on Kubernetes.
1121
+ memory : int, default 4096
1122
+ Memory size (in MB) required for this step.
1123
+ shared_memory : int, optional, default None
1124
+ The value for the size (in MiB) of the /dev/shm volume for this step.
1125
+ This parameter maps to the `--shm-size` option in Docker.
1126
+ """
1127
+ ...
1128
+
1129
+ @typing.overload
1130
+ def pypi(*, packages: typing.Dict[str, str] = {}, python: typing.Optional[str] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1131
+ """
1132
+ Specifies the PyPI packages for the step.
1133
+
1134
+ Information in this decorator will augment any
1135
+ attributes set in the `@pyi_base` flow-level decorator. Hence,
1136
+ you can use `@pypi_base` to set packages required by all
1137
+ steps and use `@pypi` to specify step-specific overrides.
1128
1138
 
1129
- load: Union[List[str], List[Tuple[Dict, str]], List[Tuple[str, str]], List[Dict], None]
1130
- The list of repos (models/datasets) to load.
1131
1139
 
1132
- Loaded repos can be accessed via `current.huggingface_hub.loaded`. If load is set, then the following happens:
1140
+ Parameters
1141
+ ----------
1142
+ packages : Dict[str, str], default: {}
1143
+ Packages to use for this step. The key is the name of the package
1144
+ and the value is the version to use.
1145
+ python : str, optional, default: None
1146
+ Version of Python to use, e.g. '3.7.4'. A default value of None implies
1147
+ that the version used will correspond to the version of the Python interpreter used to start the run.
1148
+ """
1149
+ ...
1150
+
1151
+ @typing.overload
1152
+ def pypi(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1153
+ ...
1154
+
1155
+ @typing.overload
1156
+ def pypi(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1157
+ ...
1158
+
1159
+ def pypi(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, packages: typing.Dict[str, str] = {}, python: typing.Optional[str] = None):
1160
+ """
1161
+ Specifies the PyPI packages for the step.
1133
1162
 
1134
- - If repo (model/dataset) is not found in the datastore:
1135
- - Downloads the repo from Hugging Face Hub to a temporary directory (or uses specified path) for local access
1136
- - Stores it in Metaflow's datastore (s3/gcs/azure etc.) with a unique name based on repo_type/repo_id
1137
- - All HF models loaded for a `@step` will be cached separately under flow/step/namespace.
1163
+ Information in this decorator will augment any
1164
+ attributes set in the `@pyi_base` flow-level decorator. Hence,
1165
+ you can use `@pypi_base` to set packages required by all
1166
+ steps and use `@pypi` to specify step-specific overrides.
1138
1167
 
1139
- - If repo is found in the datastore:
1140
- - Loads it directly from datastore to local path (can be temporary directory or specified path)
1168
+
1169
+ Parameters
1170
+ ----------
1171
+ packages : Dict[str, str], default: {}
1172
+ Packages to use for this step. The key is the name of the package
1173
+ and the value is the version to use.
1174
+ python : str, optional, default: None
1175
+ Version of Python to use, e.g. '3.7.4'. A default value of None implies
1176
+ that the version used will correspond to the version of the Python interpreter used to start the run.
1141
1177
  """
1142
1178
  ...
1143
1179
 
@@ -1200,396 +1236,311 @@ def timeout(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None],
1200
1236
  """
1201
1237
  ...
1202
1238
 
1203
- @typing.overload
1204
- def checkpoint(*, load_policy: str = 'fresh', temp_dir_root: str = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1239
+ def ollama(*, models: list, backend: str, force_pull: bool, cache_update_policy: str, force_cache_update: bool, debug: bool, circuit_breaker_config: dict, timeout_config: dict) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1205
1240
  """
1206
- Enables checkpointing for a step.
1207
-
1208
- > Examples
1241
+ This decorator is used to run Ollama APIs as Metaflow task sidecars.
1209
1242
 
1210
- - Saving Checkpoints
1243
+ User code call
1244
+ --------------
1245
+ @ollama(
1246
+ models=[...],
1247
+ ...
1248
+ )
1211
1249
 
1212
- ```python
1213
- @checkpoint
1214
- @step
1215
- def train(self):
1216
- model = create_model(self.parameters, checkpoint_path = None)
1217
- for i in range(self.epochs):
1218
- # some training logic
1219
- loss = model.train(self.dataset)
1220
- if i % 10 == 0:
1221
- model.save(
1222
- current.checkpoint.directory,
1223
- )
1224
- # saves the contents of the `current.checkpoint.directory` as a checkpoint
1225
- # and returns a reference dictionary to the checkpoint saved in the datastore
1226
- self.latest_checkpoint = current.checkpoint.save(
1227
- name="epoch_checkpoint",
1228
- metadata={
1229
- "epoch": i,
1230
- "loss": loss,
1231
- }
1232
- )
1233
- ```
1250
+ Valid backend options
1251
+ ---------------------
1252
+ - 'local': Run as a separate process on the local task machine.
1253
+ - (TODO) 'managed': Outerbounds hosts and selects compute provider.
1254
+ - (TODO) 'remote': Spin up separate instance to serve Ollama models.
1234
1255
 
1235
- - Using Loaded Checkpoints
1256
+ Valid model options
1257
+ -------------------
1258
+ Any model here https://ollama.com/search, e.g. 'llama3.2', 'llama3.3'
1236
1259
 
1237
- ```python
1238
- @retry(times=3)
1239
- @checkpoint
1240
- @step
1241
- def train(self):
1242
- # Assume that the task has restarted and the previous attempt of the task
1243
- # saved a checkpoint
1244
- checkpoint_path = None
1245
- if current.checkpoint.is_loaded: # Check if a checkpoint is loaded
1246
- print("Loaded checkpoint from the previous attempt")
1247
- checkpoint_path = current.checkpoint.directory
1248
1260
 
1249
- model = create_model(self.parameters, checkpoint_path = checkpoint_path)
1250
- for i in range(self.epochs):
1251
- ...
1252
- ```
1261
+ Parameters
1262
+ ----------
1263
+ models: list[str]
1264
+ List of Ollama containers running models in sidecars.
1265
+ backend: str
1266
+ Determines where and how to run the Ollama process.
1267
+ force_pull: bool
1268
+ Whether to run `ollama pull` no matter what, or first check the remote cache in Metaflow datastore for this model key.
1269
+ cache_update_policy: str
1270
+ Cache update policy: "auto", "force", or "never".
1271
+ force_cache_update: bool
1272
+ Simple override for "force" cache update policy.
1273
+ debug: bool
1274
+ Whether to turn on verbose debugging logs.
1275
+ circuit_breaker_config: dict
1276
+ Configuration for circuit breaker protection. Keys: failure_threshold, recovery_timeout, reset_timeout.
1277
+ timeout_config: dict
1278
+ Configuration for various operation timeouts. Keys: pull, stop, health_check, install, server_startup.
1279
+ """
1280
+ ...
1281
+
1282
+ @typing.overload
1283
+ def secrets(*, sources: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], role: typing.Optional[str] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1284
+ """
1285
+ Specifies secrets to be retrieved and injected as environment variables prior to
1286
+ the execution of a step.
1253
1287
 
1254
1288
 
1255
1289
  Parameters
1256
1290
  ----------
1257
- load_policy : str, default: "fresh"
1258
- The policy for loading the checkpoint. The following policies are supported:
1259
- - "eager": Loads the the latest available checkpoint within the namespace.
1260
- With this mode, the latest checkpoint written by any previous task (can be even a different run) of the step
1261
- will be loaded at the start of the task.
1262
- - "none": Do not load any checkpoint
1263
- - "fresh": Loads the lastest checkpoint created within the running Task.
1264
- This mode helps loading checkpoints across various retry attempts of the same task.
1265
- With this mode, no checkpoint will be loaded at the start of a task but any checkpoints
1266
- created within the task will be loaded when the task is retries execution on failure.
1267
-
1268
- temp_dir_root : str, default: None
1269
- The root directory under which `current.checkpoint.directory` will be created.
1291
+ sources : List[Union[str, Dict[str, Any]]], default: []
1292
+ List of secret specs, defining how the secrets are to be retrieved
1293
+ role : str, optional, default: None
1294
+ Role to use for fetching secrets
1270
1295
  """
1271
1296
  ...
1272
1297
 
1273
1298
  @typing.overload
1274
- def checkpoint(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1299
+ def secrets(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1275
1300
  ...
1276
1301
 
1277
1302
  @typing.overload
1278
- def checkpoint(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1303
+ def secrets(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1279
1304
  ...
1280
1305
 
1281
- def checkpoint(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, load_policy: str = 'fresh', temp_dir_root: str = None):
1306
+ def secrets(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, sources: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], role: typing.Optional[str] = None):
1282
1307
  """
1283
- Enables checkpointing for a step.
1284
-
1285
- > Examples
1286
-
1287
- - Saving Checkpoints
1288
-
1289
- ```python
1290
- @checkpoint
1291
- @step
1292
- def train(self):
1293
- model = create_model(self.parameters, checkpoint_path = None)
1294
- for i in range(self.epochs):
1295
- # some training logic
1296
- loss = model.train(self.dataset)
1297
- if i % 10 == 0:
1298
- model.save(
1299
- current.checkpoint.directory,
1300
- )
1301
- # saves the contents of the `current.checkpoint.directory` as a checkpoint
1302
- # and returns a reference dictionary to the checkpoint saved in the datastore
1303
- self.latest_checkpoint = current.checkpoint.save(
1304
- name="epoch_checkpoint",
1305
- metadata={
1306
- "epoch": i,
1307
- "loss": loss,
1308
- }
1309
- )
1310
- ```
1308
+ Specifies secrets to be retrieved and injected as environment variables prior to
1309
+ the execution of a step.
1311
1310
 
1312
- - Using Loaded Checkpoints
1313
1311
 
1314
- ```python
1315
- @retry(times=3)
1316
- @checkpoint
1317
- @step
1318
- def train(self):
1319
- # Assume that the task has restarted and the previous attempt of the task
1320
- # saved a checkpoint
1321
- checkpoint_path = None
1322
- if current.checkpoint.is_loaded: # Check if a checkpoint is loaded
1323
- print("Loaded checkpoint from the previous attempt")
1324
- checkpoint_path = current.checkpoint.directory
1312
+ Parameters
1313
+ ----------
1314
+ sources : List[Union[str, Dict[str, Any]]], default: []
1315
+ List of secret specs, defining how the secrets are to be retrieved
1316
+ role : str, optional, default: None
1317
+ Role to use for fetching secrets
1318
+ """
1319
+ ...
1320
+
1321
+ @typing.overload
1322
+ def card(*, type: str = 'default', id: typing.Optional[str] = None, options: typing.Dict[str, typing.Any] = {}, timeout: int = 45) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1323
+ """
1324
+ Creates a human-readable report, a Metaflow Card, after this step completes.
1325
1325
 
1326
- model = create_model(self.parameters, checkpoint_path = checkpoint_path)
1327
- for i in range(self.epochs):
1328
- ...
1329
- ```
1326
+ Note that you may add multiple `@card` decorators in a step with different parameters.
1330
1327
 
1331
1328
 
1332
1329
  Parameters
1333
1330
  ----------
1334
- load_policy : str, default: "fresh"
1335
- The policy for loading the checkpoint. The following policies are supported:
1336
- - "eager": Loads the the latest available checkpoint within the namespace.
1337
- With this mode, the latest checkpoint written by any previous task (can be even a different run) of the step
1338
- will be loaded at the start of the task.
1339
- - "none": Do not load any checkpoint
1340
- - "fresh": Loads the lastest checkpoint created within the running Task.
1341
- This mode helps loading checkpoints across various retry attempts of the same task.
1342
- With this mode, no checkpoint will be loaded at the start of a task but any checkpoints
1343
- created within the task will be loaded when the task is retries execution on failure.
1344
-
1345
- temp_dir_root : str, default: None
1346
- The root directory under which `current.checkpoint.directory` will be created.
1331
+ type : str, default 'default'
1332
+ Card type.
1333
+ id : str, optional, default None
1334
+ If multiple cards are present, use this id to identify this card.
1335
+ options : Dict[str, Any], default {}
1336
+ Options passed to the card. The contents depend on the card type.
1337
+ timeout : int, default 45
1338
+ Interrupt reporting if it takes more than this many seconds.
1347
1339
  """
1348
1340
  ...
1349
1341
 
1350
- def nvidia(*, gpu: int, gpu_type: str, queue_timeout: int) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1342
+ @typing.overload
1343
+ def card(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1344
+ ...
1345
+
1346
+ @typing.overload
1347
+ def card(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1348
+ ...
1349
+
1350
+ def card(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, type: str = 'default', id: typing.Optional[str] = None, options: typing.Dict[str, typing.Any] = {}, timeout: int = 45):
1351
1351
  """
1352
- Specifies that this step should execute on DGX cloud.
1352
+ Creates a human-readable report, a Metaflow Card, after this step completes.
1353
+
1354
+ Note that you may add multiple `@card` decorators in a step with different parameters.
1353
1355
 
1354
1356
 
1355
1357
  Parameters
1356
1358
  ----------
1357
- gpu : int
1358
- Number of GPUs to use.
1359
- gpu_type : str
1360
- Type of Nvidia GPU to use.
1361
- queue_timeout : int
1362
- Time to keep the job in NVCF's queue.
1359
+ type : str, default 'default'
1360
+ Card type.
1361
+ id : str, optional, default None
1362
+ If multiple cards are present, use this id to identify this card.
1363
+ options : Dict[str, Any], default {}
1364
+ Options passed to the card. The contents depend on the card type.
1365
+ timeout : int, default 45
1366
+ Interrupt reporting if it takes more than this many seconds.
1363
1367
  """
1364
1368
  ...
1365
1369
 
1366
- def s3_proxy(*, integration_name: typing.Optional[str] = None, write_mode: typing.Optional[str] = None, debug: typing.Optional[bool] = None) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1370
+ def vllm(*, model: str, backend: str, openai_api_server: bool, debug: bool, card_refresh_interval: int, max_retries: int, retry_alert_frequency: int, engine_args: dict) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1367
1371
  """
1368
- S3 Proxy decorator for routing S3 requests through a local proxy service.
1372
+ This decorator is used to run vllm APIs as Metaflow task sidecars.
1373
+
1374
+ User code call
1375
+ --------------
1376
+ @vllm(
1377
+ model="...",
1378
+ ...
1379
+ )
1380
+
1381
+ Valid backend options
1382
+ ---------------------
1383
+ - 'local': Run as a separate process on the local task machine.
1384
+
1385
+ Valid model options
1386
+ -------------------
1387
+ Any HuggingFace model identifier, e.g. 'meta-llama/Llama-3.2-1B'
1388
+
1389
+ NOTE: vLLM's OpenAI-compatible server serves ONE model per server instance.
1390
+ If you need multiple models, you must create multiple @vllm decorators.
1369
1391
 
1370
1392
 
1371
1393
  Parameters
1372
1394
  ----------
1373
- integration_name : str, optional
1374
- Name of the S3 proxy integration. If not specified, will use the only
1375
- available S3 proxy integration in the namespace (fails if multiple exist).
1376
- write_mode : str, optional
1377
- The desired behavior during write operations to target (origin) S3 bucket.
1378
- allowed options are:
1379
- "origin-and-cache" -> write to both the target S3 bucket and local object
1380
- storage
1381
- "origin" -> only write to the target S3 bucket
1382
- "cache" -> only write to the object storage service used for caching
1383
- debug : bool, optional
1384
- Enable debug logging for proxy operations.
1395
+ model: str
1396
+ HuggingFace model identifier to be served by vLLM.
1397
+ backend: str
1398
+ Determines where and how to run the vLLM process.
1399
+ openai_api_server: bool
1400
+ Whether to use OpenAI-compatible API server mode (subprocess) instead of native engine.
1401
+ Default is False (uses native engine).
1402
+ Set to True for backward compatibility with existing code.
1403
+ debug: bool
1404
+ Whether to turn on verbose debugging logs.
1405
+ card_refresh_interval: int
1406
+ Interval in seconds for refreshing the vLLM status card.
1407
+ Only used when openai_api_server=True.
1408
+ max_retries: int
1409
+ Maximum number of retries checking for vLLM server startup.
1410
+ Only used when openai_api_server=True.
1411
+ retry_alert_frequency: int
1412
+ Frequency of alert logs for vLLM server startup retries.
1413
+ Only used when openai_api_server=True.
1414
+ engine_args : dict
1415
+ Additional keyword arguments to pass to the vLLM engine.
1416
+ For example, `tensor_parallel_size=2`.
1385
1417
  """
1386
1418
  ...
1387
1419
 
1388
1420
  @typing.overload
1389
- def schedule(*, hourly: bool = False, daily: bool = True, weekly: bool = False, cron: typing.Optional[str] = None, timezone: typing.Optional[str] = None) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1421
+ def conda(*, packages: typing.Dict[str, str] = {}, libraries: typing.Dict[str, str] = {}, python: typing.Optional[str] = None, disabled: bool = False) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1390
1422
  """
1391
- Specifies the times when the flow should be run when running on a
1392
- production scheduler.
1423
+ Specifies the Conda environment for the step.
1424
+
1425
+ Information in this decorator will augment any
1426
+ attributes set in the `@conda_base` flow-level decorator. Hence,
1427
+ you can use `@conda_base` to set packages required by all
1428
+ steps and use `@conda` to specify step-specific overrides.
1393
1429
 
1394
1430
 
1395
1431
  Parameters
1396
1432
  ----------
1397
- hourly : bool, default False
1398
- Run the workflow hourly.
1399
- daily : bool, default True
1400
- Run the workflow daily.
1401
- weekly : bool, default False
1402
- Run the workflow weekly.
1403
- cron : str, optional, default None
1404
- Run the workflow at [a custom Cron schedule](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html#cron-expressions)
1405
- specified by this expression.
1406
- timezone : str, optional, default None
1407
- Timezone on which the schedule runs (default: None). Currently supported only for Argo workflows,
1408
- which accepts timezones in [IANA format](https://nodatime.org/TimeZones).
1433
+ packages : Dict[str, str], default {}
1434
+ Packages to use for this step. The key is the name of the package
1435
+ and the value is the version to use.
1436
+ libraries : Dict[str, str], default {}
1437
+ Supported for backward compatibility. When used with packages, packages will take precedence.
1438
+ python : str, optional, default None
1439
+ Version of Python to use, e.g. '3.7.4'. A default value of None implies
1440
+ that the version used will correspond to the version of the Python interpreter used to start the run.
1441
+ disabled : bool, default False
1442
+ If set to True, disables @conda.
1409
1443
  """
1410
1444
  ...
1411
1445
 
1412
1446
  @typing.overload
1413
- def schedule(f: typing.Type[FlowSpecDerived]) -> typing.Type[FlowSpecDerived]:
1447
+ def conda(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1414
1448
  ...
1415
1449
 
1416
- def schedule(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, hourly: bool = False, daily: bool = True, weekly: bool = False, cron: typing.Optional[str] = None, timezone: typing.Optional[str] = None):
1450
+ @typing.overload
1451
+ def conda(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1452
+ ...
1453
+
1454
+ def conda(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None, *, packages: typing.Dict[str, str] = {}, libraries: typing.Dict[str, str] = {}, python: typing.Optional[str] = None, disabled: bool = False):
1417
1455
  """
1418
- Specifies the times when the flow should be run when running on a
1419
- production scheduler.
1456
+ Specifies the Conda environment for the step.
1457
+
1458
+ Information in this decorator will augment any
1459
+ attributes set in the `@conda_base` flow-level decorator. Hence,
1460
+ you can use `@conda_base` to set packages required by all
1461
+ steps and use `@conda` to specify step-specific overrides.
1420
1462
 
1421
1463
 
1422
1464
  Parameters
1423
1465
  ----------
1424
- hourly : bool, default False
1425
- Run the workflow hourly.
1426
- daily : bool, default True
1427
- Run the workflow daily.
1428
- weekly : bool, default False
1429
- Run the workflow weekly.
1430
- cron : str, optional, default None
1431
- Run the workflow at [a custom Cron schedule](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html#cron-expressions)
1432
- specified by this expression.
1433
- timezone : str, optional, default None
1434
- Timezone on which the schedule runs (default: None). Currently supported only for Argo workflows,
1435
- which accepts timezones in [IANA format](https://nodatime.org/TimeZones).
1466
+ packages : Dict[str, str], default {}
1467
+ Packages to use for this step. The key is the name of the package
1468
+ and the value is the version to use.
1469
+ libraries : Dict[str, str], default {}
1470
+ Supported for backward compatibility. When used with packages, packages will take precedence.
1471
+ python : str, optional, default None
1472
+ Version of Python to use, e.g. '3.7.4'. A default value of None implies
1473
+ that the version used will correspond to the version of the Python interpreter used to start the run.
1474
+ disabled : bool, default False
1475
+ If set to True, disables @conda.
1436
1476
  """
1437
1477
  ...
1438
1478
 
1439
- def airflow_s3_key_sensor(*, timeout: int, poke_interval: int, mode: str, exponential_backoff: bool, pool: str, soft_fail: bool, name: str, description: str, bucket_key: typing.Union[str, typing.List[str]], bucket_name: str, wildcard_match: bool, aws_conn_id: str, verify: bool) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1479
+ @typing.overload
1480
+ def parallel(f: typing.Callable[[FlowSpecDerived, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, StepFlag], None]:
1440
1481
  """
1441
- The `@airflow_s3_key_sensor` decorator attaches a Airflow [S3KeySensor](https://airflow.apache.org/docs/apache-airflow-providers-amazon/stable/_api/airflow/providers/amazon/aws/sensors/s3/index.html#airflow.providers.amazon.aws.sensors.s3.S3KeySensor)
1442
- before the start step of the flow. This decorator only works when a flow is scheduled on Airflow
1443
- and is compiled using `airflow create`. More than one `@airflow_s3_key_sensor` can be
1444
- added as a flow decorators. Adding more than one decorator will ensure that `start` step
1445
- starts only after all sensors finish.
1446
-
1447
-
1448
- Parameters
1449
- ----------
1450
- timeout : int
1451
- Time, in seconds before the task times out and fails. (Default: 3600)
1452
- poke_interval : int
1453
- Time in seconds that the job should wait in between each try. (Default: 60)
1454
- mode : str
1455
- How the sensor operates. Options are: { poke | reschedule }. (Default: "poke")
1456
- exponential_backoff : bool
1457
- allow progressive longer waits between pokes by using exponential backoff algorithm. (Default: True)
1458
- pool : str
1459
- the slot pool this task should run in,
1460
- slot pools are a way to limit concurrency for certain tasks. (Default:None)
1461
- soft_fail : bool
1462
- Set to true to mark the task as SKIPPED on failure. (Default: False)
1463
- name : str
1464
- Name of the sensor on Airflow
1465
- description : str
1466
- Description of sensor in the Airflow UI
1467
- bucket_key : Union[str, List[str]]
1468
- The key(s) being waited on. Supports full s3:// style url or relative path from root level.
1469
- When it's specified as a full s3:// url, please leave `bucket_name` as None
1470
- bucket_name : str
1471
- Name of the S3 bucket. Only needed when bucket_key is not provided as a full s3:// url.
1472
- When specified, all the keys passed to bucket_key refers to this bucket. (Default:None)
1473
- wildcard_match : bool
1474
- whether the bucket_key should be interpreted as a Unix wildcard pattern. (Default: False)
1475
- aws_conn_id : str
1476
- a reference to the s3 connection on Airflow. (Default: None)
1477
- verify : bool
1478
- Whether or not to verify SSL certificates for S3 connection. (Default: None)
1482
+ Decorator prototype for all step decorators. This function gets specialized
1483
+ and imported for all decorators types by _import_plugin_decorators().
1479
1484
  """
1480
1485
  ...
1481
1486
 
1482
- def with_artifact_store(f: typing.Optional[typing.Type[FlowSpecDerived]] = None):
1487
+ @typing.overload
1488
+ def parallel(f: typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]) -> typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]:
1489
+ ...
1490
+
1491
+ def parallel(f: typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None], None] = None):
1483
1492
  """
1484
- Allows setting external datastores to save data for the
1485
- `@checkpoint`/`@model`/`@huggingface_hub` decorators.
1486
-
1487
- This decorator is useful when users wish to save data to a different datastore
1488
- than what is configured in Metaflow. This can be for variety of reasons:
1489
-
1490
- 1. Data security: The objects needs to be stored in a bucket (object storage) that is not accessible by other flows.
1491
- 2. Data Locality: The location where the task is executing is not located in the same region as the datastore.
1492
- - Example: Metaflow datastore lives in US East, but the task is executing in Finland datacenters.
1493
- 3. Data Lifecycle Policies: The objects need to be archived / managed separately from the Metaflow managed objects.
1494
- - Example: Flow is training very large models that need to be stored separately and will be deleted more aggressively than the Metaflow managed objects.
1495
-
1496
- Usage:
1497
- ----------
1498
-
1499
- - Using a custom IAM role to access the datastore.
1500
-
1501
- ```python
1502
- @with_artifact_store(
1503
- type="s3",
1504
- config=lambda: {
1505
- "root": "s3://my-bucket-foo/path/to/root",
1506
- "role_arn": ROLE,
1507
- },
1508
- )
1509
- class MyFlow(FlowSpec):
1510
-
1511
- @checkpoint
1512
- @step
1513
- def start(self):
1514
- with open("my_file.txt", "w") as f:
1515
- f.write("Hello, World!")
1516
- self.external_bucket_checkpoint = current.checkpoint.save("my_file.txt")
1517
- self.next(self.end)
1518
-
1519
- ```
1520
-
1521
- - Using credentials to access the s3-compatible datastore.
1522
-
1523
- ```python
1524
- @with_artifact_store(
1525
- type="s3",
1526
- config=lambda: {
1527
- "root": "s3://my-bucket-foo/path/to/root",
1528
- "client_params": {
1529
- "aws_access_key_id": os.environ.get("MY_CUSTOM_ACCESS_KEY"),
1530
- "aws_secret_access_key": os.environ.get("MY_CUSTOM_SECRET_KEY"),
1531
- },
1532
- },
1533
- )
1534
- class MyFlow(FlowSpec):
1535
-
1536
- @checkpoint
1537
- @step
1538
- def start(self):
1539
- with open("my_file.txt", "w") as f:
1540
- f.write("Hello, World!")
1541
- self.external_bucket_checkpoint = current.checkpoint.save("my_file.txt")
1542
- self.next(self.end)
1493
+ Decorator prototype for all step decorators. This function gets specialized
1494
+ and imported for all decorators types by _import_plugin_decorators().
1495
+ """
1496
+ ...
1497
+
1498
+ def nvct(*, gpu: int, gpu_type: str) -> typing.Callable[[typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]], typing.Union[typing.Callable[[FlowSpecDerived, StepFlag], None], typing.Callable[[FlowSpecDerived, typing.Any, StepFlag], None]]]:
1499
+ """
1500
+ Specifies that this step should execute on DGX cloud.
1543
1501
 
1544
- ```
1545
1502
 
1546
- - Accessing objects stored in external datastores after task execution.
1503
+ Parameters
1504
+ ----------
1505
+ gpu : int
1506
+ Number of GPUs to use.
1507
+ gpu_type : str
1508
+ Type of Nvidia GPU to use.
1509
+ """
1510
+ ...
1511
+
1512
+ def project(*, name: str, branch: typing.Optional[str] = None, production: bool = False) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1513
+ """
1514
+ Specifies what flows belong to the same project.
1547
1515
 
1548
- ```python
1549
- run = Run("CheckpointsTestsFlow/8992")
1550
- with artifact_store_from(run=run, config={
1551
- "client_params": {
1552
- "aws_access_key_id": os.environ.get("MY_CUSTOM_ACCESS_KEY"),
1553
- "aws_secret_access_key": os.environ.get("MY_CUSTOM_SECRET_KEY"),
1554
- },
1555
- }):
1556
- with Checkpoint() as cp:
1557
- latest = cp.list(
1558
- task=run["start"].task
1559
- )[0]
1560
- print(latest)
1561
- cp.load(
1562
- latest,
1563
- "test-checkpoints"
1564
- )
1516
+ A project-specific namespace is created for all flows that
1517
+ use the same `@project(name)`.
1565
1518
 
1566
- task = Task("TorchTuneFlow/8484/train/53673")
1567
- with artifact_store_from(run=run, config={
1568
- "client_params": {
1569
- "aws_access_key_id": os.environ.get("MY_CUSTOM_ACCESS_KEY"),
1570
- "aws_secret_access_key": os.environ.get("MY_CUSTOM_SECRET_KEY"),
1571
- },
1572
- }):
1573
- load_model(
1574
- task.data.model_ref,
1575
- "test-models"
1576
- )
1577
- ```
1578
- Parameters:
1519
+
1520
+ Parameters
1579
1521
  ----------
1522
+ name : str
1523
+ Project name. Make sure that the name is unique amongst all
1524
+ projects that use the same production scheduler. The name may
1525
+ contain only lowercase alphanumeric characters and underscores.
1580
1526
 
1581
- type: str
1582
- The type of the datastore. Can be one of 's3', 'gcs', 'azure' or any other supported metaflow Datastore.
1527
+ branch : Optional[str], default None
1528
+ The branch to use. If not specified, the branch is set to
1529
+ `user.<username>` unless `production` is set to `True`. This can
1530
+ also be set on the command line using `--branch` as a top-level option.
1531
+ It is an error to specify `branch` in the decorator and on the command line.
1583
1532
 
1584
- config: dict or Callable
1585
- Dictionary of configuration options for the datastore. The following keys are required:
1586
- - root: The root path in the datastore where the data will be saved. (needs to be in the format expected by the datastore)
1587
- - example: 's3://bucket-name/path/to/root'
1588
- - example: 'gs://bucket-name/path/to/root'
1589
- - example: 'https://myblockacc.blob.core.windows.net/metaflow/'
1590
- - role_arn (optional): AWS IAM role to access s3 bucket (only when `type` is 's3')
1591
- - session_vars (optional): AWS session variables to access s3 bucket (only when `type` is 's3')
1592
- - client_params (optional): AWS client parameters to access s3 bucket (only when `type` is 's3')
1533
+ production : bool, default False
1534
+ Whether or not the branch is the production branch. This can also be set on the
1535
+ command line using `--production` as a top-level option. It is an error to specify
1536
+ `production` in the decorator and on the command line.
1537
+ The project branch name will be:
1538
+ - if `branch` is specified:
1539
+ - if `production` is True: `prod.<branch>`
1540
+ - if `production` is False: `test.<branch>`
1541
+ - if `branch` is not specified:
1542
+ - if `production` is True: `prod`
1543
+ - if `production` is False: `user.<username>`
1593
1544
  """
1594
1545
  ...
1595
1546
 
@@ -1686,238 +1637,363 @@ def pypi_base(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, packag
1686
1637
  ...
1687
1638
 
1688
1639
  @typing.overload
1689
- def trigger_on_finish(*, flow: typing.Union[typing.Dict[str, str], str, None] = None, flows: typing.List[typing.Union[str, typing.Dict[str, str]]] = [], options: typing.Dict[str, typing.Any] = {}) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1640
+ def trigger(*, event: typing.Union[str, typing.Dict[str, typing.Any], None] = None, events: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], options: typing.Dict[str, typing.Any] = {}) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1690
1641
  """
1691
- Specifies the flow(s) that this flow depends on.
1642
+ Specifies the event(s) that this flow depends on.
1692
1643
 
1693
1644
  ```
1694
- @trigger_on_finish(flow='FooFlow')
1645
+ @trigger(event='foo')
1695
1646
  ```
1696
1647
  or
1697
1648
  ```
1698
- @trigger_on_finish(flows=['FooFlow', 'BarFlow'])
1649
+ @trigger(events=['foo', 'bar'])
1699
1650
  ```
1700
- This decorator respects the @project decorator and triggers the flow
1701
- when upstream runs within the same namespace complete successfully
1702
1651
 
1703
- Additionally, you can specify project aware upstream flow dependencies
1704
- by specifying the fully qualified project_flow_name.
1652
+ Additionally, you can specify the parameter mappings
1653
+ to map event payload to Metaflow parameters for the flow.
1705
1654
  ```
1706
- @trigger_on_finish(flow='my_project.branch.my_branch.FooFlow')
1655
+ @trigger(event={'name':'foo', 'parameters':{'flow_param': 'event_field'}})
1707
1656
  ```
1708
1657
  or
1709
1658
  ```
1710
- @trigger_on_finish(flows=['my_project.branch.my_branch.FooFlow', 'BarFlow'])
1659
+ @trigger(events=[{'name':'foo', 'parameters':{'flow_param_1': 'event_field_1'},
1660
+ {'name':'bar', 'parameters':{'flow_param_2': 'event_field_2'}])
1711
1661
  ```
1712
1662
 
1713
- You can also specify just the project or project branch (other values will be
1714
- inferred from the current project or project branch):
1663
+ 'parameters' can also be a list of strings and tuples like so:
1715
1664
  ```
1716
- @trigger_on_finish(flow={"name": "FooFlow", "project": "my_project", "project_branch": "branch"})
1665
+ @trigger(event={'name':'foo', 'parameters':['common_name', ('flow_param', 'event_field')]})
1666
+ ```
1667
+ This is equivalent to:
1668
+ ```
1669
+ @trigger(event={'name':'foo', 'parameters':{'common_name': 'common_name', 'flow_param': 'event_field'}})
1717
1670
  ```
1718
-
1719
- Note that `branch` is typically one of:
1720
- - `prod`
1721
- - `user.bob`
1722
- - `test.my_experiment`
1723
- - `prod.staging`
1724
1671
 
1725
1672
 
1726
1673
  Parameters
1727
1674
  ----------
1728
- flow : Union[str, Dict[str, str]], optional, default None
1729
- Upstream flow dependency for this flow.
1730
- flows : List[Union[str, Dict[str, str]]], default []
1731
- Upstream flow dependencies for this flow.
1675
+ event : Union[str, Dict[str, Any]], optional, default None
1676
+ Event dependency for this flow.
1677
+ events : List[Union[str, Dict[str, Any]]], default []
1678
+ Events dependency for this flow.
1732
1679
  options : Dict[str, Any], default {}
1733
1680
  Backend-specific configuration for tuning eventing behavior.
1734
1681
  """
1735
1682
  ...
1736
1683
 
1737
1684
  @typing.overload
1738
- def trigger_on_finish(f: typing.Type[FlowSpecDerived]) -> typing.Type[FlowSpecDerived]:
1685
+ def trigger(f: typing.Type[FlowSpecDerived]) -> typing.Type[FlowSpecDerived]:
1739
1686
  ...
1740
1687
 
1741
- def trigger_on_finish(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, flow: typing.Union[typing.Dict[str, str], str, None] = None, flows: typing.List[typing.Union[str, typing.Dict[str, str]]] = [], options: typing.Dict[str, typing.Any] = {}):
1688
+ def trigger(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, event: typing.Union[str, typing.Dict[str, typing.Any], None] = None, events: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], options: typing.Dict[str, typing.Any] = {}):
1742
1689
  """
1743
- Specifies the flow(s) that this flow depends on.
1690
+ Specifies the event(s) that this flow depends on.
1744
1691
 
1745
1692
  ```
1746
- @trigger_on_finish(flow='FooFlow')
1693
+ @trigger(event='foo')
1747
1694
  ```
1748
1695
  or
1749
1696
  ```
1750
- @trigger_on_finish(flows=['FooFlow', 'BarFlow'])
1697
+ @trigger(events=['foo', 'bar'])
1751
1698
  ```
1752
- This decorator respects the @project decorator and triggers the flow
1753
- when upstream runs within the same namespace complete successfully
1754
1699
 
1755
- Additionally, you can specify project aware upstream flow dependencies
1756
- by specifying the fully qualified project_flow_name.
1700
+ Additionally, you can specify the parameter mappings
1701
+ to map event payload to Metaflow parameters for the flow.
1757
1702
  ```
1758
- @trigger_on_finish(flow='my_project.branch.my_branch.FooFlow')
1703
+ @trigger(event={'name':'foo', 'parameters':{'flow_param': 'event_field'}})
1759
1704
  ```
1760
1705
  or
1761
1706
  ```
1762
- @trigger_on_finish(flows=['my_project.branch.my_branch.FooFlow', 'BarFlow'])
1707
+ @trigger(events=[{'name':'foo', 'parameters':{'flow_param_1': 'event_field_1'},
1708
+ {'name':'bar', 'parameters':{'flow_param_2': 'event_field_2'}])
1763
1709
  ```
1764
1710
 
1765
- You can also specify just the project or project branch (other values will be
1766
- inferred from the current project or project branch):
1711
+ 'parameters' can also be a list of strings and tuples like so:
1767
1712
  ```
1768
- @trigger_on_finish(flow={"name": "FooFlow", "project": "my_project", "project_branch": "branch"})
1713
+ @trigger(event={'name':'foo', 'parameters':['common_name', ('flow_param', 'event_field')]})
1714
+ ```
1715
+ This is equivalent to:
1716
+ ```
1717
+ @trigger(event={'name':'foo', 'parameters':{'common_name': 'common_name', 'flow_param': 'event_field'}})
1769
1718
  ```
1770
-
1771
- Note that `branch` is typically one of:
1772
- - `prod`
1773
- - `user.bob`
1774
- - `test.my_experiment`
1775
- - `prod.staging`
1776
1719
 
1777
1720
 
1778
1721
  Parameters
1779
1722
  ----------
1780
- flow : Union[str, Dict[str, str]], optional, default None
1781
- Upstream flow dependency for this flow.
1782
- flows : List[Union[str, Dict[str, str]]], default []
1783
- Upstream flow dependencies for this flow.
1723
+ event : Union[str, Dict[str, Any]], optional, default None
1724
+ Event dependency for this flow.
1725
+ events : List[Union[str, Dict[str, Any]]], default []
1726
+ Events dependency for this flow.
1784
1727
  options : Dict[str, Any], default {}
1785
1728
  Backend-specific configuration for tuning eventing behavior.
1786
1729
  """
1787
1730
  ...
1788
1731
 
1732
+ def airflow_external_task_sensor(*, timeout: int, poke_interval: int, mode: str, exponential_backoff: bool, pool: str, soft_fail: bool, name: str, description: str, external_dag_id: str, external_task_ids: typing.List[str], allowed_states: typing.List[str], failed_states: typing.List[str], execution_delta: "datetime.timedelta", check_existence: bool) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1733
+ """
1734
+ The `@airflow_external_task_sensor` decorator attaches a Airflow [ExternalTaskSensor](https://airflow.apache.org/docs/apache-airflow/stable/_api/airflow/sensors/external_task/index.html#airflow.sensors.external_task.ExternalTaskSensor) before the start step of the flow.
1735
+ This decorator only works when a flow is scheduled on Airflow and is compiled using `airflow create`. More than one `@airflow_external_task_sensor` can be added as a flow decorators. Adding more than one decorator will ensure that `start` step starts only after all sensors finish.
1736
+
1737
+
1738
+ Parameters
1739
+ ----------
1740
+ timeout : int
1741
+ Time, in seconds before the task times out and fails. (Default: 3600)
1742
+ poke_interval : int
1743
+ Time in seconds that the job should wait in between each try. (Default: 60)
1744
+ mode : str
1745
+ How the sensor operates. Options are: { poke | reschedule }. (Default: "poke")
1746
+ exponential_backoff : bool
1747
+ allow progressive longer waits between pokes by using exponential backoff algorithm. (Default: True)
1748
+ pool : str
1749
+ the slot pool this task should run in,
1750
+ slot pools are a way to limit concurrency for certain tasks. (Default:None)
1751
+ soft_fail : bool
1752
+ Set to true to mark the task as SKIPPED on failure. (Default: False)
1753
+ name : str
1754
+ Name of the sensor on Airflow
1755
+ description : str
1756
+ Description of sensor in the Airflow UI
1757
+ external_dag_id : str
1758
+ The dag_id that contains the task you want to wait for.
1759
+ external_task_ids : List[str]
1760
+ The list of task_ids that you want to wait for.
1761
+ If None (default value) the sensor waits for the DAG. (Default: None)
1762
+ allowed_states : List[str]
1763
+ Iterable of allowed states, (Default: ['success'])
1764
+ failed_states : List[str]
1765
+ Iterable of failed or dis-allowed states. (Default: None)
1766
+ execution_delta : datetime.timedelta
1767
+ time difference with the previous execution to look at,
1768
+ the default is the same logical date as the current task or DAG. (Default: None)
1769
+ check_existence: bool
1770
+ Set to True to check if the external task exists or check if
1771
+ the DAG to wait for exists. (Default: True)
1772
+ """
1773
+ ...
1774
+
1789
1775
  @typing.overload
1790
- def trigger(*, event: typing.Union[str, typing.Dict[str, typing.Any], None] = None, events: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], options: typing.Dict[str, typing.Any] = {}) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1776
+ def trigger_on_finish(*, flow: typing.Union[typing.Dict[str, str], str, None] = None, flows: typing.List[typing.Union[str, typing.Dict[str, str]]] = [], options: typing.Dict[str, typing.Any] = {}) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1791
1777
  """
1792
- Specifies the event(s) that this flow depends on.
1778
+ Specifies the flow(s) that this flow depends on.
1793
1779
 
1794
1780
  ```
1795
- @trigger(event='foo')
1781
+ @trigger_on_finish(flow='FooFlow')
1796
1782
  ```
1797
1783
  or
1798
1784
  ```
1799
- @trigger(events=['foo', 'bar'])
1785
+ @trigger_on_finish(flows=['FooFlow', 'BarFlow'])
1800
1786
  ```
1787
+ This decorator respects the @project decorator and triggers the flow
1788
+ when upstream runs within the same namespace complete successfully
1801
1789
 
1802
- Additionally, you can specify the parameter mappings
1803
- to map event payload to Metaflow parameters for the flow.
1790
+ Additionally, you can specify project aware upstream flow dependencies
1791
+ by specifying the fully qualified project_flow_name.
1804
1792
  ```
1805
- @trigger(event={'name':'foo', 'parameters':{'flow_param': 'event_field'}})
1793
+ @trigger_on_finish(flow='my_project.branch.my_branch.FooFlow')
1806
1794
  ```
1807
1795
  or
1808
1796
  ```
1809
- @trigger(events=[{'name':'foo', 'parameters':{'flow_param_1': 'event_field_1'},
1810
- {'name':'bar', 'parameters':{'flow_param_2': 'event_field_2'}])
1797
+ @trigger_on_finish(flows=['my_project.branch.my_branch.FooFlow', 'BarFlow'])
1811
1798
  ```
1812
1799
 
1813
- 'parameters' can also be a list of strings and tuples like so:
1814
- ```
1815
- @trigger(event={'name':'foo', 'parameters':['common_name', ('flow_param', 'event_field')]})
1816
- ```
1817
- This is equivalent to:
1800
+ You can also specify just the project or project branch (other values will be
1801
+ inferred from the current project or project branch):
1818
1802
  ```
1819
- @trigger(event={'name':'foo', 'parameters':{'common_name': 'common_name', 'flow_param': 'event_field'}})
1803
+ @trigger_on_finish(flow={"name": "FooFlow", "project": "my_project", "project_branch": "branch"})
1820
1804
  ```
1821
1805
 
1806
+ Note that `branch` is typically one of:
1807
+ - `prod`
1808
+ - `user.bob`
1809
+ - `test.my_experiment`
1810
+ - `prod.staging`
1811
+
1822
1812
 
1823
1813
  Parameters
1824
1814
  ----------
1825
- event : Union[str, Dict[str, Any]], optional, default None
1826
- Event dependency for this flow.
1827
- events : List[Union[str, Dict[str, Any]]], default []
1828
- Events dependency for this flow.
1815
+ flow : Union[str, Dict[str, str]], optional, default None
1816
+ Upstream flow dependency for this flow.
1817
+ flows : List[Union[str, Dict[str, str]]], default []
1818
+ Upstream flow dependencies for this flow.
1829
1819
  options : Dict[str, Any], default {}
1830
1820
  Backend-specific configuration for tuning eventing behavior.
1831
1821
  """
1832
1822
  ...
1833
1823
 
1834
1824
  @typing.overload
1835
- def trigger(f: typing.Type[FlowSpecDerived]) -> typing.Type[FlowSpecDerived]:
1825
+ def trigger_on_finish(f: typing.Type[FlowSpecDerived]) -> typing.Type[FlowSpecDerived]:
1836
1826
  ...
1837
1827
 
1838
- def trigger(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, event: typing.Union[str, typing.Dict[str, typing.Any], None] = None, events: typing.List[typing.Union[str, typing.Dict[str, typing.Any]]] = [], options: typing.Dict[str, typing.Any] = {}):
1828
+ def trigger_on_finish(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, flow: typing.Union[typing.Dict[str, str], str, None] = None, flows: typing.List[typing.Union[str, typing.Dict[str, str]]] = [], options: typing.Dict[str, typing.Any] = {}):
1839
1829
  """
1840
- Specifies the event(s) that this flow depends on.
1830
+ Specifies the flow(s) that this flow depends on.
1841
1831
 
1842
1832
  ```
1843
- @trigger(event='foo')
1833
+ @trigger_on_finish(flow='FooFlow')
1844
1834
  ```
1845
1835
  or
1846
1836
  ```
1847
- @trigger(events=['foo', 'bar'])
1837
+ @trigger_on_finish(flows=['FooFlow', 'BarFlow'])
1848
1838
  ```
1839
+ This decorator respects the @project decorator and triggers the flow
1840
+ when upstream runs within the same namespace complete successfully
1849
1841
 
1850
- Additionally, you can specify the parameter mappings
1851
- to map event payload to Metaflow parameters for the flow.
1842
+ Additionally, you can specify project aware upstream flow dependencies
1843
+ by specifying the fully qualified project_flow_name.
1852
1844
  ```
1853
- @trigger(event={'name':'foo', 'parameters':{'flow_param': 'event_field'}})
1845
+ @trigger_on_finish(flow='my_project.branch.my_branch.FooFlow')
1854
1846
  ```
1855
1847
  or
1856
1848
  ```
1857
- @trigger(events=[{'name':'foo', 'parameters':{'flow_param_1': 'event_field_1'},
1858
- {'name':'bar', 'parameters':{'flow_param_2': 'event_field_2'}])
1849
+ @trigger_on_finish(flows=['my_project.branch.my_branch.FooFlow', 'BarFlow'])
1859
1850
  ```
1860
1851
 
1861
- 'parameters' can also be a list of strings and tuples like so:
1862
- ```
1863
- @trigger(event={'name':'foo', 'parameters':['common_name', ('flow_param', 'event_field')]})
1864
- ```
1865
- This is equivalent to:
1852
+ You can also specify just the project or project branch (other values will be
1853
+ inferred from the current project or project branch):
1866
1854
  ```
1867
- @trigger(event={'name':'foo', 'parameters':{'common_name': 'common_name', 'flow_param': 'event_field'}})
1855
+ @trigger_on_finish(flow={"name": "FooFlow", "project": "my_project", "project_branch": "branch"})
1868
1856
  ```
1869
1857
 
1858
+ Note that `branch` is typically one of:
1859
+ - `prod`
1860
+ - `user.bob`
1861
+ - `test.my_experiment`
1862
+ - `prod.staging`
1863
+
1870
1864
 
1871
1865
  Parameters
1872
1866
  ----------
1873
- event : Union[str, Dict[str, Any]], optional, default None
1874
- Event dependency for this flow.
1875
- events : List[Union[str, Dict[str, Any]]], default []
1876
- Events dependency for this flow.
1867
+ flow : Union[str, Dict[str, str]], optional, default None
1868
+ Upstream flow dependency for this flow.
1869
+ flows : List[Union[str, Dict[str, str]]], default []
1870
+ Upstream flow dependencies for this flow.
1877
1871
  options : Dict[str, Any], default {}
1878
1872
  Backend-specific configuration for tuning eventing behavior.
1879
1873
  """
1880
1874
  ...
1881
1875
 
1882
- def project(*, name: str, branch: typing.Optional[str] = None, production: bool = False) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1876
+ def with_artifact_store(f: typing.Optional[typing.Type[FlowSpecDerived]] = None):
1883
1877
  """
1884
- Specifies what flows belong to the same project.
1878
+ Allows setting external datastores to save data for the
1879
+ `@checkpoint`/`@model`/`@huggingface_hub` decorators.
1885
1880
 
1886
- A project-specific namespace is created for all flows that
1887
- use the same `@project(name)`.
1881
+ This decorator is useful when users wish to save data to a different datastore
1882
+ than what is configured in Metaflow. This can be for variety of reasons:
1888
1883
 
1884
+ 1. Data security: The objects needs to be stored in a bucket (object storage) that is not accessible by other flows.
1885
+ 2. Data Locality: The location where the task is executing is not located in the same region as the datastore.
1886
+ - Example: Metaflow datastore lives in US East, but the task is executing in Finland datacenters.
1887
+ 3. Data Lifecycle Policies: The objects need to be archived / managed separately from the Metaflow managed objects.
1888
+ - Example: Flow is training very large models that need to be stored separately and will be deleted more aggressively than the Metaflow managed objects.
1889
1889
 
1890
- Parameters
1890
+ Usage:
1891
1891
  ----------
1892
- name : str
1893
- Project name. Make sure that the name is unique amongst all
1894
- projects that use the same production scheduler. The name may
1895
- contain only lowercase alphanumeric characters and underscores.
1896
1892
 
1897
- branch : Optional[str], default None
1898
- The branch to use. If not specified, the branch is set to
1899
- `user.<username>` unless `production` is set to `True`. This can
1900
- also be set on the command line using `--branch` as a top-level option.
1901
- It is an error to specify `branch` in the decorator and on the command line.
1893
+ - Using a custom IAM role to access the datastore.
1902
1894
 
1903
- production : bool, default False
1904
- Whether or not the branch is the production branch. This can also be set on the
1905
- command line using `--production` as a top-level option. It is an error to specify
1906
- `production` in the decorator and on the command line.
1907
- The project branch name will be:
1908
- - if `branch` is specified:
1909
- - if `production` is True: `prod.<branch>`
1910
- - if `production` is False: `test.<branch>`
1911
- - if `branch` is not specified:
1912
- - if `production` is True: `prod`
1913
- - if `production` is False: `user.<username>`
1895
+ ```python
1896
+ @with_artifact_store(
1897
+ type="s3",
1898
+ config=lambda: {
1899
+ "root": "s3://my-bucket-foo/path/to/root",
1900
+ "role_arn": ROLE,
1901
+ },
1902
+ )
1903
+ class MyFlow(FlowSpec):
1904
+
1905
+ @checkpoint
1906
+ @step
1907
+ def start(self):
1908
+ with open("my_file.txt", "w") as f:
1909
+ f.write("Hello, World!")
1910
+ self.external_bucket_checkpoint = current.checkpoint.save("my_file.txt")
1911
+ self.next(self.end)
1912
+
1913
+ ```
1914
+
1915
+ - Using credentials to access the s3-compatible datastore.
1916
+
1917
+ ```python
1918
+ @with_artifact_store(
1919
+ type="s3",
1920
+ config=lambda: {
1921
+ "root": "s3://my-bucket-foo/path/to/root",
1922
+ "client_params": {
1923
+ "aws_access_key_id": os.environ.get("MY_CUSTOM_ACCESS_KEY"),
1924
+ "aws_secret_access_key": os.environ.get("MY_CUSTOM_SECRET_KEY"),
1925
+ },
1926
+ },
1927
+ )
1928
+ class MyFlow(FlowSpec):
1929
+
1930
+ @checkpoint
1931
+ @step
1932
+ def start(self):
1933
+ with open("my_file.txt", "w") as f:
1934
+ f.write("Hello, World!")
1935
+ self.external_bucket_checkpoint = current.checkpoint.save("my_file.txt")
1936
+ self.next(self.end)
1937
+
1938
+ ```
1939
+
1940
+ - Accessing objects stored in external datastores after task execution.
1941
+
1942
+ ```python
1943
+ run = Run("CheckpointsTestsFlow/8992")
1944
+ with artifact_store_from(run=run, config={
1945
+ "client_params": {
1946
+ "aws_access_key_id": os.environ.get("MY_CUSTOM_ACCESS_KEY"),
1947
+ "aws_secret_access_key": os.environ.get("MY_CUSTOM_SECRET_KEY"),
1948
+ },
1949
+ }):
1950
+ with Checkpoint() as cp:
1951
+ latest = cp.list(
1952
+ task=run["start"].task
1953
+ )[0]
1954
+ print(latest)
1955
+ cp.load(
1956
+ latest,
1957
+ "test-checkpoints"
1958
+ )
1959
+
1960
+ task = Task("TorchTuneFlow/8484/train/53673")
1961
+ with artifact_store_from(run=run, config={
1962
+ "client_params": {
1963
+ "aws_access_key_id": os.environ.get("MY_CUSTOM_ACCESS_KEY"),
1964
+ "aws_secret_access_key": os.environ.get("MY_CUSTOM_SECRET_KEY"),
1965
+ },
1966
+ }):
1967
+ load_model(
1968
+ task.data.model_ref,
1969
+ "test-models"
1970
+ )
1971
+ ```
1972
+ Parameters:
1973
+ ----------
1974
+
1975
+ type: str
1976
+ The type of the datastore. Can be one of 's3', 'gcs', 'azure' or any other supported metaflow Datastore.
1977
+
1978
+ config: dict or Callable
1979
+ Dictionary of configuration options for the datastore. The following keys are required:
1980
+ - root: The root path in the datastore where the data will be saved. (needs to be in the format expected by the datastore)
1981
+ - example: 's3://bucket-name/path/to/root'
1982
+ - example: 'gs://bucket-name/path/to/root'
1983
+ - example: 'https://myblockacc.blob.core.windows.net/metaflow/'
1984
+ - role_arn (optional): AWS IAM role to access s3 bucket (only when `type` is 's3')
1985
+ - session_vars (optional): AWS session variables to access s3 bucket (only when `type` is 's3')
1986
+ - client_params (optional): AWS client parameters to access s3 bucket (only when `type` is 's3')
1914
1987
  """
1915
1988
  ...
1916
1989
 
1917
- def airflow_external_task_sensor(*, timeout: int, poke_interval: int, mode: str, exponential_backoff: bool, pool: str, soft_fail: bool, name: str, description: str, external_dag_id: str, external_task_ids: typing.List[str], allowed_states: typing.List[str], failed_states: typing.List[str], execution_delta: "datetime.timedelta", check_existence: bool) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1990
+ def airflow_s3_key_sensor(*, timeout: int, poke_interval: int, mode: str, exponential_backoff: bool, pool: str, soft_fail: bool, name: str, description: str, bucket_key: typing.Union[str, typing.List[str]], bucket_name: str, wildcard_match: bool, aws_conn_id: str, verify: bool) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
1918
1991
  """
1919
- The `@airflow_external_task_sensor` decorator attaches a Airflow [ExternalTaskSensor](https://airflow.apache.org/docs/apache-airflow/stable/_api/airflow/sensors/external_task/index.html#airflow.sensors.external_task.ExternalTaskSensor) before the start step of the flow.
1920
- This decorator only works when a flow is scheduled on Airflow and is compiled using `airflow create`. More than one `@airflow_external_task_sensor` can be added as a flow decorators. Adding more than one decorator will ensure that `start` step starts only after all sensors finish.
1992
+ The `@airflow_s3_key_sensor` decorator attaches a Airflow [S3KeySensor](https://airflow.apache.org/docs/apache-airflow-providers-amazon/stable/_api/airflow/providers/amazon/aws/sensors/s3/index.html#airflow.providers.amazon.aws.sensors.s3.S3KeySensor)
1993
+ before the start step of the flow. This decorator only works when a flow is scheduled on Airflow
1994
+ and is compiled using `airflow create`. More than one `@airflow_s3_key_sensor` can be
1995
+ added as a flow decorators. Adding more than one decorator will ensure that `start` step
1996
+ starts only after all sensors finish.
1921
1997
 
1922
1998
 
1923
1999
  Parameters
@@ -1939,21 +2015,69 @@ def airflow_external_task_sensor(*, timeout: int, poke_interval: int, mode: str,
1939
2015
  Name of the sensor on Airflow
1940
2016
  description : str
1941
2017
  Description of sensor in the Airflow UI
1942
- external_dag_id : str
1943
- The dag_id that contains the task you want to wait for.
1944
- external_task_ids : List[str]
1945
- The list of task_ids that you want to wait for.
1946
- If None (default value) the sensor waits for the DAG. (Default: None)
1947
- allowed_states : List[str]
1948
- Iterable of allowed states, (Default: ['success'])
1949
- failed_states : List[str]
1950
- Iterable of failed or dis-allowed states. (Default: None)
1951
- execution_delta : datetime.timedelta
1952
- time difference with the previous execution to look at,
1953
- the default is the same logical date as the current task or DAG. (Default: None)
1954
- check_existence: bool
1955
- Set to True to check if the external task exists or check if
1956
- the DAG to wait for exists. (Default: True)
2018
+ bucket_key : Union[str, List[str]]
2019
+ The key(s) being waited on. Supports full s3:// style url or relative path from root level.
2020
+ When it's specified as a full s3:// url, please leave `bucket_name` as None
2021
+ bucket_name : str
2022
+ Name of the S3 bucket. Only needed when bucket_key is not provided as a full s3:// url.
2023
+ When specified, all the keys passed to bucket_key refers to this bucket. (Default:None)
2024
+ wildcard_match : bool
2025
+ whether the bucket_key should be interpreted as a Unix wildcard pattern. (Default: False)
2026
+ aws_conn_id : str
2027
+ a reference to the s3 connection on Airflow. (Default: None)
2028
+ verify : bool
2029
+ Whether or not to verify SSL certificates for S3 connection. (Default: None)
2030
+ """
2031
+ ...
2032
+
2033
+ @typing.overload
2034
+ def schedule(*, hourly: bool = False, daily: bool = True, weekly: bool = False, cron: typing.Optional[str] = None, timezone: typing.Optional[str] = None) -> typing.Callable[[typing.Type[FlowSpecDerived]], typing.Type[FlowSpecDerived]]:
2035
+ """
2036
+ Specifies the times when the flow should be run when running on a
2037
+ production scheduler.
2038
+
2039
+
2040
+ Parameters
2041
+ ----------
2042
+ hourly : bool, default False
2043
+ Run the workflow hourly.
2044
+ daily : bool, default True
2045
+ Run the workflow daily.
2046
+ weekly : bool, default False
2047
+ Run the workflow weekly.
2048
+ cron : str, optional, default None
2049
+ Run the workflow at [a custom Cron schedule](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html#cron-expressions)
2050
+ specified by this expression.
2051
+ timezone : str, optional, default None
2052
+ Timezone on which the schedule runs (default: None). Currently supported only for Argo workflows,
2053
+ which accepts timezones in [IANA format](https://nodatime.org/TimeZones).
2054
+ """
2055
+ ...
2056
+
2057
+ @typing.overload
2058
+ def schedule(f: typing.Type[FlowSpecDerived]) -> typing.Type[FlowSpecDerived]:
2059
+ ...
2060
+
2061
+ def schedule(f: typing.Optional[typing.Type[FlowSpecDerived]] = None, *, hourly: bool = False, daily: bool = True, weekly: bool = False, cron: typing.Optional[str] = None, timezone: typing.Optional[str] = None):
2062
+ """
2063
+ Specifies the times when the flow should be run when running on a
2064
+ production scheduler.
2065
+
2066
+
2067
+ Parameters
2068
+ ----------
2069
+ hourly : bool, default False
2070
+ Run the workflow hourly.
2071
+ daily : bool, default True
2072
+ Run the workflow daily.
2073
+ weekly : bool, default False
2074
+ Run the workflow weekly.
2075
+ cron : str, optional, default None
2076
+ Run the workflow at [a custom Cron schedule](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduled-events.html#cron-expressions)
2077
+ specified by this expression.
2078
+ timezone : str, optional, default None
2079
+ Timezone on which the schedule runs (default: None). Currently supported only for Argo workflows,
2080
+ which accepts timezones in [IANA format](https://nodatime.org/TimeZones).
1957
2081
  """
1958
2082
  ...
1959
2083