metaflow 2.15.17__py2.py3-none-any.whl → 2.15.18__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/cli.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import functools
2
2
  import inspect
3
+ import os
3
4
  import sys
4
5
  import traceback
5
6
  from datetime import datetime
@@ -242,6 +243,14 @@ def version(obj):
242
243
  type=click.Choice(["local"] + [m.TYPE for m in ENVIRONMENTS]),
243
244
  help="Execution environment type",
244
245
  )
246
+ @click.option(
247
+ "--force-rebuild-environments/--no-force-rebuild-environments",
248
+ is_flag=True,
249
+ default=False,
250
+ hidden=True,
251
+ type=bool,
252
+ help="Explicitly rebuild the execution environments",
253
+ )
245
254
  # See comment for --quiet
246
255
  @click.option(
247
256
  "--datastore",
@@ -300,6 +309,7 @@ def start(
300
309
  quiet=False,
301
310
  metadata=None,
302
311
  environment=None,
312
+ force_rebuild_environments=False,
303
313
  datastore=None,
304
314
  datastore_root=None,
305
315
  decospecs=None,
@@ -435,6 +445,8 @@ def start(
435
445
  ctx.obj.environment = [
436
446
  e for e in ENVIRONMENTS + [MetaflowEnvironment] if e.TYPE == environment
437
447
  ][0](ctx.obj.flow)
448
+ # set force rebuild flag for environments that support it.
449
+ ctx.obj.environment._force_rebuild = force_rebuild_environments
438
450
  ctx.obj.environment.validate_environment(ctx.obj.logger, datastore)
439
451
 
440
452
  ctx.obj.event_logger = LOGGING_SIDECARS[event_logger](
@@ -214,8 +214,6 @@ CARD_GSROOT = from_conf(
214
214
  )
215
215
  CARD_NO_WARNING = from_conf("CARD_NO_WARNING", False)
216
216
 
217
- SKIP_CARD_DUALWRITE = from_conf("SKIP_CARD_DUALWRITE", False)
218
-
219
217
  RUNTIME_CARD_RENDER_INTERVAL = from_conf("RUNTIME_CARD_RENDER_INTERVAL", 60)
220
218
 
221
219
  # Azure storage account URL
@@ -16,7 +16,6 @@ from metaflow.metaflow_config import (
16
16
  CARD_SUFFIX,
17
17
  CARD_AZUREROOT,
18
18
  CARD_GSROOT,
19
- SKIP_CARD_DUALWRITE,
20
19
  )
21
20
  import metaflow.metaflow_config as metaflow_config
22
21
 
@@ -231,23 +230,6 @@ class CardDatastore(object):
231
230
 
232
231
  def save_card(self, uuid, card_type, card_html, card_id=None, overwrite=True):
233
232
  card_file_name = card_type
234
- # TEMPORARY_WORKAROUND: FIXME (LATER) : Fix the duplication of below block in a few months.
235
- # Check file blame to understand the age of this temporary workaround.
236
-
237
- # This function will end up saving cards at two locations.
238
- # Thereby doubling the number of cards. (Which is a temporary fix)
239
- # Why do this ? :
240
- # When cards were introduced there was an assumption made about task-ids being unique.
241
- # This assumption was incorrect.
242
- # Only the pathspec needs to be unique but there is no such guarantees about task-ids.
243
- # When task-ids are non-unique, card read would result in finding incorrect cards.
244
- # This happens because cards were stored based on task-ids.
245
- # If we immediately switch from storing based on task-ids to a step-name abstraction folder,
246
- # then card reading will crash for many users.
247
- # It would especially happen for users who are accessing cards created by a newer
248
- # MF client from an older version of MF client.
249
- # It will also easily end up breaking the metaflow-ui (which maybe using a client from an older version).
250
- # Hence, we are writing cards to both paths so that we can introduce breaking changes later in the future.
251
233
  card_path_with_steps = self.get_card_location(
252
234
  self._get_card_write_path(),
253
235
  card_file_name,
@@ -255,24 +237,10 @@ class CardDatastore(object):
255
237
  card_id=card_id,
256
238
  suffix=CardNameSuffix.CARD,
257
239
  )
258
- if SKIP_CARD_DUALWRITE:
259
- self._backend.save_bytes(
260
- [(card_path_with_steps, BytesIO(bytes(card_html, "utf-8")))],
261
- overwrite=overwrite,
262
- )
263
- else:
264
- card_path_without_steps = self.get_card_location(
265
- self._get_card_read_path(with_steps=False),
266
- card_file_name,
267
- uuid,
268
- card_id=card_id,
269
- suffix=CardNameSuffix.CARD,
270
- )
271
- for cp in [card_path_with_steps, card_path_without_steps]:
272
- self._backend.save_bytes(
273
- [(cp, BytesIO(bytes(card_html, "utf-8")))], overwrite=overwrite
274
- )
275
-
240
+ self._backend.save_bytes(
241
+ [(card_path_with_steps, BytesIO(bytes(card_html, "utf-8")))],
242
+ overwrite=overwrite,
243
+ )
276
244
  return self.info_from_path(card_path_with_steps, suffix=CardNameSuffix.CARD)
277
245
 
278
246
  def _list_card_paths(self, card_type=None, card_hash=None, card_id=None):
@@ -283,6 +251,10 @@ class CardDatastore(object):
283
251
  )
284
252
 
285
253
  if len(card_paths_with_steps) == 0:
254
+ # The listing logic is reading the cards with steps and without steps
255
+ # because earlier versions of clients (ones that wrote cards before June 2022),
256
+ # would have written cards without steps. So as a fallback we will try to check for the
257
+ # cards without steps.
286
258
  card_paths_without_steps = self._backend.list_content(
287
259
  [self._get_card_read_path(with_steps=False)]
288
260
  )
@@ -32,6 +32,7 @@ class CondaEnvironmentException(MetaflowException):
32
32
  class CondaEnvironment(MetaflowEnvironment):
33
33
  TYPE = "conda"
34
34
  _filecache = None
35
+ _force_rebuild = False
35
36
 
36
37
  def __init__(self, flow):
37
38
  self.flow = flow
@@ -71,7 +72,7 @@ class CondaEnvironment(MetaflowEnvironment):
71
72
  self.logger = make_thread_safe(logger)
72
73
 
73
74
  # TODO: Wire up logging
74
- micromamba = Micromamba(self.logger)
75
+ micromamba = Micromamba(self.logger, self._force_rebuild)
75
76
  self.solvers = {"conda": micromamba, "pypi": Pip(micromamba, self.logger)}
76
77
 
77
78
  def init_environment(self, echo, only_steps=None):
@@ -107,7 +108,10 @@ class CondaEnvironment(MetaflowEnvironment):
107
108
  return (
108
109
  id_,
109
110
  (
110
- self.read_from_environment_manifest([id_, platform, type_])
111
+ (
112
+ not self._force_rebuild
113
+ and self.read_from_environment_manifest([id_, platform, type_])
114
+ )
111
115
  or self.write_to_environment_manifest(
112
116
  [id_, platform, type_],
113
117
  self.solvers[type_].solve(id_, **environment),
@@ -153,7 +157,7 @@ class CondaEnvironment(MetaflowEnvironment):
153
157
  _meta = copy.deepcopy(local_packages)
154
158
  for id_, packages, _, _ in results:
155
159
  for package in packages:
156
- if package.get("path"):
160
+ if package.get("path") and not self._force_rebuild:
157
161
  # Cache only those packages that manifest is unaware of
158
162
  local_packages.pop(package["url"], None)
159
163
  else:
@@ -186,7 +190,7 @@ class CondaEnvironment(MetaflowEnvironment):
186
190
  storage.save_bytes(
187
191
  list_of_path_and_filehandle,
188
192
  len_hint=len(list_of_path_and_filehandle),
189
- # overwrite=True,
193
+ overwrite=self._force_rebuild,
190
194
  )
191
195
  for id_, packages, _, platform in results:
192
196
  if id_ in dirty:
@@ -2,6 +2,7 @@ import functools
2
2
  import json
3
3
  import os
4
4
  import re
5
+ import shutil
5
6
  import subprocess
6
7
  import tempfile
7
8
  import time
@@ -30,7 +31,7 @@ _double_equal_match = re.compile("==(?=[<=>!~])")
30
31
 
31
32
 
32
33
  class Micromamba(object):
33
- def __init__(self, logger=None):
34
+ def __init__(self, logger=None, force_rebuild=False):
34
35
  # micromamba is a tiny version of the mamba package manager and comes with
35
36
  # metaflow specific performance enhancements.
36
37
 
@@ -60,6 +61,8 @@ class Micromamba(object):
60
61
  # which causes a race condition in case micromamba needs to be installed first.
61
62
  self.install_mutex = Lock()
62
63
 
64
+ self.force_rebuild = force_rebuild
65
+
63
66
  @property
64
67
  def bin(self) -> str:
65
68
  "Defer installing Micromamba until when the binary path is actually requested"
@@ -152,6 +155,11 @@ class Micromamba(object):
152
155
  keyword="metaflow", # indicates metaflow generated environment
153
156
  id=id_,
154
157
  )
158
+ # If we are forcing a rebuild of the environment, we make sure to remove existing files beforehand.
159
+ # This is to ensure that no irrelevant packages get bundled relative to the resolved environment.
160
+ # NOTE: download always happens before create, so we want to do the cleanup here instead.
161
+ if self.force_rebuild:
162
+ shutil.rmtree(self.path_to_environment(id_, platform), ignore_errors=True)
155
163
 
156
164
  # cheap check
157
165
  if os.path.exists(f"{prefix}/fake.done"):
metaflow/version.py CHANGED
@@ -1 +1 @@
1
- metaflow_version = "2.15.17"
1
+ metaflow_version = "2.15.18"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metaflow
3
- Version: 2.15.17
3
+ Version: 2.15.18
4
4
  Summary: Metaflow: More AI and ML, Less Engineering
5
5
  Author: Metaflow Developers
6
6
  Author-email: help@metaflow.org
@@ -26,7 +26,7 @@ License-File: LICENSE
26
26
  Requires-Dist: requests
27
27
  Requires-Dist: boto3
28
28
  Provides-Extra: stubs
29
- Requires-Dist: metaflow-stubs==2.15.17; extra == "stubs"
29
+ Requires-Dist: metaflow-stubs==2.15.18; extra == "stubs"
30
30
  Dynamic: author
31
31
  Dynamic: author-email
32
32
  Dynamic: classifier
@@ -1,7 +1,7 @@
1
1
  metaflow/R.py,sha256=CqVfIatvmjciuICNnoyyNGrwE7Va9iXfLdFbQa52hwA,3958
2
2
  metaflow/__init__.py,sha256=aCCgR992PUA5Urd-pb06c1afjKbfaNPDWnH8kKQRnNk,5937
3
3
  metaflow/cards.py,sha256=IbRmredvmFEU0V6JL7DR8wCESwVmmZJubr6x24bo7U4,442
4
- metaflow/cli.py,sha256=5nqEJf0R9MDdJUpIUpOxbc2dovyw_3HlbJqXmHYVCjc,21323
4
+ metaflow/cli.py,sha256=ype7221pgVp3sFXTT4YpLmEx0yLahYD9UuHizLCbIT0,21714
5
5
  metaflow/cli_args.py,sha256=hDsdWdRmfXYifVGq6b6FDfgoWxtIG2nr_lU6EBV0Pnk,3584
6
6
  metaflow/clone_util.py,sha256=LSuVbFpPUh92UW32DBcnZbL0FFw-4w3CLa0tpEbCkzk,2066
7
7
  metaflow/cmd_with_io.py,sha256=kl53HkAIyv0ecpItv08wZYczv7u3msD1VCcciqigqf0,588
@@ -16,7 +16,7 @@ metaflow/includefile.py,sha256=RtISGl1V48qjkJBakUZ9yPpHV102h7pOIFiKP8PLHpc,20927
16
16
  metaflow/info_file.py,sha256=wtf2_F0M6dgiUu74AFImM8lfy5RrUw5Yj7Rgs2swKRY,686
17
17
  metaflow/integrations.py,sha256=LlsaoePRg03DjENnmLxZDYto3NwWc9z_PtU6nJxLldg,1480
18
18
  metaflow/lint.py,sha256=x4p6tnRzYqNNniCGXyrUW0WuYfTUgnaOMRivxvnxask,11661
19
- metaflow/metaflow_config.py,sha256=wrWSdPV6pAWFHo0Ao6uMnK2_zCaTD3S8-CYvxC5onPo,24045
19
+ metaflow/metaflow_config.py,sha256=wVREyuJvQ8EyWDhkQ8c_A11dh1CcIA5HFjohp7CEsHE,23982
20
20
  metaflow/metaflow_config_funcs.py,sha256=5GlvoafV6SxykwfL8D12WXSfwjBN_NsyuKE_Q3gjGVE,6738
21
21
  metaflow/metaflow_current.py,sha256=pfkXmkyHeMJhxIs6HBJNBEaBDpcl5kz9Wx5mW6F_3qo,7164
22
22
  metaflow/metaflow_environment.py,sha256=CWG90qpfz9iJ6hHhFlAmMVNALn2v_5eTVk3mFbQR4Pw,8379
@@ -37,7 +37,7 @@ metaflow/tuple_util.py,sha256=_G5YIEhuugwJ_f6rrZoelMFak3DqAR2tt_5CapS1XTY,830
37
37
  metaflow/unbounded_foreach.py,sha256=p184WMbrMJ3xKYHwewj27ZhRUsSj_kw1jlye5gA9xJk,387
38
38
  metaflow/util.py,sha256=MCXCjcGwpuR7y9euBf1GTNRHPtlh6fCpdPMEtbULefw,14554
39
39
  metaflow/vendor.py,sha256=EDZokNMrx1PU07jNMiWFMFtC7TL03pMXZ1kKn13k-2g,5139
40
- metaflow/version.py,sha256=NkuKBUnu2oRi4r7ARbML2YLGujb0iUN9knslDNptHkM,29
40
+ metaflow/version.py,sha256=aFD_zYUJd11BSUf4DN7nX_rYimfrx-sNGZXun2I_e-g,29
41
41
  metaflow/_vendor/__init__.py,sha256=y_CiwUD3l4eAKvTVDZeqgVujMy31cAM1qjAB-HfI-9s,353
42
42
  metaflow/_vendor/typing_extensions.py,sha256=q9zxWa6p6CzF1zZvSkygSlklduHf_b3K7MCxGz7MJRc,134519
43
43
  metaflow/_vendor/zipp.py,sha256=ajztOH-9I7KA_4wqDYygtHa6xUBVZgFpmZ8FE74HHHI,8425
@@ -248,7 +248,7 @@ metaflow/plugins/cards/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3
248
248
  metaflow/plugins/cards/card_cli.py,sha256=XyiU5f6i_xjFHPyowWGs9mKQm9fm3dK6id-IKsoe9cY,35177
249
249
  metaflow/plugins/cards/card_client.py,sha256=30dFBoC3axc261GeV7QCIs_V1OHhRtS31S0wEWsjw90,9501
250
250
  metaflow/plugins/cards/card_creator.py,sha256=vRz1EUFa4xQ1fUIWzqyACViC6D7KGFaq5XlLIEssXTI,7741
251
- metaflow/plugins/cards/card_datastore.py,sha256=3K19wE0CZVvOpuYUytftIYYnHHn3pMZJE87FMD6OYlM,14244
251
+ metaflow/plugins/cards/card_datastore.py,sha256=bPLjBFWNlAgIjONAb0IjYXMmp9vMYlh3EYhRjAlDA0U,12714
252
252
  metaflow/plugins/cards/card_decorator.py,sha256=nU-uZ4_ubU7bCsSb6uT61YnN8ruo43_FzqZ24MsZpKg,12070
253
253
  metaflow/plugins/cards/card_resolver.py,sha256=bjyujYpGUFbLJNwXNGHlHhL4f-gVdVKebl7XW1vWDtE,717
254
254
  metaflow/plugins/cards/card_server.py,sha256=DHv0RcepaPULWbkDahiEMrU5A281Cfb0DvHLUYd8JsU,11772
@@ -327,8 +327,8 @@ metaflow/plugins/metadata_providers/service.py,sha256=5UlK0R5M9_nq2J6MgJgCZwqAC3
327
327
  metaflow/plugins/pypi/__init__.py,sha256=0YFZpXvX7HCkyBFglatual7XGifdA1RwC3U4kcizyak,1037
328
328
  metaflow/plugins/pypi/bootstrap.py,sha256=NaQboUVNJc90gmUa69-cK_T3G7piHNNsUSaN96IJoic,14745
329
329
  metaflow/plugins/pypi/conda_decorator.py,sha256=N0HGiaS1mRsa6qT4eYzu2C3DHtas22QIXowW4vEl44M,15961
330
- metaflow/plugins/pypi/conda_environment.py,sha256=C7WolJm1dgBQofd6vOk8KCr3U754TyAr4bOpkhosxfM,24582
331
- metaflow/plugins/pypi/micromamba.py,sha256=XAuZulI7O2Q_Zgtx28yjAqHco6tHiPQxoy_vsf1kWm8,16843
330
+ metaflow/plugins/pypi/conda_environment.py,sha256=6QgHphwgXBob_C_ObpKL-4i2R7dN3XPn0ddlPCzu5tc,24771
331
+ metaflow/plugins/pypi/micromamba.py,sha256=UltfY8NmLphfZ-AbpaMFIdxIeOXLdTYDrMrabvPrYVU,17352
332
332
  metaflow/plugins/pypi/parsers.py,sha256=gpOOG2Ph95wI73MWCAi7XjpK0gYhv5k5YIGBs73QPuE,8556
333
333
  metaflow/plugins/pypi/pip.py,sha256=WhPyA18RoVT40sqbZRJdCEij4euL9PZwLfm1SrAKqmU,14333
334
334
  metaflow/plugins/pypi/pypi_decorator.py,sha256=ybNgo-T5Z_0W2KNuED0pdjyI0qygZ4a1MXAzKqdHt_E,7250
@@ -389,12 +389,12 @@ metaflow/user_configs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
389
389
  metaflow/user_configs/config_decorators.py,sha256=n4OTbfuaXejPVLHnXXgVlNJNcrSvWrVOdXCMcqvQlik,20512
390
390
  metaflow/user_configs/config_options.py,sha256=yyaiKLB4QWlR5AaTg9I7GoBv-OlffOFdGPe1BL85Llc,21241
391
391
  metaflow/user_configs/config_parameters.py,sha256=Eyiqcz4YV_z4algDHAh2gaejGFgIdHk8Vix9AUdPSh0,20989
392
- metaflow-2.15.17.data/data/share/metaflow/devtools/Makefile,sha256=5n89OGIC_kE4wxtEI66VCucN-b-1w5bqvGeZYmeRGz8,13737
393
- metaflow-2.15.17.data/data/share/metaflow/devtools/Tiltfile,sha256=P5_rn_F3xYLN1_cEAQ9mNeS22HG2rb8beKIz2RIK6fU,20634
394
- metaflow-2.15.17.data/data/share/metaflow/devtools/pick_services.sh,sha256=DCnrMXwtApfx3B4S-YiZESMyAFHbXa3VuNL0MxPLyiE,2196
395
- metaflow-2.15.17.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
396
- metaflow-2.15.17.dist-info/METADATA,sha256=7DfiQK2zg33YgaYjF6Oc5hEHfRgf7js9w-22xvqojFE,6742
397
- metaflow-2.15.17.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
398
- metaflow-2.15.17.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
399
- metaflow-2.15.17.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
400
- metaflow-2.15.17.dist-info/RECORD,,
392
+ metaflow-2.15.18.data/data/share/metaflow/devtools/Makefile,sha256=5n89OGIC_kE4wxtEI66VCucN-b-1w5bqvGeZYmeRGz8,13737
393
+ metaflow-2.15.18.data/data/share/metaflow/devtools/Tiltfile,sha256=P5_rn_F3xYLN1_cEAQ9mNeS22HG2rb8beKIz2RIK6fU,20634
394
+ metaflow-2.15.18.data/data/share/metaflow/devtools/pick_services.sh,sha256=DCnrMXwtApfx3B4S-YiZESMyAFHbXa3VuNL0MxPLyiE,2196
395
+ metaflow-2.15.18.dist-info/licenses/LICENSE,sha256=nl_Lt5v9VvJ-5lWJDT4ddKAG-VZ-2IaLmbzpgYDz2hU,11343
396
+ metaflow-2.15.18.dist-info/METADATA,sha256=SNMazx7rUE5-fmaqxAv1-7KxPXKDAojZyRqLBCzLZEo,6742
397
+ metaflow-2.15.18.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
398
+ metaflow-2.15.18.dist-info/entry_points.txt,sha256=RvEq8VFlgGe_FfqGOZi0D7ze1hLD0pAtXeNyGfzc_Yc,103
399
+ metaflow-2.15.18.dist-info/top_level.txt,sha256=v1pDHoWaSaKeuc5fKTRSfsXCKSdW1zvNVmvA-i0if3o,9
400
+ metaflow-2.15.18.dist-info/RECORD,,