ob-metaflow 2.15.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 (169) hide show
  1. metaflow/__init__.py +10 -3
  2. metaflow/_vendor/imghdr/__init__.py +186 -0
  3. metaflow/_vendor/yaml/__init__.py +427 -0
  4. metaflow/_vendor/yaml/composer.py +139 -0
  5. metaflow/_vendor/yaml/constructor.py +748 -0
  6. metaflow/_vendor/yaml/cyaml.py +101 -0
  7. metaflow/_vendor/yaml/dumper.py +62 -0
  8. metaflow/_vendor/yaml/emitter.py +1137 -0
  9. metaflow/_vendor/yaml/error.py +75 -0
  10. metaflow/_vendor/yaml/events.py +86 -0
  11. metaflow/_vendor/yaml/loader.py +63 -0
  12. metaflow/_vendor/yaml/nodes.py +49 -0
  13. metaflow/_vendor/yaml/parser.py +589 -0
  14. metaflow/_vendor/yaml/reader.py +185 -0
  15. metaflow/_vendor/yaml/representer.py +389 -0
  16. metaflow/_vendor/yaml/resolver.py +227 -0
  17. metaflow/_vendor/yaml/scanner.py +1435 -0
  18. metaflow/_vendor/yaml/serializer.py +111 -0
  19. metaflow/_vendor/yaml/tokens.py +104 -0
  20. metaflow/cards.py +4 -0
  21. metaflow/cli.py +125 -21
  22. metaflow/cli_components/init_cmd.py +1 -0
  23. metaflow/cli_components/run_cmds.py +204 -40
  24. metaflow/cli_components/step_cmd.py +160 -4
  25. metaflow/client/__init__.py +1 -0
  26. metaflow/client/core.py +198 -130
  27. metaflow/client/filecache.py +59 -32
  28. metaflow/cmd/code/__init__.py +2 -1
  29. metaflow/cmd/develop/stub_generator.py +49 -18
  30. metaflow/cmd/develop/stubs.py +9 -27
  31. metaflow/cmd/make_wrapper.py +30 -0
  32. metaflow/datastore/__init__.py +1 -0
  33. metaflow/datastore/content_addressed_store.py +40 -9
  34. metaflow/datastore/datastore_set.py +10 -1
  35. metaflow/datastore/flow_datastore.py +124 -4
  36. metaflow/datastore/spin_datastore.py +91 -0
  37. metaflow/datastore/task_datastore.py +92 -6
  38. metaflow/debug.py +5 -0
  39. metaflow/decorators.py +331 -82
  40. metaflow/extension_support/__init__.py +414 -356
  41. metaflow/extension_support/_empty_file.py +2 -2
  42. metaflow/flowspec.py +322 -82
  43. metaflow/graph.py +178 -15
  44. metaflow/includefile.py +25 -3
  45. metaflow/lint.py +94 -3
  46. metaflow/meta_files.py +13 -0
  47. metaflow/metadata_provider/metadata.py +13 -2
  48. metaflow/metaflow_config.py +66 -4
  49. metaflow/metaflow_environment.py +91 -25
  50. metaflow/metaflow_profile.py +18 -0
  51. metaflow/metaflow_version.py +16 -1
  52. metaflow/package/__init__.py +673 -0
  53. metaflow/packaging_sys/__init__.py +880 -0
  54. metaflow/packaging_sys/backend.py +128 -0
  55. metaflow/packaging_sys/distribution_support.py +153 -0
  56. metaflow/packaging_sys/tar_backend.py +99 -0
  57. metaflow/packaging_sys/utils.py +54 -0
  58. metaflow/packaging_sys/v1.py +527 -0
  59. metaflow/parameters.py +6 -2
  60. metaflow/plugins/__init__.py +6 -0
  61. metaflow/plugins/airflow/airflow.py +11 -1
  62. metaflow/plugins/airflow/airflow_cli.py +16 -5
  63. metaflow/plugins/argo/argo_client.py +42 -20
  64. metaflow/plugins/argo/argo_events.py +6 -6
  65. metaflow/plugins/argo/argo_workflows.py +1023 -344
  66. metaflow/plugins/argo/argo_workflows_cli.py +396 -94
  67. metaflow/plugins/argo/argo_workflows_decorator.py +9 -0
  68. metaflow/plugins/argo/argo_workflows_deployer_objects.py +75 -49
  69. metaflow/plugins/argo/capture_error.py +5 -2
  70. metaflow/plugins/argo/conditional_input_paths.py +35 -0
  71. metaflow/plugins/argo/exit_hooks.py +209 -0
  72. metaflow/plugins/argo/param_val.py +19 -0
  73. metaflow/plugins/aws/aws_client.py +6 -0
  74. metaflow/plugins/aws/aws_utils.py +33 -1
  75. metaflow/plugins/aws/batch/batch.py +72 -5
  76. metaflow/plugins/aws/batch/batch_cli.py +24 -3
  77. metaflow/plugins/aws/batch/batch_decorator.py +57 -6
  78. metaflow/plugins/aws/step_functions/step_functions.py +28 -3
  79. metaflow/plugins/aws/step_functions/step_functions_cli.py +49 -4
  80. metaflow/plugins/aws/step_functions/step_functions_deployer.py +3 -0
  81. metaflow/plugins/aws/step_functions/step_functions_deployer_objects.py +30 -0
  82. metaflow/plugins/cards/card_cli.py +20 -1
  83. metaflow/plugins/cards/card_creator.py +24 -1
  84. metaflow/plugins/cards/card_datastore.py +21 -49
  85. metaflow/plugins/cards/card_decorator.py +58 -6
  86. metaflow/plugins/cards/card_modules/basic.py +38 -9
  87. metaflow/plugins/cards/card_modules/bundle.css +1 -1
  88. metaflow/plugins/cards/card_modules/chevron/renderer.py +1 -1
  89. metaflow/plugins/cards/card_modules/components.py +592 -3
  90. metaflow/plugins/cards/card_modules/convert_to_native_type.py +34 -5
  91. metaflow/plugins/cards/card_modules/json_viewer.py +232 -0
  92. metaflow/plugins/cards/card_modules/main.css +1 -0
  93. metaflow/plugins/cards/card_modules/main.js +56 -41
  94. metaflow/plugins/cards/card_modules/test_cards.py +22 -6
  95. metaflow/plugins/cards/component_serializer.py +1 -8
  96. metaflow/plugins/cards/metadata.py +22 -0
  97. metaflow/plugins/catch_decorator.py +9 -0
  98. metaflow/plugins/datastores/local_storage.py +12 -6
  99. metaflow/plugins/datastores/spin_storage.py +12 -0
  100. metaflow/plugins/datatools/s3/s3.py +49 -17
  101. metaflow/plugins/datatools/s3/s3op.py +113 -66
  102. metaflow/plugins/env_escape/client_modules.py +102 -72
  103. metaflow/plugins/events_decorator.py +127 -121
  104. metaflow/plugins/exit_hook/__init__.py +0 -0
  105. metaflow/plugins/exit_hook/exit_hook_decorator.py +46 -0
  106. metaflow/plugins/exit_hook/exit_hook_script.py +52 -0
  107. metaflow/plugins/kubernetes/kubernetes.py +12 -1
  108. metaflow/plugins/kubernetes/kubernetes_cli.py +11 -0
  109. metaflow/plugins/kubernetes/kubernetes_decorator.py +25 -6
  110. metaflow/plugins/kubernetes/kubernetes_job.py +12 -4
  111. metaflow/plugins/kubernetes/kubernetes_jobsets.py +31 -30
  112. metaflow/plugins/metadata_providers/local.py +76 -82
  113. metaflow/plugins/metadata_providers/service.py +13 -9
  114. metaflow/plugins/metadata_providers/spin.py +16 -0
  115. metaflow/plugins/package_cli.py +36 -24
  116. metaflow/plugins/parallel_decorator.py +11 -2
  117. metaflow/plugins/parsers.py +16 -0
  118. metaflow/plugins/pypi/bootstrap.py +7 -1
  119. metaflow/plugins/pypi/conda_decorator.py +41 -82
  120. metaflow/plugins/pypi/conda_environment.py +14 -6
  121. metaflow/plugins/pypi/micromamba.py +9 -1
  122. metaflow/plugins/pypi/pip.py +41 -5
  123. metaflow/plugins/pypi/pypi_decorator.py +4 -4
  124. metaflow/plugins/pypi/utils.py +22 -0
  125. metaflow/plugins/secrets/__init__.py +3 -0
  126. metaflow/plugins/secrets/secrets_decorator.py +14 -178
  127. metaflow/plugins/secrets/secrets_func.py +49 -0
  128. metaflow/plugins/secrets/secrets_spec.py +101 -0
  129. metaflow/plugins/secrets/utils.py +74 -0
  130. metaflow/plugins/test_unbounded_foreach_decorator.py +2 -2
  131. metaflow/plugins/timeout_decorator.py +0 -1
  132. metaflow/plugins/uv/bootstrap.py +29 -1
  133. metaflow/plugins/uv/uv_environment.py +5 -3
  134. metaflow/pylint_wrapper.py +5 -1
  135. metaflow/runner/click_api.py +79 -26
  136. metaflow/runner/deployer.py +208 -6
  137. metaflow/runner/deployer_impl.py +32 -12
  138. metaflow/runner/metaflow_runner.py +266 -33
  139. metaflow/runner/subprocess_manager.py +21 -1
  140. metaflow/runner/utils.py +27 -16
  141. metaflow/runtime.py +660 -66
  142. metaflow/task.py +255 -26
  143. metaflow/user_configs/config_options.py +33 -21
  144. metaflow/user_configs/config_parameters.py +220 -58
  145. metaflow/user_decorators/__init__.py +0 -0
  146. metaflow/user_decorators/common.py +144 -0
  147. metaflow/user_decorators/mutable_flow.py +512 -0
  148. metaflow/user_decorators/mutable_step.py +424 -0
  149. metaflow/user_decorators/user_flow_decorator.py +264 -0
  150. metaflow/user_decorators/user_step_decorator.py +749 -0
  151. metaflow/util.py +197 -7
  152. metaflow/vendor.py +23 -7
  153. metaflow/version.py +1 -1
  154. {ob_metaflow-2.15.13.1.data → ob_metaflow-2.19.7.1rc0.data}/data/share/metaflow/devtools/Makefile +13 -2
  155. {ob_metaflow-2.15.13.1.data → ob_metaflow-2.19.7.1rc0.data}/data/share/metaflow/devtools/Tiltfile +107 -7
  156. {ob_metaflow-2.15.13.1.data → ob_metaflow-2.19.7.1rc0.data}/data/share/metaflow/devtools/pick_services.sh +1 -0
  157. {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/METADATA +2 -3
  158. {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/RECORD +162 -121
  159. {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/WHEEL +1 -1
  160. metaflow/_vendor/v3_5/__init__.py +0 -1
  161. metaflow/_vendor/v3_5/importlib_metadata/__init__.py +0 -644
  162. metaflow/_vendor/v3_5/importlib_metadata/_compat.py +0 -152
  163. metaflow/_vendor/v3_5/zipp.py +0 -329
  164. metaflow/info_file.py +0 -25
  165. metaflow/package.py +0 -203
  166. metaflow/user_configs/config_decorators.py +0 -568
  167. {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/entry_points.txt +0 -0
  168. {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/licenses/LICENSE +0 -0
  169. {ob_metaflow-2.15.13.1.dist-info → ob_metaflow-2.19.7.1rc0.dist-info}/top_level.txt +0 -0
@@ -7,6 +7,7 @@ from hashlib import sha1
7
7
  from metaflow import current, decorators
8
8
  from metaflow._vendor import click
9
9
  from metaflow.exception import MetaflowException, MetaflowInternalError
10
+ from metaflow.metaflow_config import FEAT_ALWAYS_UPLOAD_CODE_PACKAGE
10
11
  from metaflow.package import MetaflowPackage
11
12
  from metaflow.plugins.aws.step_functions.production_token import (
12
13
  load_token,
@@ -288,20 +289,30 @@ def make_flow(
288
289
  decorators._init_step_decorators(
289
290
  obj.flow, obj.graph, obj.environment, obj.flow_datastore, obj.logger
290
291
  )
291
-
292
+ obj.graph = obj.flow._graph
292
293
  # Save the code package in the flow datastore so that both user code and
293
294
  # metaflow package can be retrieved during workflow execution.
294
295
  obj.package = MetaflowPackage(
295
- obj.flow, obj.environment, obj.echo, obj.package_suffixes
296
+ obj.flow,
297
+ obj.environment,
298
+ obj.echo,
299
+ suffixes=obj.package_suffixes,
300
+ flow_datastore=obj.flow_datastore if FEAT_ALWAYS_UPLOAD_CODE_PACKAGE else None,
296
301
  )
297
- package_url, package_sha = obj.flow_datastore.save_data(
298
- [obj.package.blob], len_hint=1
299
- )[0]
302
+ # This blocks until the package is created
303
+ if FEAT_ALWAYS_UPLOAD_CODE_PACKAGE:
304
+ package_url = obj.package.package_url()
305
+ package_sha = obj.package.package_sha()
306
+ else:
307
+ package_url, package_sha = obj.flow_datastore.save_data(
308
+ [obj.package.blob], len_hint=1
309
+ )[0]
300
310
 
301
311
  return Airflow(
302
312
  dag_name,
303
313
  obj.graph,
304
314
  obj.flow,
315
+ obj.package.package_metadata,
305
316
  package_sha,
306
317
  package_url,
307
318
  obj.metadata,
@@ -1,5 +1,6 @@
1
1
  import json
2
2
 
3
+ from metaflow.metaflow_config import ARGO_EVENTS_SENSOR_NAMESPACE
3
4
  from metaflow.exception import MetaflowException
4
5
  from metaflow.plugins.kubernetes.kubernetes_client import KubernetesClient
5
6
 
@@ -58,21 +59,38 @@ class ArgoClient(object):
58
59
  json.loads(e.body)["message"] if e.body is not None else e.reason
59
60
  )
60
61
 
61
- def get_workflow_templates(self):
62
+ def get_workflow_templates(self, page_size=100):
62
63
  client = self._client.get()
63
- try:
64
- return client.CustomObjectsApi().list_namespaced_custom_object(
65
- group=self._group,
66
- version=self._version,
67
- namespace=self._namespace,
68
- plural="workflowtemplates",
69
- )["items"]
70
- except client.rest.ApiException as e:
71
- if e.status == 404:
72
- return None
73
- raise ArgoClientException(
74
- json.loads(e.body)["message"] if e.body is not None else e.reason
75
- )
64
+ continue_token = None
65
+
66
+ while True:
67
+ try:
68
+ params = {"limit": page_size}
69
+ if continue_token:
70
+ params["_continue"] = continue_token
71
+
72
+ response = client.CustomObjectsApi().list_namespaced_custom_object(
73
+ group=self._group,
74
+ version=self._version,
75
+ namespace=self._namespace,
76
+ plural="workflowtemplates",
77
+ **params,
78
+ )
79
+
80
+ for item in response.get("items", []):
81
+ yield item
82
+
83
+ metadata = response.get("metadata", {})
84
+ continue_token = metadata.get("continue")
85
+
86
+ if not continue_token:
87
+ break
88
+ except client.rest.ApiException as e:
89
+ if e.status == 404:
90
+ return None
91
+ raise ArgoClientException(
92
+ json.loads(e.body)["message"] if e.body is not None else e.reason
93
+ )
76
94
 
77
95
  def register_workflow_template(self, name, workflow_template):
78
96
  # Unfortunately, Kubernetes client does not handle optimistic
@@ -307,6 +325,7 @@ class ArgoClient(object):
307
325
  "failedJobsHistoryLimit": 10000, # default is unfortunately 1
308
326
  "successfulJobsHistoryLimit": 10000, # default is unfortunately 3
309
327
  "workflowSpec": {"workflowTemplateRef": {"name": name}},
328
+ "startingDeadlineSeconds": 3540, # configuring this to 59 minutes so a failed trigger of cron workflow can succeed at most 59 mins after scheduled execution
310
329
  },
311
330
  }
312
331
  try:
@@ -360,12 +379,15 @@ class ArgoClient(object):
360
379
  json.loads(e.body)["message"] if e.body is not None else e.reason
361
380
  )
362
381
 
363
- def register_sensor(self, name, sensor=None):
382
+ def register_sensor(
383
+ self, name, sensor=None, sensor_namespace=ARGO_EVENTS_SENSOR_NAMESPACE
384
+ ):
364
385
  if sensor is None:
365
386
  sensor = {}
366
387
  # Unfortunately, Kubernetes client does not handle optimistic
367
388
  # concurrency control by itself unlike kubectl
368
389
  client = self._client.get()
390
+
369
391
  if not sensor:
370
392
  sensor["metadata"] = {}
371
393
 
@@ -375,7 +397,7 @@ class ArgoClient(object):
375
397
  ] = client.CustomObjectsApi().get_namespaced_custom_object(
376
398
  group=self._group,
377
399
  version=self._version,
378
- namespace=self._namespace,
400
+ namespace=sensor_namespace,
379
401
  plural="sensors",
380
402
  name=name,
381
403
  )[
@@ -390,7 +412,7 @@ class ArgoClient(object):
390
412
  return client.CustomObjectsApi().create_namespaced_custom_object(
391
413
  group=self._group,
392
414
  version=self._version,
393
- namespace=self._namespace,
415
+ namespace=sensor_namespace,
394
416
  plural="sensors",
395
417
  body=sensor,
396
418
  )
@@ -408,7 +430,7 @@ class ArgoClient(object):
408
430
  return client.CustomObjectsApi().replace_namespaced_custom_object(
409
431
  group=self._group,
410
432
  version=self._version,
411
- namespace=self._namespace,
433
+ namespace=sensor_namespace,
412
434
  plural="sensors",
413
435
  body=sensor,
414
436
  name=name,
@@ -418,7 +440,7 @@ class ArgoClient(object):
418
440
  json.loads(e.body)["message"] if e.body is not None else e.reason
419
441
  )
420
442
 
421
- def delete_sensor(self, name):
443
+ def delete_sensor(self, name, sensor_namespace):
422
444
  """
423
445
  Issues an API call for deleting a sensor
424
446
 
@@ -430,7 +452,7 @@ class ArgoClient(object):
430
452
  return client.CustomObjectsApi().delete_namespaced_custom_object(
431
453
  group=self._group,
432
454
  version=self._version,
433
- namespace=self._namespace,
455
+ namespace=sensor_namespace,
434
456
  plural="sensors",
435
457
  name=name,
436
458
  )
@@ -11,6 +11,7 @@ from metaflow.metaflow_config import (
11
11
  ARGO_EVENTS_WEBHOOK_AUTH,
12
12
  ARGO_EVENTS_WEBHOOK_URL,
13
13
  SERVICE_HEADERS,
14
+ SERVICE_RETRY_COUNT,
14
15
  )
15
16
 
16
17
 
@@ -127,12 +128,11 @@ class ArgoEvent(object):
127
128
  headers={"Content-Type": "application/json", **headers},
128
129
  data=json.dumps(data).encode("utf-8"),
129
130
  )
130
- retries = 3
131
- backoff_factor = 2
132
131
 
133
- for i in range(retries):
132
+ for i in range(SERVICE_RETRY_COUNT):
134
133
  try:
135
- urllib.request.urlopen(request, timeout=10.0)
134
+ # we do not want to wait indefinitely for a response on the event broadcast, as this will keep the task running.
135
+ urllib.request.urlopen(request, timeout=60)
136
136
  print(
137
137
  "Argo Event (%s) published." % self._name, file=sys.stderr
138
138
  )
@@ -141,10 +141,10 @@ class ArgoEvent(object):
141
141
  # TODO: Retry retryable HTTP error codes
142
142
  raise e
143
143
  except urllib.error.URLError as e:
144
- if i == retries - 1:
144
+ if i == SERVICE_RETRY_COUNT - 1:
145
145
  raise e
146
146
  else:
147
- time.sleep(backoff_factor**i)
147
+ time.sleep(2**i)
148
148
  except Exception as e:
149
149
  msg = "Unable to publish Argo Event (%s): %s" % (self._name, e)
150
150
  if ignore_errors: