metaflow 2.15.7__tar.gz → 2.15.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {metaflow-2.15.7/metaflow.egg-info → metaflow-2.15.9}/PKG-INFO +2 -2
- {metaflow-2.15.7 → metaflow-2.15.9}/devtools/Makefile +2 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli.py +8 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_components/run_cmds.py +2 -2
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/main_cli.py +1 -1
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metadata_provider/metadata.py +35 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metaflow_config.py +6 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metaflow_environment.py +6 -1
- metaflow-2.15.9/metaflow/metaflow_git.py +115 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metaflow_version.py +2 -2
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/__init__.py +1 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_workflows.py +43 -6
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_workflows_cli.py +11 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/aws_client.py +4 -3
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/s3/s3.py +46 -44
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/s3/s3op.py +133 -63
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kubernetes.py +4 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kubernetes_cli.py +8 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kubernetes_decorator.py +10 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kubernetes_job.py +8 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kubernetes_jobsets.py +7 -0
- metaflow-2.15.9/metaflow/plugins/uv/bootstrap.py +100 -0
- metaflow-2.15.9/metaflow/plugins/uv/uv_environment.py +70 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/deployer.py +8 -2
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/deployer_impl.py +6 -2
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/metaflow_runner.py +7 -2
- metaflow-2.15.9/metaflow/user_configs/__init__.py +0 -0
- metaflow-2.15.9/metaflow/version.py +1 -0
- {metaflow-2.15.7 → metaflow-2.15.9/metaflow.egg-info}/PKG-INFO +2 -2
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow.egg-info/SOURCES.txt +4 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow.egg-info/requires.txt +1 -1
- metaflow-2.15.7/metaflow/version.py +0 -1
- {metaflow-2.15.7 → metaflow-2.15.9}/LICENSE +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/MANIFEST.in +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/devtools/Tiltfile +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/devtools/pick_services.sh +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/R.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/_bashcomplete.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/_compat.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/_termui_impl.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/_textwrap.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/_unicodefun.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/_winconsole.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/core.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/decorators.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/exceptions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/formatting.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/globals.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/parser.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/termui.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/testing.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/types.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/click/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_adapters.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_collections.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_compat.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_functools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_itertools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_meta.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/_text.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/importlib_metadata/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/_elffile.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/_manylinux.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/_musllinux.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/_parser.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/_structures.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/_tokenizer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/markers.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/requirements.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/specifiers.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/tags.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/packaging/version.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_checkers.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_config.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_decorators.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_exceptions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_functions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_importhook.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_memo.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_pytest_plugin.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_suppression.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_transformer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_union_transformer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typeguard/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/typing_extensions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_5/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_5/zipp.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_adapters.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_collections.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_compat.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_functools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_itertools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_meta.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/_text.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/importlib_metadata/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/typing_extensions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_6/zipp.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_collections.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_compat.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_functools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_meta.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/_text.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_checkers.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_config.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_decorators.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_exceptions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_functions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_importhook.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_memo.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_suppression.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_transformer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_union_transformer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/typing_extensions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/v3_7/zipp.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/_vendor/zipp.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cards.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_args.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_components/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_components/dump_cmd.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_components/init_cmd.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_components/step_cmd.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cli_components/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/client/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/client/core.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/client/filecache.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/clone_util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/code/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/configure_cmd.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/develop/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/develop/stub_generator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/develop/stubs.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/make_wrapper.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/tutorials_cmd.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd/util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/cmd_with_io.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/content_addressed_store.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/datastore_set.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/datastore_storage.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/exceptions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/flow_datastore.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/inputs.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/datastore/task_datastore.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/debug.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/decorators.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/event_logger.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/events.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/exception.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/extension_support/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/extension_support/_empty_file.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/extension_support/cmd.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/extension_support/integrations.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/extension_support/plugins.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/flowspec.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/graph.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/includefile.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/info_file.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/integrations.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/lint.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metadata_provider/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metadata_provider/heartbeat.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metadata_provider/util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metaflow_config_funcs.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metaflow_current.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/metaflow_profile.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/mflog/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/mflog/mflog.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/mflog/save_logs.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/mflog/save_logs_periodically.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/mflog/tee.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/monitor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/multicore_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/package.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/parameters.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/airflow.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/airflow_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/airflow_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/airflow_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/dag.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/exception.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/plumbing/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/plumbing/set_parameters.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/sensors/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/sensors/base_sensor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/sensors/external_task_sensor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/airflow/sensors/s3_sensor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_events.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_workflows_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_workflows_deployer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/argo_workflows_deployer_objects.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/capture_error.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/generate_input_paths.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/argo/jobset_input_paths.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/aws_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/batch/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/batch/batch.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/batch/batch_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/batch/batch_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/batch/batch_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/secrets_manager/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/event_bridge_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/production_token.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/schedule_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/set_batch_environment.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/step_functions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/step_functions_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/step_functions_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/step_functions_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/step_functions_deployer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/azure_credential.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/azure_exceptions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/azure_tail.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/azure_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/blob_service_client_factory.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/azure/includefile_support.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_creator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_datastore.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/base.html +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/basic.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/bundle.css +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/card.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/chevron/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/chevron/main.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/chevron/metadata.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/chevron/renderer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/chevron/tokenizer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/components.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/convert_to_native_type.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/main.js +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/renderer_tools.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_modules/test_cards.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_resolver.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_server.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/card_viewer/viewer.html +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/component_serializer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/cards/exception.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/catch_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datastores/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datastores/azure_storage.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datastores/gs_storage.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datastores/local_storage.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datastores/s3_storage.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/local.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/s3/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/s3/s3tail.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/datatools/s3/s3util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/debug_logger.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/debug_monitor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/client_modules.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/communication/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/communication/bytestream.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/communication/channel.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/communication/socket_bytestream.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/communication/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/configurations/emulate_test_lib/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/configurations/emulate_test_lib/overrides.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/configurations/emulate_test_lib/server_mappings.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/configurations/test_lib_impl/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/configurations/test_lib_impl/test_lib.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/consts.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/data_transferer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/exception_transferer.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/override_decorators.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/server.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/stub.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/env_escape/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/environment_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/events_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/frameworks/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/frameworks/pytorch.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/gs_exceptions.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/gs_storage_client_factory.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/gs_tail.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/gs_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/gcp/includefile_support.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kube_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/kubernetes_client.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/spot_metadata_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/kubernetes/spot_monitor_sidecar.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/logs_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/metadata_providers/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/metadata_providers/local.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/metadata_providers/service.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/package_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/parallel_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/project_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/bootstrap.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/conda_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/conda_environment.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/micromamba.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/parsers.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/pip.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/pypi_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/pypi_environment.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/pypi/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/resources_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/retry_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/secrets/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/secrets/inline_secrets_provider.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/secrets/secrets_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/storage_executor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/tag_cli.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/test_unbounded_foreach_decorator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/plugins/timeout_decorator.py +0 -0
- {metaflow-2.15.7/metaflow/runner → metaflow-2.15.9/metaflow/plugins/uv}/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/procpoll.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/py.typed +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/pylint_wrapper.py +0 -0
- {metaflow-2.15.7/metaflow/user_configs → metaflow-2.15.9/metaflow/runner}/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/click_api.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/nbdeploy.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/nbrun.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/subprocess_manager.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runner/utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/runtime.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/sidecar/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/sidecar/sidecar.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/sidecar/sidecar_messages.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/sidecar/sidecar_subprocess.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/sidecar/sidecar_worker.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/system/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/system/system_logger.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/system/system_monitor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/system/system_utils.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tagging_util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/task.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tracing/__init__.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tracing/propagator.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tracing/span_exporter.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tracing/tracing_modules.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tuple_util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/00-helloworld/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/00-helloworld/helloworld.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/01-playlist/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/01-playlist/movies.csv +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/01-playlist/playlist.ipynb +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/01-playlist/playlist.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/02-statistics/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/02-statistics/movies.csv +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/02-statistics/stats.ipynb +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/02-statistics/stats.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/03-playlist-redux/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/03-playlist-redux/playlist.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/04-playlist-plus/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/04-playlist-plus/playlist.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/05-hello-cloud/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/05-hello-cloud/hello-cloud.ipynb +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/05-hello-cloud/hello-cloud.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/06-statistics-redux/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/06-statistics-redux/stats.ipynb +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/07-worldview/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/07-worldview/worldview.ipynb +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/08-autopilot/README.md +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/tutorials/08-autopilot/autopilot.ipynb +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/unbounded_foreach.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/user_configs/config_decorators.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/user_configs/config_options.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/user_configs/config_parameters.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/util.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow/vendor.py +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow.egg-info/dependency_links.txt +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow.egg-info/entry_points.txt +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/metaflow.egg-info/top_level.txt +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/setup.cfg +0 -0
- {metaflow-2.15.7 → metaflow-2.15.9}/setup.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: metaflow
|
3
|
-
Version: 2.15.
|
3
|
+
Version: 2.15.9
|
4
4
|
Summary: Metaflow: More AI and ML, Less Engineering
|
5
5
|
Author: Metaflow Developers
|
6
6
|
Author-email: help@metaflow.org
|
@@ -26,7 +26,7 @@ License-File: LICENSE
|
|
26
26
|
Requires-Dist: requests
|
27
27
|
Requires-Dist: boto3
|
28
28
|
Provides-Extra: stubs
|
29
|
-
Requires-Dist: metaflow-stubs==2.15.
|
29
|
+
Requires-Dist: metaflow-stubs==2.15.9; extra == "stubs"
|
30
30
|
Dynamic: author
|
31
31
|
Dynamic: author-email
|
32
32
|
Dynamic: classifier
|
@@ -260,6 +260,7 @@ shell: setup-tilt
|
|
260
260
|
env METAFLOW_HOME="$(DEVTOOLS_DIR)" \
|
261
261
|
METAFLOW_PROFILE=local \
|
262
262
|
AWS_CONFIG_FILE="$(DEVTOOLS_DIR)/aws_config" \
|
263
|
+
AWS_SHARED_CREDENTIALS_FILE= \
|
263
264
|
"$$user_shell" -i; \
|
264
265
|
else \
|
265
266
|
env METAFLOW_HOME="$(DEVTOOLS_DIR)" \
|
@@ -301,6 +302,7 @@ create-dev-shell: setup-tilt
|
|
301
302
|
echo " env METAFLOW_HOME=\"$(DEVTOOLS_DIR)\" \\" >> $$SHELL_PATH && \
|
302
303
|
echo " METAFLOW_PROFILE=local \\" >> $$SHELL_PATH && \
|
303
304
|
echo " AWS_CONFIG_FILE=\"$(DEVTOOLS_DIR)/aws_config\" \\" >> $$SHELL_PATH && \
|
305
|
+
echo " AWS_SHARED_CREDENTIALS_FILE= \\" >> $$SHELL_PATH && \
|
304
306
|
echo " \"\$$user_shell\" -i" >> $$SHELL_PATH && \
|
305
307
|
echo "else" >> $$SHELL_PATH && \
|
306
308
|
echo " env METAFLOW_HOME=\"$(DEVTOOLS_DIR)\" \\" >> $$SHELL_PATH && \
|
@@ -17,6 +17,7 @@ from .flowspec import _FlowState
|
|
17
17
|
from .graph import FlowGraph
|
18
18
|
from .metaflow_config import (
|
19
19
|
DEFAULT_DATASTORE,
|
20
|
+
DEFAULT_DECOSPECS,
|
20
21
|
DEFAULT_ENVIRONMENT,
|
21
22
|
DEFAULT_EVENT_LOGGER,
|
22
23
|
DEFAULT_METADATA,
|
@@ -509,9 +510,16 @@ def start(
|
|
509
510
|
):
|
510
511
|
# run/resume are special cases because they can add more decorators with --with,
|
511
512
|
# so they have to take care of themselves.
|
513
|
+
|
512
514
|
all_decospecs = ctx.obj.tl_decospecs + list(
|
513
515
|
ctx.obj.environment.decospecs() or []
|
514
516
|
)
|
517
|
+
|
518
|
+
# We add the default decospecs for everything except init and step since in those
|
519
|
+
# cases, the decospecs will already have been handled by either a run/resume
|
520
|
+
# or a scheduler setting them up in their own way.
|
521
|
+
if ctx.saved_args[0] not in ("step", "init"):
|
522
|
+
all_decospecs += DEFAULT_DECOSPECS.split()
|
515
523
|
if all_decospecs:
|
516
524
|
decorators._attach_decorators(ctx.obj.flow, all_decospecs)
|
517
525
|
decorators._init(ctx.obj.flow)
|
@@ -71,7 +71,7 @@ def write_file(file_path, content):
|
|
71
71
|
f.write(str(content))
|
72
72
|
|
73
73
|
|
74
|
-
def
|
74
|
+
def config_callback(ctx, param, value):
|
75
75
|
# Callback to:
|
76
76
|
# - read the Click auto_envvar variable from both the
|
77
77
|
# environment AND the configuration
|
@@ -127,7 +127,7 @@ def common_run_options(func):
|
|
127
127
|
help="Add a decorator to all steps. You can specify this "
|
128
128
|
"option multiple times to attach multiple decorators "
|
129
129
|
"in steps.",
|
130
|
-
callback=
|
130
|
+
callback=config_callback,
|
131
131
|
)
|
132
132
|
@click.option(
|
133
133
|
"--run-id-file",
|
@@ -94,7 +94,7 @@ def start(ctx):
|
|
94
94
|
echo("(%s)\n" % version, fg="magenta", bold=False)
|
95
95
|
|
96
96
|
if ctx.invoked_subcommand is None:
|
97
|
-
echo("More
|
97
|
+
echo("More AI, less engineering\n", fg="magenta")
|
98
98
|
|
99
99
|
lnk_sz = max(len(lnk) for lnk in CONTACT_INFO.values()) + 1
|
100
100
|
for what, lnk in CONTACT_INFO.items():
|
@@ -630,6 +630,20 @@ class MetadataProvider(object):
|
|
630
630
|
sys_info["r_version"] = env["r_version_code"]
|
631
631
|
return sys_info
|
632
632
|
|
633
|
+
def _get_git_info_as_dict(self):
|
634
|
+
git_info = {}
|
635
|
+
env = self._environment.get_environment_info()
|
636
|
+
for key in [
|
637
|
+
"repo_url",
|
638
|
+
"branch_name",
|
639
|
+
"commit_sha",
|
640
|
+
"has_uncommitted_changes",
|
641
|
+
]:
|
642
|
+
if key in env and env[key]:
|
643
|
+
git_info[key] = env[key]
|
644
|
+
|
645
|
+
return git_info
|
646
|
+
|
633
647
|
def _get_system_tags(self):
|
634
648
|
"""Convert system info dictionary into a list of system tags"""
|
635
649
|
return [
|
@@ -670,6 +684,27 @@ class MetadataProvider(object):
|
|
670
684
|
tags=["attempt_id:{0}".format(attempt)],
|
671
685
|
)
|
672
686
|
)
|
687
|
+
# Add script name as metadata
|
688
|
+
script_name = self._environment.get_environment_info()["script"]
|
689
|
+
metadata.append(
|
690
|
+
MetaDatum(
|
691
|
+
field="script-name",
|
692
|
+
value=script_name,
|
693
|
+
type="script-name",
|
694
|
+
tags=["attempt_id:{0}".format(attempt)],
|
695
|
+
)
|
696
|
+
)
|
697
|
+
# And add git metadata
|
698
|
+
git_info = self._get_git_info_as_dict()
|
699
|
+
if git_info:
|
700
|
+
metadata.append(
|
701
|
+
MetaDatum(
|
702
|
+
field="git-info",
|
703
|
+
value=json.dumps(git_info),
|
704
|
+
type="git-info",
|
705
|
+
tags=["attempt_id:{0}".format(attempt)],
|
706
|
+
)
|
707
|
+
)
|
673
708
|
if metadata:
|
674
709
|
self.register_metadata(run_id, step_name, task_id, metadata)
|
675
710
|
|
@@ -109,6 +109,12 @@ S3_WORKER_COUNT = from_conf("S3_WORKER_COUNT", 64)
|
|
109
109
|
# top-level retries)
|
110
110
|
S3_TRANSIENT_RETRY_COUNT = from_conf("S3_TRANSIENT_RETRY_COUNT", 20)
|
111
111
|
|
112
|
+
# S3 retry configuration used in the aws client
|
113
|
+
# Use the adaptive retry strategy by default
|
114
|
+
S3_CLIENT_RETRY_CONFIG = from_conf(
|
115
|
+
"S3_CLIENT_RETRY_CONFIG", {"max_attempts": 10, "mode": "adaptive"}
|
116
|
+
)
|
117
|
+
|
112
118
|
# Threshold to start printing warnings for an AWS retry
|
113
119
|
RETRY_WARNING_THRESHOLD = 3
|
114
120
|
|
@@ -4,6 +4,7 @@ import sys
|
|
4
4
|
|
5
5
|
from .util import get_username
|
6
6
|
from . import metaflow_version
|
7
|
+
from . import metaflow_git
|
7
8
|
from metaflow.exception import MetaflowException
|
8
9
|
from metaflow.extension_support import dump_module_info
|
9
10
|
from metaflow.mflog import BASH_MFLOG, BASH_FLUSH_LOGS
|
@@ -197,6 +198,10 @@ class MetaflowEnvironment(object):
|
|
197
198
|
"python_version_code": "%d.%d.%d" % sys.version_info[:3],
|
198
199
|
"metaflow_version": metaflow_version.get_version(),
|
199
200
|
"script": os.path.basename(os.path.abspath(sys.argv[0])),
|
201
|
+
# Add git info
|
202
|
+
**metaflow_git.get_repository_info(
|
203
|
+
path=os.path.dirname(os.path.abspath(sys.argv[0]))
|
204
|
+
),
|
200
205
|
}
|
201
206
|
if R.use_r():
|
202
207
|
env["metaflow_r_version"] = R.metaflow_r_version()
|
@@ -206,7 +211,7 @@ class MetaflowEnvironment(object):
|
|
206
211
|
# Information about extension modules (to load them in the proper order)
|
207
212
|
ext_key, ext_val = dump_module_info()
|
208
213
|
env[ext_key] = ext_val
|
209
|
-
return env
|
214
|
+
return {k: v for k, v in env.items() if v is not None and v != ""}
|
210
215
|
|
211
216
|
def executable(self, step_name, default=None):
|
212
217
|
if default is not None:
|
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env python
|
2
|
+
"""Get git repository information for the package
|
3
|
+
|
4
|
+
Functions to retrieve git repository details like URL, branch name,
|
5
|
+
and commit SHA for Metaflow code provenance tracking.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import os
|
9
|
+
import subprocess
|
10
|
+
from typing import Dict, List, Optional, Tuple, Union
|
11
|
+
|
12
|
+
# Cache for git information to avoid repeated subprocess calls
|
13
|
+
_git_info_cache = None
|
14
|
+
|
15
|
+
__all__ = ("get_repository_info",)
|
16
|
+
|
17
|
+
|
18
|
+
def _call_git(
|
19
|
+
args: List[str], path=Union[str, os.PathLike]
|
20
|
+
) -> Tuple[Optional[str], Optional[int], bool]:
|
21
|
+
"""
|
22
|
+
Call git with provided args.
|
23
|
+
|
24
|
+
Returns
|
25
|
+
-------
|
26
|
+
tuple : Tuple containing
|
27
|
+
(stdout, exitcode, failure) of the call
|
28
|
+
"""
|
29
|
+
try:
|
30
|
+
result = subprocess.run(
|
31
|
+
["git", *args],
|
32
|
+
cwd=path,
|
33
|
+
capture_output=True,
|
34
|
+
text=True,
|
35
|
+
check=False,
|
36
|
+
)
|
37
|
+
return result.stdout.strip(), result.returncode, False
|
38
|
+
except (OSError, subprocess.SubprocessError):
|
39
|
+
# Covers subprocess timeouts and other errors which would not lead to an exit code
|
40
|
+
return None, None, True
|
41
|
+
|
42
|
+
|
43
|
+
def _get_repo_url(path: Union[str, os.PathLike]) -> Optional[str]:
|
44
|
+
"""Get the repository URL from git config"""
|
45
|
+
stdout, returncode, _failed = _call_git(
|
46
|
+
["config", "--get", "remote.origin.url"], path
|
47
|
+
)
|
48
|
+
if returncode == 0:
|
49
|
+
url = stdout
|
50
|
+
# Convert SSH URLs to HTTPS for clickable links
|
51
|
+
if url.startswith("git@"):
|
52
|
+
parts = url.split(":", 1)
|
53
|
+
if len(parts) == 2:
|
54
|
+
domain = parts[0].replace("git@", "")
|
55
|
+
repo_path = parts[1]
|
56
|
+
url = f"https://{domain}/{repo_path}"
|
57
|
+
return url
|
58
|
+
return None
|
59
|
+
|
60
|
+
|
61
|
+
def _get_branch_name(path: Union[str, os.PathLike]) -> Optional[str]:
|
62
|
+
"""Get the current git branch name"""
|
63
|
+
stdout, returncode, _failed = _call_git(["rev-parse", "--abbrev-ref", "HEAD"], path)
|
64
|
+
return stdout if returncode == 0 else None
|
65
|
+
|
66
|
+
|
67
|
+
def _get_commit_sha(path: Union[str, os.PathLike]) -> Optional[str]:
|
68
|
+
"""Get the current git commit SHA"""
|
69
|
+
stdout, returncode, _failed = _call_git(["rev-parse", "HEAD"], path)
|
70
|
+
return stdout if returncode == 0 else None
|
71
|
+
|
72
|
+
|
73
|
+
def _is_in_git_repo(path: Union[str, os.PathLike]) -> bool:
|
74
|
+
"""Check if we're currently in a git repository"""
|
75
|
+
stdout, returncode, _failed = _call_git(
|
76
|
+
["rev-parse", "--is-inside-work-tree"], path
|
77
|
+
)
|
78
|
+
return returncode == 0 and stdout == "true"
|
79
|
+
|
80
|
+
|
81
|
+
def _has_uncommitted_changes(path: Union[str, os.PathLike]) -> Optional[bool]:
|
82
|
+
"""Check if the git repository has uncommitted changes"""
|
83
|
+
_stdout, returncode, failed = _call_git(
|
84
|
+
["diff-index", "--quiet", "HEAD", "--"], path
|
85
|
+
)
|
86
|
+
if failed:
|
87
|
+
return None
|
88
|
+
return returncode != 0
|
89
|
+
|
90
|
+
|
91
|
+
def get_repository_info(path: Union[str, os.PathLike]) -> Dict[str, Union[str, bool]]:
|
92
|
+
"""Get git repository information for a path
|
93
|
+
|
94
|
+
Returns:
|
95
|
+
dict: Dictionary containing:
|
96
|
+
repo_url: Repository URL (converted to HTTPS if from SSH)
|
97
|
+
branch_name: Current branch name
|
98
|
+
commit_sha: Current commit SHA
|
99
|
+
has_uncommitted_changes: Boolean indicating if there are uncommitted changes
|
100
|
+
"""
|
101
|
+
global _git_info_cache
|
102
|
+
|
103
|
+
if _git_info_cache is not None:
|
104
|
+
return _git_info_cache
|
105
|
+
|
106
|
+
_git_info_cache = {}
|
107
|
+
if _is_in_git_repo(path):
|
108
|
+
_git_info_cache = {
|
109
|
+
"repo_url": _get_repo_url(path),
|
110
|
+
"branch_name": _get_branch_name(path),
|
111
|
+
"commit_sha": _get_commit_sha(path),
|
112
|
+
"has_uncommitted_changes": _has_uncommitted_changes(path),
|
113
|
+
}
|
114
|
+
|
115
|
+
return _git_info_cache
|
@@ -27,11 +27,11 @@ if name == "nt":
|
|
27
27
|
"""find the path to the git executable on Windows"""
|
28
28
|
# first see if git is in the path
|
29
29
|
try:
|
30
|
-
check_output(["where", "/Q", "git"])
|
30
|
+
subprocess.check_output(["where", "/Q", "git"])
|
31
31
|
# if this command succeeded, git is in the path
|
32
32
|
return "git"
|
33
33
|
# catch the exception thrown if git was not found
|
34
|
-
except CalledProcessError:
|
34
|
+
except subprocess.CalledProcessError:
|
35
35
|
pass
|
36
36
|
# There are several locations where git.exe may be hiding
|
37
37
|
possible_locations = []
|
@@ -7,6 +7,7 @@ import sys
|
|
7
7
|
from collections import defaultdict
|
8
8
|
from hashlib import sha1
|
9
9
|
from math import inf
|
10
|
+
from typing import List
|
10
11
|
|
11
12
|
from metaflow import JSONType, current
|
12
13
|
from metaflow.decorators import flow_decorators
|
@@ -110,6 +111,7 @@ class ArgoWorkflows(object):
|
|
110
111
|
notify_pager_duty_integration_key=None,
|
111
112
|
notify_incident_io_api_key=None,
|
112
113
|
incident_io_alert_source_config_id=None,
|
114
|
+
incident_io_metadata: List[str] = None,
|
113
115
|
enable_heartbeat_daemon=True,
|
114
116
|
enable_error_msg_capture=False,
|
115
117
|
):
|
@@ -161,6 +163,9 @@ class ArgoWorkflows(object):
|
|
161
163
|
self.notify_pager_duty_integration_key = notify_pager_duty_integration_key
|
162
164
|
self.notify_incident_io_api_key = notify_incident_io_api_key
|
163
165
|
self.incident_io_alert_source_config_id = incident_io_alert_source_config_id
|
166
|
+
self.incident_io_metadata = self.parse_incident_io_metadata(
|
167
|
+
incident_io_metadata
|
168
|
+
)
|
164
169
|
self.enable_heartbeat_daemon = enable_heartbeat_daemon
|
165
170
|
self.enable_error_msg_capture = enable_error_msg_capture
|
166
171
|
self.parameters = self._process_parameters()
|
@@ -287,6 +292,21 @@ class ArgoWorkflows(object):
|
|
287
292
|
|
288
293
|
return True
|
289
294
|
|
295
|
+
@staticmethod
|
296
|
+
def parse_incident_io_metadata(metadata: List[str] = None):
|
297
|
+
"parse key value pairs into a dict for incident.io metadata if given"
|
298
|
+
parsed_metadata = None
|
299
|
+
if metadata is not None:
|
300
|
+
parsed_metadata = {}
|
301
|
+
for kv in metadata:
|
302
|
+
key, value = kv.split("=", 1)
|
303
|
+
if key in parsed_metadata:
|
304
|
+
raise MetaflowException(
|
305
|
+
"Incident.io Metadata *%s* provided multiple times" % key
|
306
|
+
)
|
307
|
+
parsed_metadata[key] = value
|
308
|
+
return parsed_metadata
|
309
|
+
|
290
310
|
@classmethod
|
291
311
|
def trigger(cls, name, parameters=None):
|
292
312
|
if parameters is None:
|
@@ -1958,6 +1978,15 @@ class ArgoWorkflows(object):
|
|
1958
1978
|
resources["disk"],
|
1959
1979
|
)
|
1960
1980
|
|
1981
|
+
security_context = resources.get("security_context", None)
|
1982
|
+
_security_context = {}
|
1983
|
+
if security_context is not None and len(security_context) > 0:
|
1984
|
+
_security_context = {
|
1985
|
+
"security_context": kubernetes_sdk.V1SecurityContext(
|
1986
|
+
**security_context
|
1987
|
+
)
|
1988
|
+
}
|
1989
|
+
|
1961
1990
|
# Create a ContainerTemplate for this node. Ideally, we would have
|
1962
1991
|
# liked to inline this ContainerTemplate and avoid scanning the workflow
|
1963
1992
|
# twice, but due to issues with variable substitution, we will have to
|
@@ -2014,6 +2043,7 @@ class ArgoWorkflows(object):
|
|
2014
2043
|
shared_memory=shared_memory,
|
2015
2044
|
port=port,
|
2016
2045
|
qos=resources["qos"],
|
2046
|
+
security_context=security_context,
|
2017
2047
|
)
|
2018
2048
|
|
2019
2049
|
for k, v in env.items():
|
@@ -2290,6 +2320,7 @@ class ArgoWorkflows(object):
|
|
2290
2320
|
is not None
|
2291
2321
|
else []
|
2292
2322
|
),
|
2323
|
+
**_security_context,
|
2293
2324
|
).to_dict()
|
2294
2325
|
)
|
2295
2326
|
)
|
@@ -2552,9 +2583,12 @@ class ArgoWorkflows(object):
|
|
2552
2583
|
else None
|
2553
2584
|
),
|
2554
2585
|
"metadata": {
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2586
|
+
**(self.incident_io_metadata or {}),
|
2587
|
+
**{
|
2588
|
+
"run_status": "failed",
|
2589
|
+
"flow_name": self.flow.name,
|
2590
|
+
"run_id": "argo-{{workflow.name}}",
|
2591
|
+
},
|
2558
2592
|
},
|
2559
2593
|
}
|
2560
2594
|
)
|
@@ -2603,9 +2637,12 @@ class ArgoWorkflows(object):
|
|
2603
2637
|
else None
|
2604
2638
|
),
|
2605
2639
|
"metadata": {
|
2606
|
-
|
2607
|
-
|
2608
|
-
|
2640
|
+
**(self.incident_io_metadata or {}),
|
2641
|
+
**{
|
2642
|
+
"run_status": "succeeded",
|
2643
|
+
"flow_name": self.flow.name,
|
2644
|
+
"run_id": "argo-{{workflow.name}}",
|
2645
|
+
},
|
2609
2646
|
},
|
2610
2647
|
}
|
2611
2648
|
)
|
@@ -187,6 +187,13 @@ def argo_workflows(obj, name=None):
|
|
187
187
|
default=None,
|
188
188
|
help="Incident.io Alert source config ID. Example '01GW2G3V0S59R238FAHPDS1R66'",
|
189
189
|
)
|
190
|
+
@click.option(
|
191
|
+
"--incident-io-metadata",
|
192
|
+
default=None,
|
193
|
+
type=str,
|
194
|
+
multiple=True,
|
195
|
+
help="Incident.io Alert Custom Metadata field in the form of Key=Value",
|
196
|
+
)
|
190
197
|
@click.option(
|
191
198
|
"--enable-heartbeat-daemon/--no-enable-heartbeat-daemon",
|
192
199
|
default=False,
|
@@ -226,6 +233,7 @@ def create(
|
|
226
233
|
notify_pager_duty_integration_key=None,
|
227
234
|
notify_incident_io_api_key=None,
|
228
235
|
incident_io_alert_source_config_id=None,
|
236
|
+
incident_io_metadata=None,
|
229
237
|
enable_heartbeat_daemon=True,
|
230
238
|
deployer_attribute_file=None,
|
231
239
|
enable_error_msg_capture=False,
|
@@ -283,6 +291,7 @@ def create(
|
|
283
291
|
notify_pager_duty_integration_key,
|
284
292
|
notify_incident_io_api_key,
|
285
293
|
incident_io_alert_source_config_id,
|
294
|
+
incident_io_metadata,
|
286
295
|
enable_heartbeat_daemon,
|
287
296
|
enable_error_msg_capture,
|
288
297
|
)
|
@@ -459,6 +468,7 @@ def make_flow(
|
|
459
468
|
notify_pager_duty_integration_key,
|
460
469
|
notify_incident_io_api_key,
|
461
470
|
incident_io_alert_source_config_id,
|
471
|
+
incident_io_metadata,
|
462
472
|
enable_heartbeat_daemon,
|
463
473
|
enable_error_msg_capture,
|
464
474
|
):
|
@@ -538,6 +548,7 @@ def make_flow(
|
|
538
548
|
notify_pager_duty_integration_key=notify_pager_duty_integration_key,
|
539
549
|
notify_incident_io_api_key=notify_incident_io_api_key,
|
540
550
|
incident_io_alert_source_config_id=incident_io_alert_source_config_id,
|
551
|
+
incident_io_metadata=incident_io_metadata,
|
541
552
|
enable_heartbeat_daemon=enable_heartbeat_daemon,
|
542
553
|
enable_error_msg_capture=enable_error_msg_capture,
|
543
554
|
)
|
@@ -14,6 +14,7 @@ class Boto3ClientProvider(object):
|
|
14
14
|
AWS_SANDBOX_ENABLED,
|
15
15
|
AWS_SANDBOX_STS_ENDPOINT_URL,
|
16
16
|
AWS_SANDBOX_API_KEY,
|
17
|
+
S3_CLIENT_RETRY_CONFIG,
|
17
18
|
)
|
18
19
|
|
19
20
|
if session_vars is None:
|
@@ -37,10 +38,10 @@ class Boto3ClientProvider(object):
|
|
37
38
|
if module == "s3" and (
|
38
39
|
"config" not in client_params or client_params["config"].retries is None
|
39
40
|
):
|
40
|
-
#
|
41
|
-
# the user has already set something
|
41
|
+
# do not set anything if the user has already set something
|
42
42
|
config = client_params.get("config", Config())
|
43
|
-
config.retries =
|
43
|
+
config.retries = S3_CLIENT_RETRY_CONFIG
|
44
|
+
client_params["config"] = config
|
44
45
|
|
45
46
|
if AWS_SANDBOX_ENABLED:
|
46
47
|
# role is ignored in the sandbox
|
@@ -18,6 +18,7 @@ from metaflow.metaflow_config import (
|
|
18
18
|
S3_RETRY_COUNT,
|
19
19
|
S3_TRANSIENT_RETRY_COUNT,
|
20
20
|
S3_SERVER_SIDE_ENCRYPTION,
|
21
|
+
S3_WORKER_COUNT,
|
21
22
|
TEMPDIR,
|
22
23
|
)
|
23
24
|
from metaflow.util import (
|
@@ -1390,9 +1391,31 @@ class S3(object):
|
|
1390
1391
|
)
|
1391
1392
|
|
1392
1393
|
# add some jitter to make sure retries are not synchronized
|
1393
|
-
def _jitter_sleep(
|
1394
|
-
|
1395
|
-
|
1394
|
+
def _jitter_sleep(
|
1395
|
+
self, trynum: int, base: int = 2, cap: int = 360, jitter: float = 0.1
|
1396
|
+
) -> None:
|
1397
|
+
"""
|
1398
|
+
Sleep for an exponentially increasing interval with added jitter.
|
1399
|
+
|
1400
|
+
Parameters
|
1401
|
+
----------
|
1402
|
+
trynum: The current retry attempt number.
|
1403
|
+
base: The base multiplier for the exponential backoff.
|
1404
|
+
cap: The maximum interval to sleep.
|
1405
|
+
jitter: The maximum jitter percentage to add to the interval.
|
1406
|
+
"""
|
1407
|
+
# Calculate the exponential backoff interval
|
1408
|
+
interval = min(cap, base**trynum)
|
1409
|
+
|
1410
|
+
# Add random jitter
|
1411
|
+
jitter_value = interval * jitter * random.uniform(-1, 1)
|
1412
|
+
interval_with_jitter = interval + jitter_value
|
1413
|
+
|
1414
|
+
# Ensure the interval is not negative
|
1415
|
+
interval_with_jitter = max(0, interval_with_jitter)
|
1416
|
+
|
1417
|
+
# Sleep for the calculated interval
|
1418
|
+
time.sleep(interval_with_jitter)
|
1396
1419
|
|
1397
1420
|
# NOTE: re: _read_many_files and _put_many_files
|
1398
1421
|
# All file IO is through binary files - we write bytes, we read
|
@@ -1480,20 +1503,17 @@ class S3(object):
|
|
1480
1503
|
# - a known transient failure (SlowDown for example) in which case we will
|
1481
1504
|
# retry *only* the inputs that have this transient failure.
|
1482
1505
|
# - an unknown failure (something went wrong but we cannot say if it was
|
1483
|
-
# a known permanent failure or something else). In this case, we
|
1484
|
-
#
|
1485
|
-
#
|
1486
|
-
# There are therefore two retry counts:
|
1487
|
-
# - the transient failure retry count: how many times do we try on known
|
1488
|
-
# transient errors
|
1489
|
-
# - the top-level retry count: how many times do we try on unknown failures
|
1506
|
+
# a known permanent failure or something else). In this case, we assume
|
1507
|
+
# it's a transient failure and retry only those inputs (same as above).
|
1490
1508
|
#
|
1491
|
-
#
|
1492
|
-
#
|
1493
|
-
#
|
1494
|
-
#
|
1495
|
-
#
|
1496
|
-
#
|
1509
|
+
# NOTES(npow): 2025-05-13
|
1510
|
+
# Previously, this code would also retry the fatal failures, including no_progress
|
1511
|
+
# and unknown failures, from the beginning. This is not ideal because:
|
1512
|
+
# 1. Fatal errors are not supposed to be retried.
|
1513
|
+
# 2. Retrying from the beginning does not improve the situation, and is
|
1514
|
+
# wasteful since we have already uploaded some files.
|
1515
|
+
# 3. The number of transient errors is far more than fatal errors, so we
|
1516
|
+
# can be optimistic and assume the unknown errors are transient.
|
1497
1517
|
cmdline = [sys.executable, os.path.abspath(s3op.__file__), mode]
|
1498
1518
|
recursive_get = False
|
1499
1519
|
for key, value in options.items():
|
@@ -1528,7 +1548,6 @@ class S3(object):
|
|
1528
1548
|
# Otherwise, we cap the failure rate at 90%
|
1529
1549
|
return min(90, self._s3_inject_failures)
|
1530
1550
|
|
1531
|
-
retry_count = 0 # Number of retries (excluding transient failures)
|
1532
1551
|
transient_retry_count = 0 # Number of transient retries (per top-level retry)
|
1533
1552
|
inject_failures = _inject_failure_rate()
|
1534
1553
|
out_lines = [] # List to contain the lines returned by _s3op_with_retries
|
@@ -1595,7 +1614,12 @@ class S3(object):
|
|
1595
1614
|
# things, this will shrink more and more until we are doing a
|
1596
1615
|
# single operation at a time. If things start going better, it
|
1597
1616
|
# will increase by 20% every round.
|
1598
|
-
|
1617
|
+
#
|
1618
|
+
# If we made no progress (last_ok_count == 0) we retry at most
|
1619
|
+
# 2*S3_WORKER_COUNT from whatever is left in `pending_retries`
|
1620
|
+
max_count = min(
|
1621
|
+
int(last_ok_count * 1.2), len(pending_retries)
|
1622
|
+
) or min(2 * S3_WORKER_COUNT, len(pending_retries))
|
1599
1623
|
tmp_input.writelines(pending_retries[:max_count])
|
1600
1624
|
tmp_input.flush()
|
1601
1625
|
debug.s3client_exec(
|
@@ -1712,38 +1736,16 @@ class S3(object):
|
|
1712
1736
|
_update_out_lines(out_lines, ok_lines, resize=loop_count == 0)
|
1713
1737
|
return 0, 0, inject_failures, err_out
|
1714
1738
|
|
1715
|
-
while
|
1739
|
+
while transient_retry_count <= S3_TRANSIENT_RETRY_COUNT:
|
1716
1740
|
(
|
1717
1741
|
last_ok_count,
|
1718
1742
|
last_retry_count,
|
1719
1743
|
inject_failures,
|
1720
1744
|
err_out,
|
1721
1745
|
) = try_s3_op(last_ok_count, pending_retries, out_lines, inject_failures)
|
1722
|
-
if err_out
|
1723
|
-
|
1724
|
-
|
1725
|
-
last_ok_count == 0
|
1726
|
-
or transient_retry_count > S3_TRANSIENT_RETRY_COUNT
|
1727
|
-
)
|
1728
|
-
):
|
1729
|
-
# We had a fatal failure (err_out is not None)
|
1730
|
-
# or we made no progress (last_ok_count is 0)
|
1731
|
-
# or we are out of transient retries
|
1732
|
-
# so we will restart from scratch (being very conservative)
|
1733
|
-
retry_count += 1
|
1734
|
-
err_msg = err_out
|
1735
|
-
if err_msg is None and last_ok_count == 0:
|
1736
|
-
err_msg = "No progress"
|
1737
|
-
if err_msg is None:
|
1738
|
-
err_msg = "Too many transient errors"
|
1739
|
-
print(
|
1740
|
-
"S3 non-transient error (attempt #%d): %s" % (retry_count, err_msg)
|
1741
|
-
)
|
1742
|
-
_reset()
|
1743
|
-
if retry_count <= S3_RETRY_COUNT:
|
1744
|
-
self._jitter_sleep(retry_count)
|
1745
|
-
continue
|
1746
|
-
elif last_retry_count != 0:
|
1746
|
+
if err_out:
|
1747
|
+
break
|
1748
|
+
if last_retry_count != 0:
|
1747
1749
|
# During our last try, we did not manage to process everything we wanted
|
1748
1750
|
# due to a transient failure so we try again.
|
1749
1751
|
transient_retry_count += 1
|