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.
Files changed (289) hide show
  1. metaflow/R.py +10 -7
  2. metaflow/__init__.py +40 -25
  3. metaflow/_vendor/imghdr/__init__.py +186 -0
  4. metaflow/_vendor/importlib_metadata/__init__.py +1063 -0
  5. metaflow/_vendor/importlib_metadata/_adapters.py +68 -0
  6. metaflow/_vendor/importlib_metadata/_collections.py +30 -0
  7. metaflow/_vendor/importlib_metadata/_compat.py +71 -0
  8. metaflow/_vendor/importlib_metadata/_functools.py +104 -0
  9. metaflow/_vendor/importlib_metadata/_itertools.py +73 -0
  10. metaflow/_vendor/importlib_metadata/_meta.py +48 -0
  11. metaflow/_vendor/importlib_metadata/_text.py +99 -0
  12. metaflow/_vendor/importlib_metadata/py.typed +0 -0
  13. metaflow/_vendor/typeguard/__init__.py +48 -0
  14. metaflow/_vendor/typeguard/_checkers.py +1070 -0
  15. metaflow/_vendor/typeguard/_config.py +108 -0
  16. metaflow/_vendor/typeguard/_decorators.py +233 -0
  17. metaflow/_vendor/typeguard/_exceptions.py +42 -0
  18. metaflow/_vendor/typeguard/_functions.py +308 -0
  19. metaflow/_vendor/typeguard/_importhook.py +213 -0
  20. metaflow/_vendor/typeguard/_memo.py +48 -0
  21. metaflow/_vendor/typeguard/_pytest_plugin.py +127 -0
  22. metaflow/_vendor/typeguard/_suppression.py +86 -0
  23. metaflow/_vendor/typeguard/_transformer.py +1229 -0
  24. metaflow/_vendor/typeguard/_union_transformer.py +55 -0
  25. metaflow/_vendor/typeguard/_utils.py +173 -0
  26. metaflow/_vendor/typeguard/py.typed +0 -0
  27. metaflow/_vendor/typing_extensions.py +3641 -0
  28. metaflow/_vendor/v3_7/importlib_metadata/__init__.py +1063 -0
  29. metaflow/_vendor/v3_7/importlib_metadata/_adapters.py +68 -0
  30. metaflow/_vendor/v3_7/importlib_metadata/_collections.py +30 -0
  31. metaflow/_vendor/v3_7/importlib_metadata/_compat.py +71 -0
  32. metaflow/_vendor/v3_7/importlib_metadata/_functools.py +104 -0
  33. metaflow/_vendor/v3_7/importlib_metadata/_itertools.py +73 -0
  34. metaflow/_vendor/v3_7/importlib_metadata/_meta.py +48 -0
  35. metaflow/_vendor/v3_7/importlib_metadata/_text.py +99 -0
  36. metaflow/_vendor/v3_7/importlib_metadata/py.typed +0 -0
  37. metaflow/_vendor/v3_7/typeguard/__init__.py +48 -0
  38. metaflow/_vendor/v3_7/typeguard/_checkers.py +906 -0
  39. metaflow/_vendor/v3_7/typeguard/_config.py +108 -0
  40. metaflow/_vendor/v3_7/typeguard/_decorators.py +237 -0
  41. metaflow/_vendor/v3_7/typeguard/_exceptions.py +42 -0
  42. metaflow/_vendor/v3_7/typeguard/_functions.py +310 -0
  43. metaflow/_vendor/v3_7/typeguard/_importhook.py +213 -0
  44. metaflow/_vendor/v3_7/typeguard/_memo.py +48 -0
  45. metaflow/_vendor/v3_7/typeguard/_pytest_plugin.py +100 -0
  46. metaflow/_vendor/v3_7/typeguard/_suppression.py +88 -0
  47. metaflow/_vendor/v3_7/typeguard/_transformer.py +1207 -0
  48. metaflow/_vendor/v3_7/typeguard/_union_transformer.py +54 -0
  49. metaflow/_vendor/v3_7/typeguard/_utils.py +169 -0
  50. metaflow/_vendor/v3_7/typeguard/py.typed +0 -0
  51. metaflow/_vendor/v3_7/typing_extensions.py +3072 -0
  52. metaflow/_vendor/yaml/__init__.py +427 -0
  53. metaflow/_vendor/yaml/composer.py +139 -0
  54. metaflow/_vendor/yaml/constructor.py +748 -0
  55. metaflow/_vendor/yaml/cyaml.py +101 -0
  56. metaflow/_vendor/yaml/dumper.py +62 -0
  57. metaflow/_vendor/yaml/emitter.py +1137 -0
  58. metaflow/_vendor/yaml/error.py +75 -0
  59. metaflow/_vendor/yaml/events.py +86 -0
  60. metaflow/_vendor/yaml/loader.py +63 -0
  61. metaflow/_vendor/yaml/nodes.py +49 -0
  62. metaflow/_vendor/yaml/parser.py +589 -0
  63. metaflow/_vendor/yaml/reader.py +185 -0
  64. metaflow/_vendor/yaml/representer.py +389 -0
  65. metaflow/_vendor/yaml/resolver.py +227 -0
  66. metaflow/_vendor/yaml/scanner.py +1435 -0
  67. metaflow/_vendor/yaml/serializer.py +111 -0
  68. metaflow/_vendor/yaml/tokens.py +104 -0
  69. metaflow/cards.py +5 -0
  70. metaflow/cli.py +331 -785
  71. metaflow/cli_args.py +17 -0
  72. metaflow/cli_components/__init__.py +0 -0
  73. metaflow/cli_components/dump_cmd.py +96 -0
  74. metaflow/cli_components/init_cmd.py +52 -0
  75. metaflow/cli_components/run_cmds.py +546 -0
  76. metaflow/cli_components/step_cmd.py +334 -0
  77. metaflow/cli_components/utils.py +140 -0
  78. metaflow/client/__init__.py +1 -0
  79. metaflow/client/core.py +467 -73
  80. metaflow/client/filecache.py +75 -35
  81. metaflow/clone_util.py +7 -1
  82. metaflow/cmd/code/__init__.py +231 -0
  83. metaflow/cmd/develop/stub_generator.py +756 -288
  84. metaflow/cmd/develop/stubs.py +12 -28
  85. metaflow/cmd/main_cli.py +6 -4
  86. metaflow/cmd/make_wrapper.py +78 -0
  87. metaflow/datastore/__init__.py +1 -0
  88. metaflow/datastore/content_addressed_store.py +41 -10
  89. metaflow/datastore/datastore_set.py +11 -2
  90. metaflow/datastore/flow_datastore.py +156 -10
  91. metaflow/datastore/spin_datastore.py +91 -0
  92. metaflow/datastore/task_datastore.py +154 -39
  93. metaflow/debug.py +5 -0
  94. metaflow/decorators.py +404 -78
  95. metaflow/exception.py +8 -2
  96. metaflow/extension_support/__init__.py +527 -376
  97. metaflow/extension_support/_empty_file.py +2 -2
  98. metaflow/extension_support/plugins.py +49 -31
  99. metaflow/flowspec.py +482 -33
  100. metaflow/graph.py +210 -42
  101. metaflow/includefile.py +84 -40
  102. metaflow/lint.py +141 -22
  103. metaflow/meta_files.py +13 -0
  104. metaflow/{metadata → metadata_provider}/heartbeat.py +24 -8
  105. metaflow/{metadata → metadata_provider}/metadata.py +86 -1
  106. metaflow/metaflow_config.py +175 -28
  107. metaflow/metaflow_config_funcs.py +51 -3
  108. metaflow/metaflow_current.py +4 -10
  109. metaflow/metaflow_environment.py +139 -53
  110. metaflow/metaflow_git.py +115 -0
  111. metaflow/metaflow_profile.py +18 -0
  112. metaflow/metaflow_version.py +150 -66
  113. metaflow/mflog/__init__.py +4 -3
  114. metaflow/mflog/save_logs.py +2 -2
  115. metaflow/multicore_utils.py +31 -14
  116. metaflow/package/__init__.py +673 -0
  117. metaflow/packaging_sys/__init__.py +880 -0
  118. metaflow/packaging_sys/backend.py +128 -0
  119. metaflow/packaging_sys/distribution_support.py +153 -0
  120. metaflow/packaging_sys/tar_backend.py +99 -0
  121. metaflow/packaging_sys/utils.py +54 -0
  122. metaflow/packaging_sys/v1.py +527 -0
  123. metaflow/parameters.py +149 -28
  124. metaflow/plugins/__init__.py +74 -5
  125. metaflow/plugins/airflow/airflow.py +40 -25
  126. metaflow/plugins/airflow/airflow_cli.py +22 -5
  127. metaflow/plugins/airflow/airflow_decorator.py +1 -1
  128. metaflow/plugins/airflow/airflow_utils.py +5 -3
  129. metaflow/plugins/airflow/sensors/base_sensor.py +4 -4
  130. metaflow/plugins/airflow/sensors/external_task_sensor.py +2 -2
  131. metaflow/plugins/airflow/sensors/s3_sensor.py +2 -2
  132. metaflow/plugins/argo/argo_client.py +78 -33
  133. metaflow/plugins/argo/argo_events.py +6 -6
  134. metaflow/plugins/argo/argo_workflows.py +2410 -527
  135. metaflow/plugins/argo/argo_workflows_cli.py +571 -121
  136. metaflow/plugins/argo/argo_workflows_decorator.py +43 -12
  137. metaflow/plugins/argo/argo_workflows_deployer.py +106 -0
  138. metaflow/plugins/argo/argo_workflows_deployer_objects.py +453 -0
  139. metaflow/plugins/argo/capture_error.py +73 -0
  140. metaflow/plugins/argo/conditional_input_paths.py +35 -0
  141. metaflow/plugins/argo/exit_hooks.py +209 -0
  142. metaflow/plugins/argo/jobset_input_paths.py +15 -0
  143. metaflow/plugins/argo/param_val.py +19 -0
  144. metaflow/plugins/aws/aws_client.py +10 -3
  145. metaflow/plugins/aws/aws_utils.py +55 -2
  146. metaflow/plugins/aws/batch/batch.py +72 -5
  147. metaflow/plugins/aws/batch/batch_cli.py +33 -10
  148. metaflow/plugins/aws/batch/batch_client.py +4 -3
  149. metaflow/plugins/aws/batch/batch_decorator.py +102 -35
  150. metaflow/plugins/aws/secrets_manager/aws_secrets_manager_secrets_provider.py +13 -10
  151. metaflow/plugins/aws/step_functions/dynamo_db_client.py +0 -3
  152. metaflow/plugins/aws/step_functions/production_token.py +1 -1
  153. metaflow/plugins/aws/step_functions/step_functions.py +65 -8
  154. metaflow/plugins/aws/step_functions/step_functions_cli.py +101 -7
  155. metaflow/plugins/aws/step_functions/step_functions_decorator.py +1 -2
  156. metaflow/plugins/aws/step_functions/step_functions_deployer.py +97 -0
  157. metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +264 -0
  158. metaflow/plugins/azure/azure_exceptions.py +1 -1
  159. metaflow/plugins/azure/azure_secret_manager_secrets_provider.py +240 -0
  160. metaflow/plugins/azure/azure_tail.py +1 -1
  161. metaflow/plugins/azure/includefile_support.py +2 -0
  162. metaflow/plugins/cards/card_cli.py +66 -30
  163. metaflow/plugins/cards/card_creator.py +25 -1
  164. metaflow/plugins/cards/card_datastore.py +21 -49
  165. metaflow/plugins/cards/card_decorator.py +132 -8
  166. metaflow/plugins/cards/card_modules/basic.py +112 -17
  167. metaflow/plugins/cards/card_modules/bundle.css +1 -1
  168. metaflow/plugins/cards/card_modules/card.py +16 -1
  169. metaflow/plugins/cards/card_modules/chevron/renderer.py +1 -1
  170. metaflow/plugins/cards/card_modules/components.py +665 -28
  171. metaflow/plugins/cards/card_modules/convert_to_native_type.py +36 -7
  172. metaflow/plugins/cards/card_modules/json_viewer.py +232 -0
  173. metaflow/plugins/cards/card_modules/main.css +1 -0
  174. metaflow/plugins/cards/card_modules/main.js +68 -49
  175. metaflow/plugins/cards/card_modules/renderer_tools.py +1 -0
  176. metaflow/plugins/cards/card_modules/test_cards.py +26 -12
  177. metaflow/plugins/cards/card_server.py +39 -14
  178. metaflow/plugins/cards/component_serializer.py +2 -9
  179. metaflow/plugins/cards/metadata.py +22 -0
  180. metaflow/plugins/catch_decorator.py +9 -0
  181. metaflow/plugins/datastores/azure_storage.py +10 -1
  182. metaflow/plugins/datastores/gs_storage.py +6 -2
  183. metaflow/plugins/datastores/local_storage.py +12 -6
  184. metaflow/plugins/datastores/spin_storage.py +12 -0
  185. metaflow/plugins/datatools/local.py +2 -0
  186. metaflow/plugins/datatools/s3/s3.py +126 -75
  187. metaflow/plugins/datatools/s3/s3op.py +254 -121
  188. metaflow/plugins/env_escape/__init__.py +3 -3
  189. metaflow/plugins/env_escape/client_modules.py +102 -72
  190. metaflow/plugins/env_escape/server.py +7 -0
  191. metaflow/plugins/env_escape/stub.py +24 -5
  192. metaflow/plugins/events_decorator.py +343 -185
  193. metaflow/plugins/exit_hook/__init__.py +0 -0
  194. metaflow/plugins/exit_hook/exit_hook_decorator.py +46 -0
  195. metaflow/plugins/exit_hook/exit_hook_script.py +52 -0
  196. metaflow/plugins/gcp/__init__.py +1 -1
  197. metaflow/plugins/gcp/gcp_secret_manager_secrets_provider.py +11 -6
  198. metaflow/plugins/gcp/gs_tail.py +10 -6
  199. metaflow/plugins/gcp/includefile_support.py +3 -0
  200. metaflow/plugins/kubernetes/kube_utils.py +108 -0
  201. metaflow/plugins/kubernetes/kubernetes.py +411 -130
  202. metaflow/plugins/kubernetes/kubernetes_cli.py +168 -36
  203. metaflow/plugins/kubernetes/kubernetes_client.py +104 -2
  204. metaflow/plugins/kubernetes/kubernetes_decorator.py +246 -88
  205. metaflow/plugins/kubernetes/kubernetes_job.py +253 -581
  206. metaflow/plugins/kubernetes/kubernetes_jobsets.py +1071 -0
  207. metaflow/plugins/kubernetes/spot_metadata_cli.py +69 -0
  208. metaflow/plugins/kubernetes/spot_monitor_sidecar.py +109 -0
  209. metaflow/plugins/logs_cli.py +359 -0
  210. metaflow/plugins/{metadata → metadata_providers}/local.py +144 -84
  211. metaflow/plugins/{metadata → metadata_providers}/service.py +103 -26
  212. metaflow/plugins/metadata_providers/spin.py +16 -0
  213. metaflow/plugins/package_cli.py +36 -24
  214. metaflow/plugins/parallel_decorator.py +128 -11
  215. metaflow/plugins/parsers.py +16 -0
  216. metaflow/plugins/project_decorator.py +51 -5
  217. metaflow/plugins/pypi/bootstrap.py +357 -105
  218. metaflow/plugins/pypi/conda_decorator.py +82 -81
  219. metaflow/plugins/pypi/conda_environment.py +187 -52
  220. metaflow/plugins/pypi/micromamba.py +157 -47
  221. metaflow/plugins/pypi/parsers.py +268 -0
  222. metaflow/plugins/pypi/pip.py +88 -13
  223. metaflow/plugins/pypi/pypi_decorator.py +37 -1
  224. metaflow/plugins/pypi/utils.py +48 -2
  225. metaflow/plugins/resources_decorator.py +2 -2
  226. metaflow/plugins/secrets/__init__.py +3 -0
  227. metaflow/plugins/secrets/secrets_decorator.py +26 -181
  228. metaflow/plugins/secrets/secrets_func.py +49 -0
  229. metaflow/plugins/secrets/secrets_spec.py +101 -0
  230. metaflow/plugins/secrets/utils.py +74 -0
  231. metaflow/plugins/tag_cli.py +4 -7
  232. metaflow/plugins/test_unbounded_foreach_decorator.py +41 -6
  233. metaflow/plugins/timeout_decorator.py +3 -3
  234. metaflow/plugins/uv/__init__.py +0 -0
  235. metaflow/plugins/uv/bootstrap.py +128 -0
  236. metaflow/plugins/uv/uv_environment.py +72 -0
  237. metaflow/procpoll.py +1 -1
  238. metaflow/pylint_wrapper.py +5 -1
  239. metaflow/runner/__init__.py +0 -0
  240. metaflow/runner/click_api.py +717 -0
  241. metaflow/runner/deployer.py +470 -0
  242. metaflow/runner/deployer_impl.py +201 -0
  243. metaflow/runner/metaflow_runner.py +714 -0
  244. metaflow/runner/nbdeploy.py +132 -0
  245. metaflow/runner/nbrun.py +225 -0
  246. metaflow/runner/subprocess_manager.py +650 -0
  247. metaflow/runner/utils.py +335 -0
  248. metaflow/runtime.py +1078 -260
  249. metaflow/sidecar/sidecar_worker.py +1 -1
  250. metaflow/system/__init__.py +5 -0
  251. metaflow/system/system_logger.py +85 -0
  252. metaflow/system/system_monitor.py +108 -0
  253. metaflow/system/system_utils.py +19 -0
  254. metaflow/task.py +521 -225
  255. metaflow/tracing/__init__.py +7 -7
  256. metaflow/tracing/span_exporter.py +31 -38
  257. metaflow/tracing/tracing_modules.py +38 -43
  258. metaflow/tuple_util.py +27 -0
  259. metaflow/user_configs/__init__.py +0 -0
  260. metaflow/user_configs/config_options.py +563 -0
  261. metaflow/user_configs/config_parameters.py +598 -0
  262. metaflow/user_decorators/__init__.py +0 -0
  263. metaflow/user_decorators/common.py +144 -0
  264. metaflow/user_decorators/mutable_flow.py +512 -0
  265. metaflow/user_decorators/mutable_step.py +424 -0
  266. metaflow/user_decorators/user_flow_decorator.py +264 -0
  267. metaflow/user_decorators/user_step_decorator.py +749 -0
  268. metaflow/util.py +243 -27
  269. metaflow/vendor.py +23 -7
  270. metaflow/version.py +1 -1
  271. ob_metaflow-2.19.7.1rc0.data/data/share/metaflow/devtools/Makefile +355 -0
  272. ob_metaflow-2.19.7.1rc0.data/data/share/metaflow/devtools/Tiltfile +726 -0
  273. ob_metaflow-2.19.7.1rc0.data/data/share/metaflow/devtools/pick_services.sh +105 -0
  274. ob_metaflow-2.19.7.1rc0.dist-info/METADATA +87 -0
  275. ob_metaflow-2.19.7.1rc0.dist-info/RECORD +445 -0
  276. {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/WHEEL +1 -1
  277. {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/entry_points.txt +1 -0
  278. metaflow/_vendor/v3_5/__init__.py +0 -1
  279. metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -644
  280. metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -152
  281. metaflow/package.py +0 -188
  282. ob_metaflow-2.11.13.1.dist-info/METADATA +0 -85
  283. ob_metaflow-2.11.13.1.dist-info/RECORD +0 -308
  284. /metaflow/_vendor/{v3_5/zipp.py → zipp.py} +0 -0
  285. /metaflow/{metadata → metadata_provider}/__init__.py +0 -0
  286. /metaflow/{metadata → metadata_provider}/util.py +0 -0
  287. /metaflow/plugins/{metadata → metadata_providers}/__init__.py +0 -0
  288. {ob_metaflow-2.11.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info/licenses}/LICENSE +0 -0
  289. {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)
@@ -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()