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
@@ -21,6 +21,7 @@ if sys.platform == "darwin":
21
21
 
22
22
  # Path to the local directory to store artifacts for 'local' datastore.
23
23
  DATASTORE_LOCAL_DIR = ".metaflow"
24
+ DATASTORE_SPIN_LOCAL_DIR = ".metaflow_spin"
24
25
 
25
26
  # Local configuration file (in .metaflow) containing overrides per-project
26
27
  LOCAL_CONFIG_FILE = "config.json"
@@ -47,6 +48,38 @@ DEFAULT_FROM_DEPLOYMENT_IMPL = from_conf(
47
48
  "DEFAULT_FROM_DEPLOYMENT_IMPL", "argo-workflows"
48
49
  )
49
50
 
51
+ ###
52
+ # Spin configuration
53
+ ###
54
+ # Essentially a whitelist of decorators that are allowed in Spin steps
55
+ SPIN_ALLOWED_DECORATORS = from_conf(
56
+ "SPIN_ALLOWED_DECORATORS",
57
+ [
58
+ "conda",
59
+ "pypi",
60
+ "conda_base",
61
+ "pypi_base",
62
+ "environment",
63
+ "project",
64
+ "timeout",
65
+ "conda_env_internal",
66
+ "card",
67
+ ],
68
+ )
69
+
70
+ # Essentially a blacklist of decorators that are not allowed in Spin steps
71
+ # Note: decorators not in either SPIN_ALLOWED_DECORATORS or SPIN_DISALLOWED_DECORATORS
72
+ # are simply ignored in Spin steps
73
+ SPIN_DISALLOWED_DECORATORS = from_conf(
74
+ "SPIN_DISALLOWED_DECORATORS",
75
+ [
76
+ "parallel",
77
+ ],
78
+ )
79
+
80
+ # Default value for persist option in spin command
81
+ SPIN_PERSIST = from_conf("SPIN_PERSIST", False)
82
+
50
83
  ###
51
84
  # User configuration
52
85
  ###
@@ -57,6 +90,7 @@ USER = from_conf("USER")
57
90
  # Datastore configuration
58
91
  ###
59
92
  DATASTORE_SYSROOT_LOCAL = from_conf("DATASTORE_SYSROOT_LOCAL")
93
+ DATASTORE_SYSROOT_SPIN = from_conf("DATASTORE_SYSROOT_SPIN")
60
94
  # S3 bucket and prefix to store artifacts for 's3' datastore.
61
95
  DATASTORE_SYSROOT_S3 = from_conf("DATASTORE_SYSROOT_S3")
62
96
  # Azure Blob Storage container and blob prefix
@@ -109,6 +143,9 @@ S3_WORKER_COUNT = from_conf("S3_WORKER_COUNT", 64)
109
143
  # top-level retries)
110
144
  S3_TRANSIENT_RETRY_COUNT = from_conf("S3_TRANSIENT_RETRY_COUNT", 20)
111
145
 
146
+ # Whether to log transient retry messages to stdout
147
+ S3_LOG_TRANSIENT_RETRIES = from_conf("S3_LOG_TRANSIENT_RETRIES", False)
148
+
112
149
  # S3 retry configuration used in the aws client
113
150
  # Use the adaptive retry strategy by default
114
151
  S3_CLIENT_RETRY_CONFIG = from_conf(
@@ -214,8 +251,6 @@ CARD_GSROOT = from_conf(
214
251
  )
215
252
  CARD_NO_WARNING = from_conf("CARD_NO_WARNING", False)
216
253
 
217
- SKIP_CARD_DUALWRITE = from_conf("SKIP_CARD_DUALWRITE", False)
218
-
219
254
  RUNTIME_CARD_RENDER_INTERVAL = from_conf("RUNTIME_CARD_RENDER_INTERVAL", 60)
220
255
 
221
256
  # Azure storage account URL
@@ -317,6 +352,8 @@ SERVICE_INTERNAL_URL = from_conf("SERVICE_INTERNAL_URL", SERVICE_URL)
317
352
  # in all Metaflow deployments. Hopefully, some day we can flip the
318
353
  # default to True.
319
354
  BATCH_EMIT_TAGS = from_conf("BATCH_EMIT_TAGS", False)
355
+ # Default tags to add to AWS Batch jobs. These are in addition to the defaults set when BATCH_EMIT_TAGS is true.
356
+ BATCH_DEFAULT_TAGS = from_conf("BATCH_DEFAULT_TAGS", {})
320
357
 
321
358
  ###
322
359
  # AWS Step Functions configuration
@@ -345,6 +382,8 @@ SFN_S3_DISTRIBUTED_MAP_OUTPUT_PATH = from_conf(
345
382
  else None
346
383
  ),
347
384
  )
