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
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import tempfile
|
|
3
|
+
from typing import Dict, Optional
|
|
4
|
+
|
|
5
|
+
from metaflow import Deployer
|
|
6
|
+
from metaflow.runner.utils import get_current_cell, format_flowfile
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NBDeployerInitializationError(Exception):
|
|
10
|
+
"""Custom exception for errors during NBDeployer initialization."""
|
|
11
|
+
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class NBDeployer(object):
|
|
16
|
+
"""
|
|
17
|
+
A wrapper over `Deployer` for deploying flows defined in a Jupyter
|
|
18
|
+
notebook cell.
|
|
19
|
+
|
|
20
|
+
Instantiate this class on the last line of a notebook cell where
|
|
21
|
+
a `flow` is defined. In contrast to `Deployer`, this class is not
|
|
22
|
+
meant to be used in a context manager.
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
deployer = NBDeployer(FlowName)
|
|
26
|
+
ar = deployer.argo_workflows(name="madhur")
|
|
27
|
+
ar_obj = ar.create()
|
|
28
|
+
result = ar_obj.trigger(alpha=300)
|
|
29
|
+
print(result.status)
|
|
30
|
+
print(result.run)
|
|
31
|
+
result.terminate()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Parameters
|
|
35
|
+
----------
|
|
36
|
+
flow : FlowSpec
|
|
37
|
+
Flow defined in the same cell
|
|
38
|
+
show_output : bool, default True
|
|
39
|
+
Show the 'stdout' and 'stderr' to the console by default,
|
|
40
|
+
profile : str, optional, default None
|
|
41
|
+
Metaflow profile to use to deploy this run. If not specified, the default
|
|
42
|
+
profile is used (or the one already set using `METAFLOW_PROFILE`)
|
|
43
|
+
env : Dict[str, str], optional, default None
|
|
44
|
+
Additional environment variables to set. This overrides the
|
|
45
|
+
environment set for this process.
|
|
46
|
+
base_dir : str, optional, default None
|
|
47
|
+
The directory to run the subprocess in; if not specified, the current
|
|
48
|
+
working directory is used.
|
|
49
|
+
file_read_timeout : int, default 3600
|
|
50
|
+
The timeout until which we try to read the deployer attribute file (in seconds).
|
|
51
|
+
**kwargs : Any
|
|
52
|
+
Additional arguments that you would pass to `python myflow.py` i.e. options
|
|
53
|
+
listed in `python myflow.py --help`
|
|
54
|
+
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
def __init__(
|
|
58
|
+
self,
|
|
59
|
+
flow,
|
|
60
|
+
show_output: bool = True,
|
|
61
|
+
profile: Optional[str] = None,
|
|
62
|
+
env: Optional[Dict] = None,
|
|
63
|
+
base_dir: Optional[str] = None,
|
|
64
|
+
file_read_timeout: int = 3600,
|
|
65
|
+
**kwargs,
|
|
66
|
+
):
|
|
67
|
+
try:
|
|
68
|
+
from IPython import get_ipython
|
|
69
|
+
|
|
70
|
+
ipython = get_ipython()
|
|
71
|
+
except ModuleNotFoundError as e:
|
|
72
|
+
raise NBDeployerInitializationError(
|
|
73
|
+
"'NBDeployer' requires an interactive Python environment "
|
|
74
|
+
"(such as Jupyter)"
|
|
75
|
+
) from e
|
|
76
|
+
|
|
77
|
+
self.cell = get_current_cell(ipython)
|
|
78
|
+
self.flow = flow
|
|
79
|
+
self.show_output = show_output
|
|
80
|
+
self.profile = profile
|
|
81
|
+
self.env = env
|
|
82
|
+
self.cwd = base_dir if base_dir is not None else os.getcwd()
|
|
83
|
+
self.file_read_timeout = file_read_timeout
|
|
84
|
+
self.top_level_kwargs = kwargs
|
|
85
|
+
|
|
86
|
+
self.env_vars = os.environ.copy()
|
|
87
|
+
self.env_vars.update(env or {})
|
|
88
|
+
# clears the Jupyter parent process ID environment variable
|
|
89
|
+
# prevents server from interfering with Metaflow
|
|
90
|
+
self.env_vars.update({"JPY_PARENT_PID": ""})
|
|
91
|
+
|
|
92
|
+
if self.profile:
|
|
93
|
+
self.env_vars["METAFLOW_PROFILE"] = self.profile
|
|
94
|
+
|
|
95
|
+
if not self.cell:
|
|
96
|
+
raise ValueError("Couldn't find a cell.")
|
|
97
|
+
|
|
98
|
+
self.tmp_flow_file = tempfile.NamedTemporaryFile(
|
|
99
|
+
prefix=self.flow.__name__,
|
|
100
|
+
suffix=".py",
|
|
101
|
+
mode="w",
|
|
102
|
+
dir=self.cwd,
|
|
103
|
+
delete=False,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
self.tmp_flow_file.write(format_flowfile(self.cell))
|
|
107
|
+
self.tmp_flow_file.flush()
|
|
108
|
+
self.tmp_flow_file.close()
|
|
109
|
+
|
|
110
|
+
self.flow_file = self.tmp_flow_file.name
|
|
111
|
+
|
|
112
|
+
self.deployer = Deployer(
|
|
113
|
+
flow_file=self.flow_file,
|
|
114
|
+
show_output=self.show_output,
|
|
115
|
+
profile=self.profile,
|
|
116
|
+
env=self.env_vars,
|
|
117
|
+
cwd=self.cwd,
|
|
118
|
+
file_read_timeout=self.file_read_timeout,
|
|
119
|
+
**kwargs,
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
def __getattr__(self, name):
|
|
123
|
+
"""
|
|
124
|
+
Forward all attribute access to the underlying `Deployer` instance.
|
|
125
|
+
"""
|
|
126
|
+
return getattr(self.deployer, name)
|
|
127
|
+
|
|
128
|
+
def cleanup(self):
|
|
129
|
+
"""
|
|
130
|
+
Delete any temporary files created during execution.
|
|
131
|
+
"""
|
|
132
|
+
os.remove(self.flow_file)
|
metaflow/runner/nbrun.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import tempfile
|
|
3
|
+
from typing import Dict, Optional
|
|
4
|
+
|
|
5
|
+
from metaflow import Runner
|
|
6
|
+
from metaflow.runner.utils import get_current_cell, format_flowfile
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class NBRunnerInitializationError(Exception):
|
|
10
|
+
"""Custom exception for errors during NBRunner initialization."""
|
|
11
|
+
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class NBRunner(object):
|
|
16
|
+
"""
|
|
17
|
+
A wrapper over `Runner` for executing flows defined in a Jupyter
|
|
18
|
+
notebook cell.
|
|
19
|
+
|
|
20
|
+
Instantiate this class on the last line of a notebook cell where
|
|
21
|
+
a `flow` is defined. In contrast to `Runner`, this class is not
|
|
22
|
+
meant to be used in a context manager. Instead, use a blocking helper
|
|
23
|
+
function like `nbrun` (which calls `cleanup()` internally) or call
|
|
24
|
+
`cleanup()` explictly when using non-blocking APIs.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
run = NBRunner(FlowName).nbrun()
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
flow : FlowSpec
|
|
33
|
+
Flow defined in the same cell
|
|
34
|
+
show_output : bool, default True
|
|
35
|
+
Show the 'stdout' and 'stderr' to the console by default,
|
|
36
|
+
Only applicable for synchronous 'run' and 'resume' functions.
|
|
37
|
+
profile : str, optional, default None
|
|
38
|
+
Metaflow profile to use to run this run. If not specified, the default
|
|
39
|
+
profile is used (or the one already set using `METAFLOW_PROFILE`)
|
|
40
|
+
env : Dict[str, str], optional, default None
|
|
41
|
+
Additional environment variables to set for the Run. This overrides the
|
|
42
|
+
environment set for this process.
|
|
43
|
+
base_dir : str, optional, default None
|
|
44
|
+
The directory to run the subprocess in; if not specified, the current
|
|
45
|
+
working directory is used.
|
|
46
|
+
file_read_timeout : int, default 3600
|
|
47
|
+
The timeout until which we try to read the runner attribute file (in seconds).
|
|
48
|
+
**kwargs : Any
|
|
49
|
+
Additional arguments that you would pass to `python myflow.py` before
|
|
50
|
+
the `run` command.
|
|
51
|
+
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(
|
|
55
|
+
self,
|
|
56
|
+
flow,
|
|
57
|
+
show_output: bool = True,
|
|
58
|
+
profile: Optional[str] = None,
|
|
59
|
+
env: Optional[Dict] = None,
|
|
60
|
+
base_dir: Optional[str] = None,
|
|
61
|
+
file_read_timeout: int = 3600,
|
|
62
|
+
**kwargs,
|
|
63
|
+
):
|
|
64
|
+
try:
|
|
65
|
+
from IPython import get_ipython
|
|
66
|
+
|
|
67
|
+
ipython = get_ipython()
|
|
68
|
+
except ModuleNotFoundError:
|
|
69
|
+
raise NBRunnerInitializationError(
|
|
70
|
+
"'NBRunner' requires an interactive Python environment (such as Jupyter)"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
self.cell = get_current_cell(ipython)
|
|
74
|
+
self.flow = flow
|
|
75
|
+
self.show_output = show_output
|
|
76
|
+
|
|
77
|
+
self.env_vars = os.environ.copy()
|
|
78
|
+
self.env_vars.update(env or {})
|
|
79
|
+
# clears the Jupyter parent process ID environment variable
|
|
80
|
+
# prevents server from interfering with Metaflow
|
|
81
|
+
self.env_vars.update({"JPY_PARENT_PID": ""})
|
|
82
|
+
if profile:
|
|
83
|
+
self.env_vars["METAFLOW_PROFILE"] = profile
|
|
84
|
+
|
|
85
|
+
self.base_dir = base_dir if base_dir is not None else os.getcwd()
|
|
86
|
+
self.file_read_timeout = file_read_timeout
|
|
87
|
+
|
|
88
|
+
if not self.cell:
|
|
89
|
+
raise ValueError("Couldn't find a cell.")
|
|
90
|
+
|
|
91
|
+
self.tmp_flow_file = tempfile.NamedTemporaryFile(
|
|
92
|
+
prefix=self.flow.__name__,
|
|
93
|
+
suffix=".py",
|
|
94
|
+
mode="w",
|
|
95
|
+
dir=self.base_dir,
|
|
96
|
+
delete=False,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
self.tmp_flow_file.write(format_flowfile(self.cell))
|
|
100
|
+
self.tmp_flow_file.flush()
|
|
101
|
+
self.tmp_flow_file.close()
|
|
102
|
+
|
|
103
|
+
self.runner = Runner(
|
|
104
|
+
flow_file=self.tmp_flow_file.name,
|
|
105
|
+
show_output=self.show_output,
|
|
106
|
+
profile=profile,
|
|
107
|
+
env=self.env_vars,
|
|
108
|
+
cwd=self.base_dir,
|
|
109
|
+
file_read_timeout=self.file_read_timeout,
|
|
110
|
+
**kwargs,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
def nbrun(self, **kwargs):
|
|
114
|
+
"""
|
|
115
|
+
Blocking execution of the run. This method will wait until
|
|
116
|
+
the run has completed execution.
|
|
117
|
+
|
|
118
|
+
Note that in contrast to `run`, this method returns a
|
|
119
|
+
`metaflow.Run` object directly and calls `cleanup()` internally
|
|
120
|
+
to support a common notebook pattern of executing a flow and
|
|
121
|
+
retrieving its results immediately.
|
|
122
|
+
|
|
123
|
+
Parameters
|
|
124
|
+
----------
|
|
125
|
+
**kwargs : Any
|
|
126
|
+
Additional arguments that you would pass to `python myflow.py` after
|
|
127
|
+
the `run` command, in particular, any parameters accepted by the flow.
|
|
128
|
+
|
|
129
|
+
Returns
|
|
130
|
+
-------
|
|
131
|
+
Run
|
|
132
|
+
A `metaflow.Run` object representing the finished run.
|
|
133
|
+
"""
|
|
134
|
+
result = self.runner.run(**kwargs)
|
|
135
|
+
self.cleanup()
|
|
136
|
+
return result.run
|
|
137
|
+
|
|
138
|
+
def nbresume(self, **kwargs):
|
|
139
|
+
"""
|
|
140
|
+
Blocking resuming of a run. This method will wait until
|
|
141
|
+
the resumed run has completed execution.
|
|
142
|
+
|
|
143
|
+
Note that in contrast to `resume`, this method returns a
|
|
144
|
+
`metaflow.Run` object directly and calls `cleanup()` internally
|
|
145
|
+
to support a common notebook pattern of executing a flow and
|
|
146
|
+
retrieving its results immediately.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
**kwargs : Any
|
|
151
|
+
Additional arguments that you would pass to `python myflow.py` after
|
|
152
|
+
the `resume` command.
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
Run
|
|
157
|
+
A `metaflow.Run` object representing the resumed run.
|
|
158
|
+
"""
|
|
159
|
+
|
|
160
|
+
result = self.runner.resume(**kwargs)
|
|
161
|
+
self.cleanup()
|
|
162
|
+
return result.run
|
|
163
|
+
|
|
164
|
+
def run(self, **kwargs):
|
|
165
|
+
"""
|
|
166
|
+
Runs the flow.
|
|
167
|
+
"""
|
|
168
|
+
return self.runner.run(**kwargs)
|
|
169
|
+
|
|
170
|
+
def resume(self, **kwargs):
|
|
171
|
+
"""
|
|
172
|
+
Resumes the flow.
|
|
173
|
+
"""
|
|
174
|
+
return self.runner.resume(**kwargs)
|
|
175
|
+
|
|
176
|
+
async def async_run(self, **kwargs):
|
|
177
|
+
"""
|
|
178
|
+
Non-blocking execution of the run. This method will return as soon as the
|
|
179
|
+
run has launched. This method is equivalent to `Runner.async_run`.
|
|
180
|
+
|
|
181
|
+
Note that this method is asynchronous and needs to be `await`ed.
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
Parameters
|
|
185
|
+
----------
|
|
186
|
+
**kwargs : Any
|
|
187
|
+
Additional arguments that you would pass to `python myflow.py` after
|
|
188
|
+
the `run` command, in particular, any parameters accepted by the flow.
|
|
189
|
+
|
|
190
|
+
Returns
|
|
191
|
+
-------
|
|
192
|
+
ExecutingRun
|
|
193
|
+
ExecutingRun representing the run that was started.
|
|
194
|
+
"""
|
|
195
|
+
return await self.runner.async_run(**kwargs)
|
|
196
|
+
|
|
197
|
+
async def async_resume(self, **kwargs):
|
|
198
|
+
"""
|
|
199
|
+
Non-blocking execution of the run. This method will return as soon as the
|
|
200
|
+
run has launched. This method is equivalent to `Runner.async_resume`.
|
|
201
|
+
|
|
202
|
+
Note that this method is asynchronous and needs to be `await`ed.
|
|
203
|
+
|
|
204
|
+
Parameters
|
|
205
|
+
----------
|
|
206
|
+
**kwargs : Any
|
|
207
|
+
Additional arguments that you would pass to `python myflow.py` after
|
|
208
|
+
the `run` command, in particular, any parameters accepted by the flow.
|
|
209
|
+
|
|
210
|
+
Returns
|
|
211
|
+
-------
|
|
212
|
+
ExecutingRun
|
|
213
|
+
ExecutingRun representing the run that was started.
|
|
214
|
+
"""
|
|
215
|
+
return await self.runner.async_resume(**kwargs)
|
|
216
|
+
|
|
217
|
+
def cleanup(self):
|
|
218
|
+
"""
|
|
219
|
+
Delete any temporary files created during execution.
|
|
220
|
+
|
|
221
|
+
Call this method after using `async_run` or `async_resume`. You don't
|
|
222
|
+
have to call this after `nbrun` or `nbresume`.
|
|
223
|
+
"""
|
|
224
|
+
os.remove(self.tmp_flow_file.name)
|
|
225
|
+
self.runner.cleanup()
|