ob-metaflow 2.11.13.1__py2.py3-none-any.whl → 2.19.7.1rc0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- metaflow/R.py +10 -7
- metaflow/__init__.py +40 -25
- metaflow/_vendor/imghdr/__init__.py +186 -0
- metaflow/_vendor/importlib_metadata/__init__.py +1063 -0
- metaflow/_vendor/importlib_metadata/_adapters.py +68 -0
- metaflow/_vendor/importlib_metadata/_collections.py +30 -0
- metaflow/_vendor/importlib_metadata/_compat.py +71 -0
- metaflow/_vendor/importlib_metadata/_functools.py +104 -0
- metaflow/_vendor/importlib_metadata/_itertools.py +73 -0
- metaflow/_vendor/importlib_metadata/_meta.py +48 -0
- metaflow/_vendor/importlib_metadata/_text.py +99 -0
- metaflow/_vendor/importlib_metadata/py.typed +0 -0
- metaflow/_vendor/typeguard/__init__.py +48 -0
- metaflow/_vendor/typeguard/_checkers.py +1070 -0
- metaflow/_vendor/typeguard/_config.py +108 -0
- metaflow/_vendor/typeguard/_decorators.py +233 -0
- metaflow/_vendor/typeguard/_exceptions.py +42 -0
- metaflow/_vendor/typeguard/_functions.py +308 -0
- metaflow/_vendor/typeguard/_importhook.py +213 -0
- metaflow/_vendor/typeguard/_memo.py +48 -0
- metaflow/_vendor/typeguard/_pytest_plugin.py +127 -0
- metaflow/_vendor/typeguard/_suppression.py +86 -0
- metaflow/_vendor/typeguard/_transformer.py +1229 -0
- metaflow/_vendor/typeguard/_union_transformer.py +55 -0
- metaflow/_vendor/typeguard/_utils.py +173 -0
- metaflow/_vendor/typeguard/py.typed +0 -0
- metaflow/_vendor/typing_extensions.py +3641 -0
- metaflow/_vendor/v3_7/importlib_metadata/__init__.py +1063 -0
- metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +68 -0
- metaflow/_vendor/v3_7/importlib_metadata/_collections.py +30 -0
- metaflow/_vendor/v3_7/importlib_metadata/_compat.py +71 -0
- metaflow/_vendor/v3_7/importlib_metadata/_functools.py +104 -0
- metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +73 -0
- metaflow/_vendor/v3_7/importlib_metadata/_meta.py +48 -0
- metaflow/_vendor/v3_7/importlib_metadata/_text.py +99 -0
- metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
- metaflow/_vendor/v3_7/typeguard/__init__.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_checkers.py +906 -0
- metaflow/_vendor/v3_7/typeguard/_config.py +108 -0
- metaflow/_vendor/v3_7/typeguard/_decorators.py +237 -0
- metaflow/_vendor/v3_7/typeguard/_exceptions.py +42 -0
- metaflow/_vendor/v3_7/typeguard/_functions.py +310 -0
- metaflow/_vendor/v3_7/typeguard/_importhook.py +213 -0
- metaflow/_vendor/v3_7/typeguard/_memo.py +48 -0
- metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +100 -0
- metaflow/_vendor/v3_7/typeguard/_suppression.py +88 -0
- metaflow/_vendor/v3_7/typeguard/_transformer.py +1207 -0
- metaflow/_vendor/v3_7/typeguard/_union_transformer.py +54 -0
- metaflow/_vendor/v3_7/typeguard/_utils.py +169 -0
- metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
- metaflow/_vendor/v3_7/typing_extensions.py +3072 -0
- metaflow/_vendor/yaml/__init__.py +427 -0
- metaflow/_vendor/yaml/composer.py +139 -0
- metaflow/_vendor/yaml/constructor.py +748 -0
- metaflow/_vendor/yaml/cyaml.py +101 -0
- metaflow/_vendor/yaml/dumper.py +62 -0
- metaflow/_vendor/yaml/emitter.py +1137 -0
- metaflow/_vendor/yaml/error.py +75 -0
- metaflow/_vendor/yaml/events.py +86 -0
- metaflow/_vendor/yaml/loader.py +63 -0
- metaflow/_vendor/yaml/nodes.py +49 -0
- metaflow/_vendor/yaml/parser.py +589 -0
- metaflow/_vendor/yaml/reader.py +185 -0
- metaflow/_vendor/yaml/representer.py +389 -0
- metaflow/_vendor/yaml/resolver.py +227 -0
- metaflow/_vendor/yaml/scanner.py +1435 -0
- metaflow/_vendor/yaml/serializer.py +111 -0
- metaflow/_vendor/yaml/tokens.py +104 -0
- metaflow/cards.py +5 -0
- metaflow/cli.py +331 -785
- metaflow/cli_args.py +17 -0
- metaflow/cli_components/__init__.py +0 -0
- metaflow/cli_components/dump_cmd.py +96 -0
- metaflow/cli_components/init_cmd.py +52 -0
- metaflow/cli_components/run_cmds.py +546 -0
- metaflow/cli_components/step_cmd.py +334 -0
- metaflow/cli_components/utils.py +140 -0
- metaflow/client/__init__.py +1 -0
- metaflow/client/core.py +467 -73
- metaflow/client/filecache.py +75 -35
- metaflow/clone_util.py +7 -1
- metaflow/cmd/code/__init__.py +231 -0
- metaflow/cmd/develop/stub_generator.py +756 -288
- metaflow/cmd/develop/stubs.py +12 -28
- metaflow/cmd/main_cli.py +6 -4
- metaflow/cmd/make_wrapper.py +78 -0
- metaflow/datastore/__init__.py +1 -0
- metaflow/datastore/content_addressed_store.py +41 -10
- metaflow/datastore/datastore_set.py +11 -2
- metaflow/datastore/flow_datastore.py +156 -10
- metaflow/datastore/spin_datastore.py +91 -0
- metaflow/datastore/task_datastore.py +154 -39
- metaflow/debug.py +5 -0
- metaflow/decorators.py +404 -78
- metaflow/exception.py +8 -2
- metaflow/extension_support/__init__.py +527 -376
- metaflow/extension_support/_empty_file.py +2 -2
- metaflow/extension_support/plugins.py +49 -31
- metaflow/flowspec.py +482 -33
- metaflow/graph.py +210 -42
- metaflow/includefile.py +84 -40
- metaflow/lint.py +141 -22
- metaflow/meta_files.py +13 -0
- metaflow/{metadata → metadata_provider}/heartbeat.py +24 -8
- metaflow/{metadata → metadata_provider}/metadata.py +86 -1
- metaflow/metaflow_config.py +175 -28
- metaflow/metaflow_config_funcs.py +51 -3
- metaflow/metaflow_current.py +4 -10
- metaflow/metaflow_environment.py +139 -53
- metaflow/metaflow_git.py +115 -0
- metaflow/metaflow_profile.py +18 -0
- metaflow/metaflow_version.py +150 -66
- metaflow/mflog/__init__.py +4 -3
- metaflow/mflog/save_logs.py +2 -2
- metaflow/multicore_utils.py +31 -14
- metaflow/package/__init__.py +673 -0
- metaflow/packaging_sys/__init__.py +880 -0
- metaflow/packaging_sys/backend.py +128 -0
- metaflow/packaging_sys/distribution_support.py +153 -0
- metaflow/packaging_sys/tar_backend.py +99 -0
- metaflow/packaging_sys/utils.py +54 -0
- metaflow/packaging_sys/v1.py +527 -0
- metaflow/parameters.py +149 -28
- metaflow/plugins/__init__.py +74 -5
- metaflow/plugins/airflow/airflow.py +40 -25
- metaflow/plugins/airflow/airflow_cli.py +22 -5
- metaflow/plugins/airflow/airflow_decorator.py +1 -1
- metaflow/plugins/airflow/airflow_utils.py +5 -3
- metaflow/plugins/airflow/sensors/base_sensor.py +4 -4
- metaflow/plugins/airflow/sensors/external_task_sensor.py +2 -2
- metaflow/plugins/airflow/sensors/s3_sensor.py +2 -2
- metaflow/plugins/argo/argo_client.py +78 -33
- metaflow/plugins/argo/argo_events.py +6 -6
- metaflow/plugins/argo/argo_workflows.py +2410 -527
- metaflow/plugins/argo/argo_workflows_cli.py +571 -121
- metaflow/plugins/argo/argo_workflows_decorator.py +43 -12
- metaflow/plugins/argo/argo_workflows_deployer.py +106 -0
- metaflow/plugins/argo/argo_workflows_deployer_objects.py +453 -0
- metaflow/plugins/argo/capture_error.py +73 -0
- metaflow/plugins/argo/conditional_input_paths.py +35 -0
- metaflow/plugins/argo/exit_hooks.py +209 -0
- metaflow/plugins/argo/jobset_input_paths.py +15 -0
- metaflow/plugins/argo/param_val.py +19 -0
- metaflow/plugins/aws/aws_client.py +10 -3
- metaflow/plugins/aws/aws_utils.py +55 -2
- metaflow/plugins/aws/batch/batch.py +72 -5
- metaflow/plugins/aws/batch/batch_cli.py +33 -10
- metaflow/plugins/aws/batch/batch_client.py +4 -3
- metaflow/plugins/aws/batch/batch_decorator.py +102 -35
- metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +13 -10
- metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -3
- metaflow/plugins/aws/step_functions/production_token.py +1 -1
- metaflow/plugins/aws/step_functions/step_functions.py +65 -8
- metaflow/plugins/aws/step_functions/step_functions_cli.py +101 -7
- metaflow/plugins/aws/step_functions/step_functions_decorator.py +1 -2
- metaflow/plugins/aws/step_functions/step_functions_deployer.py +97 -0
- metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +264 -0
- metaflow/plugins/azure/azure_exceptions.py +1 -1
- metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +240 -0
- metaflow/plugins/azure/azure_tail.py +1 -1
- metaflow/plugins/azure/includefile_support.py +2 -0
- metaflow/plugins/cards/card_cli.py +66 -30
- metaflow/plugins/cards/card_creator.py +25 -1
- metaflow/plugins/cards/card_datastore.py +21 -49
- metaflow/plugins/cards/card_decorator.py +132 -8
- metaflow/plugins/cards/card_modules/basic.py +112 -17
- metaflow/plugins/cards/card_modules/bundle.css +1 -1
- metaflow/plugins/cards/card_modules/card.py +16 -1
- metaflow/plugins/cards/card_modules/chevron/renderer.py +1 -1
- metaflow/plugins/cards/card_modules/components.py +665 -28
- metaflow/plugins/cards/card_modules/convert_to_native_type.py +36 -7
- metaflow/plugins/cards/card_modules/json_viewer.py +232 -0
- metaflow/plugins/cards/card_modules/main.css +1 -0
- metaflow/plugins/cards/card_modules/main.js +68 -49
- metaflow/plugins/cards/card_modules/renderer_tools.py +1 -0
- metaflow/plugins/cards/card_modules/test_cards.py +26 -12
- metaflow/plugins/cards/card_server.py +39 -14
- metaflow/plugins/cards/component_serializer.py +2 -9
- metaflow/plugins/cards/metadata.py +22 -0
- metaflow/plugins/catch_decorator.py +9 -0
- metaflow/plugins/datastores/azure_storage.py +10 -1
- metaflow/plugins/datastores/gs_storage.py +6 -2
- metaflow/plugins/datastores/local_storage.py +12 -6
- metaflow/plugins/datastores/spin_storage.py +12 -0
- metaflow/plugins/datatools/local.py +2 -0
- metaflow/plugins/datatools/s3/s3.py +126 -75
- metaflow/plugins/datatools/s3/s3op.py +254 -121
- metaflow/plugins/env_escape/__init__.py +3 -3
- metaflow/plugins/env_escape/client_modules.py +102 -72
- metaflow/plugins/env_escape/server.py +7 -0
- metaflow/plugins/env_escape/stub.py +24 -5
- metaflow/plugins/events_decorator.py +343 -185
- metaflow/plugins/exit_hook/__init__.py +0 -0
- metaflow/plugins/exit_hook/exit_hook_decorator.py +46 -0
- metaflow/plugins/exit_hook/exit_hook_script.py +52 -0
- metaflow/plugins/gcp/__init__.py +1 -1
- metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +11 -6
- metaflow/plugins/gcp/gs_tail.py +10 -6
- metaflow/plugins/gcp/includefile_support.py +3 -0
- metaflow/plugins/kubernetes/kube_utils.py +108 -0
- metaflow/plugins/kubernetes/kubernetes.py +411 -130
- metaflow/plugins/kubernetes/kubernetes_cli.py +168 -36
- metaflow/plugins/kubernetes/kubernetes_client.py +104 -2
- metaflow/plugins/kubernetes/kubernetes_decorator.py +246 -88
- metaflow/plugins/kubernetes/kubernetes_job.py +253 -581
- metaflow/plugins/kubernetes/kubernetes_jobsets.py +1071 -0
- metaflow/plugins/kubernetes/spot_metadata_cli.py +69 -0
- metaflow/plugins/kubernetes/spot_monitor_sidecar.py +109 -0
- metaflow/plugins/logs_cli.py +359 -0
- metaflow/plugins/{metadata → metadata_providers}/local.py +144 -84
- metaflow/plugins/{metadata → metadata_providers}/service.py +103 -26
- metaflow/plugins/metadata_providers/spin.py +16 -0
- metaflow/plugins/package_cli.py +36 -24
- metaflow/plugins/parallel_decorator.py +128 -11
- metaflow/plugins/parsers.py +16 -0
- metaflow/plugins/project_decorator.py +51 -5
- metaflow/plugins/pypi/bootstrap.py +357 -105
- metaflow/plugins/pypi/conda_decorator.py +82 -81
- metaflow/plugins/pypi/conda_environment.py +187 -52
- metaflow/plugins/pypi/micromamba.py +157 -47
- metaflow/plugins/pypi/parsers.py +268 -0
- metaflow/plugins/pypi/pip.py +88 -13
- metaflow/plugins/pypi/pypi_decorator.py +37 -1
- metaflow/plugins/pypi/utils.py +48 -2
- metaflow/plugins/resources_decorator.py +2 -2
- metaflow/plugins/secrets/__init__.py +3 -0
- metaflow/plugins/secrets/secrets_decorator.py +26 -181
- metaflow/plugins/secrets/secrets_func.py +49 -0
- metaflow/plugins/secrets/secrets_spec.py +101 -0
- metaflow/plugins/secrets/utils.py +74 -0
- metaflow/plugins/tag_cli.py +4 -7
- metaflow/plugins/test_unbounded_foreach_decorator.py +41 -6
- metaflow/plugins/timeout_decorator.py +3 -3
- metaflow/plugins/uv/__init__.py +0 -0
- metaflow/plugins/uv/bootstrap.py +128 -0
- metaflow/plugins/uv/uv_environment.py +72 -0
- metaflow/procpoll.py +1 -1
- metaflow/pylint_wrapper.py +5 -1
- metaflow/runner/__init__.py +0 -0
- metaflow/runner/click_api.py +717 -0
- metaflow/runner/deployer.py +470 -0
- metaflow/runner/deployer_impl.py +201 -0
- metaflow/runner/metaflow_runner.py +714 -0
- metaflow/runner/nbdeploy.py +132 -0
- metaflow/runner/nbrun.py +225 -0
- metaflow/runner/subprocess_manager.py +650 -0
- metaflow/runner/utils.py +335 -0
- metaflow/runtime.py +1078 -260
- metaflow/sidecar/sidecar_worker.py +1 -1
- metaflow/system/__init__.py +5 -0
- metaflow/system/system_logger.py +85 -0
- metaflow/system/system_monitor.py +108 -0
- metaflow/system/system_utils.py +19 -0
- metaflow/task.py +521 -225
- metaflow/tracing/__init__.py +7 -7
- metaflow/tracing/span_exporter.py +31 -38
- metaflow/tracing/tracing_modules.py +38 -43
- metaflow/tuple_util.py +27 -0
- metaflow/user_configs/__init__.py +0 -0
- metaflow/user_configs/config_options.py +563 -0
- metaflow/user_configs/config_parameters.py +598 -0
- metaflow/user_decorators/__init__.py +0 -0
- metaflow/user_decorators/common.py +144 -0
- metaflow/user_decorators/mutable_flow.py +512 -0
- metaflow/user_decorators/mutable_step.py +424 -0
- metaflow/user_decorators/user_flow_decorator.py +264 -0
- metaflow/user_decorators/user_step_decorator.py +749 -0
- metaflow/util.py +243 -27
- metaflow/vendor.py +23 -7
- metaflow/version.py +1 -1
- ob_metaflow-2.19.7.1rc0.data/data/share/metaflow/devtools/Makefile +355 -0
- ob_metaflow-2.19.7.1rc0.data/data/share/metaflow/devtools/Tiltfile +726 -0
- ob_metaflow-2.19.7.1rc0.data/data/share/metaflow/devtools/pick_services.sh +105 -0
- ob_metaflow-2.19.7.1rc0.dist-info/METADATA +87 -0
- ob_metaflow-2.19.7.1rc0.dist-info/RECORD +445 -0
- {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/WHEEL +1 -1
- {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/entry_points.txt +1 -0
- metaflow/_vendor/v3_5/__init__.py +0 -1
- metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -644
- metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -152
- metaflow/package.py +0 -188
- ob_metaflow-2.11.13.1.dist-info/METADATA +0 -85
- ob_metaflow-2.11.13.1.dist-info/RECORD +0 -308
- /metaflow/_vendor/{v3_5/zipp.py → zipp.py} +0 -0
- /metaflow/{metadata → metadata_provider}/__init__.py +0 -0
- /metaflow/{metadata → metadata_provider}/util.py +0 -0
- /metaflow/plugins/{metadata → metadata_providers}/__init__.py +0 -0
- {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info/licenses}/LICENSE +0 -0
- {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/top_level.txt +0 -0
|
@@ -40,6 +40,7 @@ def render_safely(func):
|
|
|
40
40
|
This is a decorator that can be added to any `MetaflowCardComponent.render`
|
|
41
41
|
The goal is to render subcomponents safely and ensure that they are JSON serializable.
|
|
42
42
|
"""
|
|
43
|
+
|
|
43
44
|
# expects a renderer func
|
|
44
45
|
def ret_func(self, *args, **kwargs):
|
|
45
46
|
return _render_component_safely(self, func, True, *args, **kwargs)
|
|
@@ -34,41 +34,41 @@ class TestPathSpecCard(MetaflowCard):
|
|
|
34
34
|
class TestEditableCard(MetaflowCard):
|
|
35
35
|
type = "test_editable_card"
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
separator = "$&#!!@*"
|
|
38
38
|
|
|
39
39
|
ALLOW_USER_COMPONENTS = True
|
|
40
40
|
|
|
41
|
-
def __init__(self,
|
|
41
|
+
def __init__(self, components=[], **kwargs):
|
|
42
42
|
self._components = components
|
|
43
43
|
|
|
44
44
|
def render(self, task):
|
|
45
|
-
return self.
|
|
45
|
+
return self.separator.join([str(comp) for comp in self._components])
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class TestEditableCard2(MetaflowCard):
|
|
49
49
|
type = "test_editable_card_2"
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
separator = "$&#!!@*"
|
|
52
52
|
|
|
53
53
|
ALLOW_USER_COMPONENTS = True
|
|
54
54
|
|
|
55
|
-
def __init__(self,
|
|
55
|
+
def __init__(self, components=[], **kwargs):
|
|
56
56
|
self._components = components
|
|
57
57
|
|
|
58
58
|
def render(self, task):
|
|
59
|
-
return self.
|
|
59
|
+
return self.separator.join([str(comp) for comp in self._components])
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
class TestNonEditableCard(MetaflowCard):
|
|
63
63
|
type = "test_non_editable_card"
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
separator = "$&#!!@*"
|
|
66
66
|
|
|
67
|
-
def __init__(self,
|
|
67
|
+
def __init__(self, components=[], **kwargs):
|
|
68
68
|
self._components = components
|
|
69
69
|
|
|
70
70
|
def render(self, task):
|
|
71
|
-
return self.
|
|
71
|
+
return self.separator.join([str(comp) for comp in self._components])
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
class TestMockCard(MetaflowCard):
|
|
@@ -138,7 +138,6 @@ class TestJSONComponent(MetaflowCardComponent):
|
|
|
138
138
|
|
|
139
139
|
|
|
140
140
|
class TestRefreshCard(MetaflowCard):
|
|
141
|
-
|
|
142
141
|
"""
|
|
143
142
|
This card takes no components and helps test the `current.card.refresh(data)` interface.
|
|
144
143
|
"""
|
|
@@ -178,7 +177,6 @@ def _component_values_to_hash(components):
|
|
|
178
177
|
|
|
179
178
|
|
|
180
179
|
class TestRefreshComponentCard(MetaflowCard):
|
|
181
|
-
|
|
182
180
|
"""
|
|
183
181
|
This card takes components and helps test the `current.card.components["A"].update()`
|
|
184
182
|
interface
|
|
@@ -195,7 +193,7 @@ class TestRefreshComponentCard(MetaflowCard):
|
|
|
195
193
|
|
|
196
194
|
type = "test_component_refresh_card"
|
|
197
195
|
|
|
198
|
-
def __init__(self,
|
|
196
|
+
def __init__(self, components=[], **kwargs):
|
|
199
197
|
self._components = components
|
|
200
198
|
|
|
201
199
|
def render(self, task) -> str:
|
|
@@ -215,3 +213,19 @@ class TestRefreshComponentCard(MetaflowCard):
|
|
|
215
213
|
if task.finished:
|
|
216
214
|
return "final"
|
|
217
215
|
return "runtime-%s" % _component_values_to_hash(data["components"])
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class TestImageCard(MetaflowCard):
|
|
219
|
+
"""Card that renders a tiny PNG using ``TaskToDict.parse_image``."""
|
|
220
|
+
|
|
221
|
+
type = "test_image_card"
|
|
222
|
+
|
|
223
|
+
def render(self, task):
|
|
224
|
+
from .convert_to_native_type import TaskToDict
|
|
225
|
+
import base64
|
|
226
|
+
|
|
227
|
+
png_bytes = base64.b64decode(
|
|
228
|
+
"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGNgYGBgAAAABQABRDE8UwAAAABJRU5ErkJggg=="
|
|
229
|
+
)
|
|
230
|
+
img_src = TaskToDict().parse_image(png_bytes)
|
|
231
|
+
return f"<html><img src='{img_src}' /></html>"
|
|
@@ -20,14 +20,9 @@ except ImportError:
|
|
|
20
20
|
from .card_client import CardContainer
|
|
21
21
|
from .exception import CardNotPresentException
|
|
22
22
|
from .card_resolver import resolve_paths_from_task
|
|
23
|
-
from metaflow.metaflow_config import DATASTORE_LOCAL_DIR
|
|
24
23
|
from metaflow import namespace
|
|
25
|
-
from metaflow.exception import
|
|
26
|
-
|
|
27
|
-
MetaflowNotFound,
|
|
28
|
-
MetaflowNamespaceMismatch,
|
|
29
|
-
)
|
|
30
|
-
|
|
24
|
+
from metaflow.exception import MetaflowNotFound
|
|
25
|
+
from metaflow.plugins.datastores.local_storage import LocalStorage
|
|
31
26
|
|
|
32
27
|
VIEWER_PATH = os.path.join(
|
|
33
28
|
os.path.dirname(os.path.abspath(__file__)), "card_viewer", "viewer.html"
|
|
@@ -50,18 +45,48 @@ class RunWatcher(Thread):
|
|
|
50
45
|
def __init__(self, flow_name, connection: Connection):
|
|
51
46
|
super().__init__()
|
|
52
47
|
|
|
53
|
-
self._watch_file = os.path.join(
|
|
54
|
-
os.getcwd(), DATASTORE_LOCAL_DIR, flow_name, "latest_run"
|
|
55
|
-
)
|
|
56
|
-
self._current_run_id = self.get_run_id()
|
|
57
48
|
self.daemon = True
|
|
58
49
|
self._connection = connection
|
|
50
|
+
self._flow_name = flow_name
|
|
51
|
+
|
|
52
|
+
self._watch_file = self._initialize_watch_file()
|
|
53
|
+
if self._watch_file is None:
|
|
54
|
+
_ClickLogger(
|
|
55
|
+
"Warning: Could not initialize watch file location.", fg="yellow"
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
self._current_run_id = self.get_run_id()
|
|
59
|
+
|
|
60
|
+
def _initialize_watch_file(self):
|
|
61
|
+
local_root = LocalStorage.datastore_root
|
|
62
|
+
if local_root is None:
|
|
63
|
+
local_root = LocalStorage.get_datastore_root_from_config(
|
|
64
|
+
lambda _: None, create_on_absent=False
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
os.path.join(local_root, self._flow_name, "latest_run")
|
|
69
|
+
if local_root
|
|
70
|
+
else None
|
|
71
|
+
)
|
|
59
72
|
|
|
60
73
|
def get_run_id(self):
|
|
61
|
-
if
|
|
74
|
+
# Try to reinitialize watch file if needed
|
|
75
|
+
if not self._watch_file:
|
|
76
|
+
self._watch_file = self._initialize_watch_file()
|
|
77
|
+
|
|
78
|
+
# Early return if watch file is still None or doesn't exist
|
|
79
|
+
if not (self._watch_file and os.path.exists(self._watch_file)):
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
with open(self._watch_file, "r") as f:
|
|
84
|
+
return f.read().strip()
|
|
85
|
+
except (IOError, OSError) as e:
|
|
86
|
+
_ClickLogger(
|
|
87
|
+
"Warning: Could not read run ID from watch file: %s" % e, fg="yellow"
|
|
88
|
+
)
|
|
62
89
|
return None
|
|
63
|
-
with open(self._watch_file, "r") as f:
|
|
64
|
-
return f.read().strip()
|
|
65
90
|
|
|
66
91
|
def watch(self):
|
|
67
92
|
while True:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from .card_modules import MetaflowCardComponent
|
|
2
|
+
from .card_modules.card import create_component_id
|
|
2
3
|
from .card_modules.basic import ErrorComponent, SectionComponent
|
|
3
4
|
from .card_modules.components import (
|
|
4
5
|
UserComponent,
|
|
5
|
-
create_component_id,
|
|
6
6
|
StubComponent,
|
|
7
7
|
)
|
|
8
8
|
from .exception import ComponentOverwriteNotSupportedException
|
|
@@ -57,15 +57,8 @@ class ComponentStore:
|
|
|
57
57
|
The `_component_map` attribute is supposed to be a dictionary so that we can access the components by their ids.
|
|
58
58
|
But we also want to maintain order in which components are inserted since all of these components are going to be visible on a UI.
|
|
59
59
|
Since python3.6 dictionaries are ordered by default so we can use the default python `dict`.
|
|
60
|
-
For python3.5 and below we need to use an OrderedDict since `dict`'s are not ordered by default.
|
|
61
60
|
"""
|
|
62
|
-
|
|
63
|
-
platform.python_version_tuple()[1]
|
|
64
|
-
)
|
|
65
|
-
if python_version < 36:
|
|
66
|
-
self._component_map = OrderedDict()
|
|
67
|
-
else:
|
|
68
|
-
self._component_map = {}
|
|
61
|
+
self._component_map = {}
|
|
69
62
|
|
|
70
63
|
def __init__(self, logger, card_type=None, components=None, user_set_id=None):
|
|
71
64
|
self._logger = logger
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from metaflow.metadata_provider import MetaDatum
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _save_metadata(
|
|
6
|
+
metadata_provider,
|
|
7
|
+
run_id,
|
|
8
|
+
step_name,
|
|
9
|
+
task_id,
|
|
10
|
+
attempt_id,
|
|
11
|
+
card_uuid,
|
|
12
|
+
save_metadata,
|
|
13
|
+
):
|
|
14
|
+
entries = [
|
|
15
|
+
MetaDatum(
|
|
16
|
+
field=card_uuid,
|
|
17
|
+
value=json.dumps(save_metadata),
|
|
18
|
+
type="card-info",
|
|
19
|
+
tags=["attempt_id:{0}".format(attempt_id)],
|
|
20
|
+
)
|
|
21
|
+
]
|
|
22
|
+
metadata_provider.register_metadata(run_id, step_name, task_id, entries)
|
|
@@ -52,6 +52,15 @@ class CatchDecorator(StepDecorator):
|
|
|
52
52
|
"split steps." % step
|
|
53
53
|
)
|
|
54
54
|
|
|
55
|
+
# Do not support catch on switch steps for now.
|
|
56
|
+
# When applying @catch to a switch step, we can not guarantee that the flow attribute used for the switching condition gets properly recorded.
|
|
57
|
+
if graph[step].type == "split-switch":
|
|
58
|
+
raise MetaflowException(
|
|
59
|
+
"@catch is defined for the step *%s* "
|
|
60
|
+
"but @catch is not supported in conditional "
|
|
61
|
+
"switch steps." % step
|
|
62
|
+
)
|
|
63
|
+
|
|
55
64
|
def _print_exception(self, step, flow):
|
|
56
65
|
self.logger(head="@catch caught an exception from %s" % flow, timestamp=False)
|
|
57
66
|
for line in traceback.format_exc().splitlines():
|
|
@@ -145,12 +145,19 @@ class _AzureRootClient(object):
|
|
|
145
145
|
# It is good enough 99.9% of the time.
|
|
146
146
|
# Depending on ResourceExistsError is more costly, though
|
|
147
147
|
# we are still going to handle it right.
|
|
148
|
+
|
|
149
|
+
# The default timeout in the Azure blobstore python SDK
|
|
150
|
+
# doesn't work well on slower network connections and largish
|
|
151
|
+
# files. Hence increasing the connection_timeout below.
|
|
152
|
+
# For more details, see this:
|
|
153
|
+
# https://github.com/Azure/azure-sdk-for-python/issues/23232
|
|
148
154
|
if overwrite or not blob.exists():
|
|
149
155
|
blob.upload_blob(
|
|
150
156
|
byte_stream,
|
|
151
157
|
overwrite=overwrite,
|
|
152
158
|
metadata=metadata_to_upload,
|
|
153
159
|
max_concurrency=AZURE_STORAGE_UPLOAD_MAX_CONCURRENCY,
|
|
160
|
+
connection_timeout=14400,
|
|
154
161
|
)
|
|
155
162
|
except ResourceExistsError:
|
|
156
163
|
if overwrite:
|
|
@@ -346,7 +353,9 @@ class AzureStorage(DataStoreStorage):
|
|
|
346
353
|
byte_stream, metadata = byte_stream
|
|
347
354
|
tmp_filename = os.path.join(tmpdir, str(uuid.uuid4()))
|
|
348
355
|
with open(tmp_filename, "wb") as f:
|
|
349
|
-
|
|
356
|
+
# make sure to close the file handle after reading.
|
|
357
|
+
with byte_stream as bytes:
|
|
358
|
+
f.write(bytes.read())
|
|
350
359
|
# Fully finish writing the file, before submitting work. Careful with indentation.
|
|
351
360
|
|
|
352
361
|
futures.append(
|
|
@@ -119,7 +119,9 @@ class _GSRootClient(object):
|
|
|
119
119
|
blob.metadata = {"metaflow-user-attributes": json.dumps(metadata)}
|
|
120
120
|
from google.cloud.storage.retry import DEFAULT_RETRY
|
|
121
121
|
|
|
122
|
-
blob.upload_from_filename(
|
|
122
|
+
blob.upload_from_filename(
|
|
123
|
+
tmpfile, retry=DEFAULT_RETRY, timeout=(14400, 60)
|
|
124
|
+
) # generous timeout for massive uploads. Use the same values as for Azure (connection_timeout, read_timeout)
|
|
123
125
|
except Exception as e:
|
|
124
126
|
process_gs_exception(e)
|
|
125
127
|
|
|
@@ -225,7 +227,9 @@ class GSStorage(DataStoreStorage):
|
|
|
225
227
|
byte_stream, metadata = byte_stream
|
|
226
228
|
tmp_filename = os.path.join(tmpdir, str(uuid.uuid4()))
|
|
227
229
|
with open(tmp_filename, "wb") as f:
|
|
228
|
-
|
|
230
|
+
# make sure to close the file handle after reading.
|
|
231
|
+
with byte_stream as bytes:
|
|
232
|
+
f.write(bytes.read())
|
|
229
233
|
# Fully finish writing the file, before submitting work. Careful with indentation.
|
|
230
234
|
|
|
231
235
|
futures.append(
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
3
|
|
|
4
|
-
from metaflow.metaflow_config import
|
|
4
|
+
from metaflow.metaflow_config import (
|
|
5
|
+
DATASTORE_LOCAL_DIR,
|
|
6
|
+
DATASTORE_SYSROOT_LOCAL,
|
|
7
|
+
)
|
|
5
8
|
from metaflow.datastore.datastore_storage import CloseAfterUse, DataStoreStorage
|
|
6
9
|
|
|
7
10
|
|
|
8
11
|
class LocalStorage(DataStoreStorage):
|
|
9
12
|
TYPE = "local"
|
|
10
13
|
METADATA_DIR = "_meta"
|
|
14
|
+
DATASTORE_DIR = DATASTORE_LOCAL_DIR # ".metaflow"
|
|
15
|
+
SYSROOT_VAR = DATASTORE_SYSROOT_LOCAL
|
|
11
16
|
|
|
12
17
|
@classmethod
|
|
13
18
|
def get_datastore_root_from_config(cls, echo, create_on_absent=True):
|
|
14
|
-
result =
|
|
19
|
+
result = cls.SYSROOT_VAR
|
|
15
20
|
if result is None:
|
|
16
21
|
try:
|
|
17
22
|
# Python2
|
|
18
23
|
current_path = os.getcwdu()
|
|
19
24
|
except: # noqa E722
|
|
20
25
|
current_path = os.getcwd()
|
|
21
|
-
check_dir = os.path.join(current_path,
|
|
26
|
+
check_dir = os.path.join(current_path, cls.DATASTORE_DIR)
|
|
22
27
|
check_dir = os.path.realpath(check_dir)
|
|
23
28
|
orig_path = check_dir
|
|
24
29
|
top_level_reached = False
|
|
@@ -28,12 +33,13 @@ class LocalStorage(DataStoreStorage):
|
|
|
28
33
|
top_level_reached = True
|
|
29
34
|
break # We are no longer making upward progress
|
|
30
35
|
current_path = new_path
|
|
31
|
-
check_dir = os.path.join(current_path,
|
|
36
|
+
check_dir = os.path.join(current_path, cls.DATASTORE_DIR)
|
|
32
37
|
if top_level_reached:
|
|
33
38
|
if create_on_absent:
|
|
34
39
|
# Could not find any directory to use so create a new one
|
|
35
40
|
echo(
|
|
36
|
-
"Creating
|
|
41
|
+
"Creating %s datastore in current directory (%s)"
|
|
42
|
+
% (cls.TYPE, orig_path)
|
|
37
43
|
)
|
|
38
44
|
os.mkdir(orig_path)
|
|
39
45
|
result = orig_path
|
|
@@ -42,7 +48,7 @@ class LocalStorage(DataStoreStorage):
|
|
|
42
48
|
else:
|
|
43
49
|
result = check_dir
|
|
44
50
|
else:
|
|
45
|
-
result = os.path.join(result,
|
|
51
|
+
result = os.path.join(result, cls.DATASTORE_DIR)
|
|
46
52
|
return result
|
|
47
53
|
|
|
48
54
|
@staticmethod
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from metaflow.metaflow_config import (
|
|
2
|
+
DATASTORE_SPIN_LOCAL_DIR,
|
|
3
|
+
DATASTORE_SYSROOT_SPIN,
|
|
4
|
+
)
|
|
5
|
+
from metaflow.plugins.datastores.local_storage import LocalStorage
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SpinStorage(LocalStorage):
|
|
9
|
+
TYPE = "spin"
|
|
10
|
+
METADATA_DIR = "_meta"
|
|
11
|
+
DATASTORE_DIR = DATASTORE_SPIN_LOCAL_DIR # ".metaflow_spin"
|
|
12
|
+
SYSROOT_VAR = DATASTORE_SYSROOT_SPIN
|