385
+ # Toggle for step command being part of the Step Function payload, or if it should be offloaded to S3
386
+ SFN_COMPRESS_STATE_MACHINE = from_conf("SFN_COMPRESS_STATE_MACHINE", False)
348
387
  ###
349
388
  # Kubernetes configuration
350
389
  ###
@@ -371,6 +410,8 @@ KUBERNETES_CONTAINER_IMAGE = from_conf(
371
410
  )
372
411
  # Image pull policy for container images
373
412
  KUBERNETES_IMAGE_PULL_POLICY = from_conf("KUBERNETES_IMAGE_PULL_POLICY", None)
413
+ # Image pull secrets for container images
414
+ KUBERNETES_IMAGE_PULL_SECRETS = from_conf("KUBERNETES_IMAGE_PULL_SECRETS", "")
374
415
  # Default container registry for K8S
375
416
  KUBERNETES_CONTAINER_REGISTRY = from_conf(
376
417
  "KUBERNETES_CONTAINER_REGISTRY", DEFAULT_CONTAINER_REGISTRY
@@ -408,6 +449,9 @@ ARGO_EVENTS_INTERNAL_WEBHOOK_URL = from_conf(
408
449
  "ARGO_EVENTS_INTERNAL_WEBHOOK_URL", ARGO_EVENTS_WEBHOOK_URL
409
450
  )
410
451
  ARGO_EVENTS_WEBHOOK_AUTH = from_conf("ARGO_EVENTS_WEBHOOK_AUTH", "none")
452
+ ARGO_EVENTS_SENSOR_NAMESPACE = from_conf(
453
+ "ARGO_EVENTS_SENSOR_NAMESPACE", KUBERNETES_NAMESPACE
454
+ )
411
455
 
412
456
  ARGO_WORKFLOWS_UI_URL = from_conf("ARGO_WORKFLOWS_UI_URL")
413
457
 
@@ -450,10 +494,27 @@ CONDA_USE_FAST_INIT = from_conf("CONDA_USE_FAST_INIT", False)
450
494
  # Print out warning if escape hatch is not used for the target packages
451
495
  ESCAPE_HATCH_WARNING = from_conf("ESCAPE_HATCH_WARNING", True)
452
496
 
497
+ ###
498
+ # Features
499
+ ###
500
+ FEAT_ALWAYS_UPLOAD_CODE_PACKAGE = from_conf("FEAT_ALWAYS_UPLOAD_CODE_PACKAGE", False)
501
+ ###
502
+ # Profile
503
+ ###
504
+ PROFILE_FROM_START = from_conf("PROFILE_FROM_START", False)
453
505
  ###
454
506
  # Debug configuration
455
507
  ###
456
- DEBUG_OPTIONS = ["subcommand", "sidecar", "s3client", "tracing", "stubgen", "userconf"]
508
+ DEBUG_OPTIONS = [
509
+ "subcommand",
510
+ "sidecar",
511
+ "s3client",
512
+ "tracing",
513
+ "stubgen",
514
+ "userconf",
515
+ "conda",
516
+ "package",
517
+ ]
457
518
 
458
519
  for typ in DEBUG_OPTIONS:
459
520
  vars()["DEBUG_%s" % typ.upper()] = from_conf("DEBUG_%s" % typ.upper(), False)
@@ -526,7 +587,7 @@ MAX_ATTEMPTS = 6
526
587
  # Feature flag (experimental features that are *explicitly* unsupported)
527
588
 
528
589
  # Process configs even when using the click_api for Runner/Deployer
529
- CLICK_API_PROCESS_CONFIG = from_conf("CLICK_API_PROCESS_CONFIG", False)
590
+ CLICK_API_PROCESS_CONFIG = from_conf("CLICK_API_PROCESS_CONFIG", True)
530
591
 
531
592
 
532
593
  # PINNED_CONDA_LIBS are the libraries that metaflow depends on for execution
@@ -547,6 +608,7 @@ def get_pinned_conda_libs(python_version, datastore_type):
547
608
  pins["google-auth"] = ">=2.11.0"
548
609
  pins["google-cloud-secret-manager"] = ">=2.10.0"
549
610
  pins["simple-gcp-object-downloader"] = ">=0.1.0"
611
+ pins["packaging"] = ">=24.0"
550
612
  elif datastore_type == "local":
551
613
  pass
552
614
  else:
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import os
2
3
  import platform
3
4
  import sys
@@ -8,6 +9,8 @@ from . import metaflow_git
8
9
  from metaflow.exception import MetaflowException
9
10
  from metaflow.extension_support import dump_module_info
10
11
  from metaflow.mflog import BASH_MFLOG, BASH_FLUSH_LOGS
12
+ from metaflow.package import MetaflowPackage
13
+
11
14
  from . import R
12
15
 
13
16
 
@@ -49,8 +52,36 @@ class MetaflowEnvironment(object):
49
52
 
50
53
  def add_to_package(self):
51
54
  """
52
- A list of tuples (file, arcname) to add to the job package.
53
- `arcname` is an alternative name for the file in the job package.
55
+ Called to add custom files needed for this environment. This hook will be
56
+ called in the `MetaflowPackage` class where metaflow compiles the code package
57
+ tarball. This hook can return one of two things (the first is for backwards
58
+ compatibility -- move to the second):
59
+ - a generator yielding a tuple of `(file_path, arcname)` to add files to
60
+ the code package. `file_path` is the path to the file on the local filesystem
61
+ and `arcname` is the path relative to the packaged code.
62
+ - a generator yielding a tuple of `(content, arcname, type)` where:
63
+ - type is one of
64
+ ContentType.{USER_CONTENT, CODE_CONTENT, MODULE_CONTENT, OTHER_CONTENT}
65
+ - for USER_CONTENT:
66
+ - the file will be included relative to the directory containing the
67
+ user's flow file.
68
+ - content: path to the file to include
69
+ - arcname: path relative to the directory containing the user's flow file
70
+ - for CODE_CONTENT:
71
+ - the file will be included relative to the code directory in the package.
72
+ This will be the directory containing `metaflow`.
73
+ - content: path to the file to include
74
+ - arcname: path relative to the code directory in the package
75
+ - for MODULE_CONTENT:
76
+ - the module will be added to the code package as a python module. It will
77
+ be accessible as usual (import <module_name>)
78
+ - content: name of the module
79
+ - arcname: None (ignored)
80
+ - for OTHER_CONTENT:
81
+ - the file will be included relative to any other configuration/metadata
82
+ files for the flow
83
+ - content: path to the file to include
84
+ - arcname: path relative to the config directory in the package
54
85
  """
55
86
  return []
56
87
 
@@ -143,6 +174,7 @@ class MetaflowEnvironment(object):
143
174
  "google-auth",
144
175
  "simple-gcp-object-downloader",
145
176
  "google-cloud-secret-manager",
177
+ "packaging",
146
178
  ],
