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