147
179
  }
148
180
 
@@ -157,29 +189,63 @@ class MetaflowEnvironment(object):
157
189
  # skip pip installs if we know that packages might already be available
158
190
  return "if [ -z $METAFLOW_SKIP_INSTALL_DEPENDENCIES ]; then {}; fi".format(cmd)
159
191
 
160
- def get_package_commands(self, code_package_url, datastore_type):
161
- cmds = [
162
- BASH_MFLOG,
163
- BASH_FLUSH_LOGS,
164
- "mflog 'Setting up task environment.'",
165
- self._get_install_dependencies_cmd(datastore_type),
166
- "mkdir metaflow",
167
- "cd metaflow",
168
- "mkdir .metaflow", # mute local datastore creation log
169
- "i=0; while [ $i -le 5 ]; do "
170
- "mflog 'Downloading code package...'; "
171
- + self._get_download_code_package_cmd(code_package_url, datastore_type)
172
- + " && mflog 'Code package downloaded.' && break; "
173
- "sleep 10; i=$((i+1)); "
174
- "done",
175
- "if [ $i -gt 5 ]; then "
176
- "mflog 'Failed to download code package from %s "
177
- "after 6 tries. Exiting...' && exit 1; "
178
- "fi" % code_package_url,
179
- "TAR_OPTIONS='--warning=no-timestamp' tar xf job.tar",
180
- "mflog 'Task is starting.'",
181
- "flush_mflogs",
182
- ]
192
+ def get_package_commands(
193
+ self, code_package_url, datastore_type, code_package_metadata=None
194
+ ):
195
+ # HACK: We want to keep forward compatibility with compute layers so that
196
+ # they can still call get_package_commands and NOT pass any metadata. If
197
+ # there is no additional information, we *assume* that it is the default
198
+ # used.
199
+ if code_package_metadata is None:
200
+ code_package_metadata = json.dumps(
201
+ {
202
+ "version": 0,
203
+ "archive_format": "tgz",
204
+ "mfcontent_version": 1,
205
+ }
206
+ )
207
+
208
+ extra_exports = []
209
+ for k, v in MetaflowPackage.get_post_extract_env_vars(
210
+ code_package_metadata, dest_dir="$(pwd)"
211
+ ).items():
212
+ if k.endswith(":"):
213
+ # If the value ends with a colon, we override the existing value
214
+ extra_exports.append("export %s=%s" % (k[:-1], v))
215
+ else:
216
+ extra_exports.append(
217
+ "export %s=%s:$(printenv %s)" % (k, v.replace('"', '\\"'), k)
218
+ )
219
+
220
+ cmds = (
221
+ [
222
+ BASH_MFLOG,
223
+ BASH_FLUSH_LOGS,
224
+ "mflog 'Setting up task environment.'",
225
+ self._get_install_dependencies_cmd(datastore_type),
226
+ "mkdir metaflow",
227
+ "cd metaflow",
228
+ "mkdir .metaflow", # mute local datastore creation log
229
+ "i=0; while [ $i -le 5 ]; do "
230
+ "mflog 'Downloading code package...'; "
231
+ + self._get_download_code_package_cmd(code_package_url, datastore_type)
232
+ + " && mflog 'Code package downloaded.' && break; "
233
+ "sleep 10; i=$((i+1)); "
234
+ "done",
235
+ "if [ $i -gt 5 ]; then "
236
+ "mflog 'Failed to download code package from %s "
237
+ "after 6 tries. Exiting...' && exit 1; "
238
+ "fi" % code_package_url,
239
+ ]
240
+ + MetaflowPackage.get_extract_commands(
241
+ code_package_metadata, "job.tar", dest_dir="."
242
+ )
243
+ + extra_exports
244
+ + [
245
+ "mflog 'Task is starting.'",
246
+ "flush_mflogs",
247
+ ]
248
+ )
183
249
  return cmds
184
250
 
185
251
  def get_environment_info(self, include_ext_info=False):
@@ -2,6 +2,24 @@ import time
2
2
 
3
3
  from contextlib import contextmanager
4
4
 
5
+ from .metaflow_config import PROFILE_FROM_START
6
+
7
+ init_time = None
8
+
9
+
10
+ if PROFILE_FROM_START:
11
+
12
+ def from_start(msg: str):
13
+ global init_time
14
+ if init_time is None:
15
+ init_time = time.time()
16
+ print("From start: %s took %dms" % (msg, int((time.time() - init_time) * 1000)))
17
+
18
+ else:
19
+
20
+ def from_start(_msg: str):
21
+ pass
22
+
5
23
 
6
24
  @contextmanager
7
25
  def profile(label, stats_dict=None):
@@ -11,7 +11,7 @@ import subprocess
11
11
  from os import path, name, environ, listdir
12
12
 
13
13
  from metaflow.extension_support import update_package_info
14
- from metaflow.info_file import CURRENT_DIRECTORY, read_info_file
14
+ from metaflow.meta_files import read_info_file
15
15
 
16
16
 
17
17
  # True/False correspond to the value `public`` in get_version
@@ -133,6 +133,16 @@ def read_info_version():
133
133
  return None
134
134
 
135
135
 
136
+ def make_public_version(version_string):
137
+ """
138
+ Takes a complex version string and returns a public, PEP 440-compliant version.
139
+ It removes local version identifiers (+...) and development markers (-...).
140
+ """
141
+ base_version = version_string.split("+", 1)[0]
142
+ public_version = base_version.split("-", 1)[0]
143
+ return public_version
144
+
145
+
136
146
  def get_version(public=False):
137
147
  """Tracks the version number.
138
148
 
@@ -170,6 +180,11 @@ def get_version(public=False):
170
180
  ) # Version info is cached in INFO file; includes extension info
171
181
 
172
182
  if version:
183
+ # If we have a version from the INFO file, use it directly.
184
+ # However, if we are asked for a public version, we parse it to make sure
185
+ # that no local information is included.
186
+ if public:
187
+ version = make_public_version(version)
173
188
  _version_cache[public] = version
174
189
  return version
175
190