modAL 1.4.3.dev4__py3-none-any.whl → 1.4.3.dev6__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.
modal/client.pyi CHANGED
@@ -35,7 +35,7 @@ class _Client:
35
35
  server_url: str,
36
36
  client_type: int,
37
37
  credentials: typing.Optional[tuple[str, str]],
38
- version: str = "1.4.3.dev4",
38
+ version: str = "1.4.3.dev6",
39
39
  ):
40
40
  """mdmd:hidden
41
41
  The Modal client object is not intended to be instantiated directly by users.
@@ -175,7 +175,7 @@ class Client:
175
175
  server_url: str,
176
176
  client_type: int,
177
177
  credentials: typing.Optional[tuple[str, str]],
178
- version: str = "1.4.3.dev4",
178
+ version: str = "1.4.3.dev6",
179
179
  ):
180
180
  """mdmd:hidden
181
181
  The Modal client object is not intended to be instantiated directly by users.
modal/exception.py CHANGED
@@ -90,7 +90,7 @@ class _GRPCErrorWrapper(grpclib.GRPCError):
90
90
  def __repr__(self) -> str:
91
91
  return f"{type(self).__name__}({self._message!r})"
92
92
 
93
- def _warn_on_grpc_error_attribute_access(self) -> None:
93
+ def _attribute_warning(self) -> None:
94
94
  from ._utils.deprecation import deprecation_warning # Avoid circular import
95
95
 
96
96
  exc_type = type(self).__name__
@@ -104,7 +104,7 @@ class _GRPCErrorWrapper(grpclib.GRPCError):
104
104
 
105
105
  @property
106
106
  def message(self) -> str:
107
- self._warn_on_grpc_error_attribute_access()
107
+ self._attribute_warning()
108
108
  return self._grpc_message
109
109
 
110
110
  @message.setter
@@ -113,7 +113,7 @@ class _GRPCErrorWrapper(grpclib.GRPCError):
113
113
 
114
114
  @property
115
115
  def status(self) -> grpclib.Status:
116
- self._warn_on_grpc_error_attribute_access()
116
+ self._attribute_warning()
117
117
  return self._grpc_status
118
118
 
119
119
  @status.setter
@@ -122,7 +122,7 @@ class _GRPCErrorWrapper(grpclib.GRPCError):
122
122
 
123
123
  @property
124
124
  def details(self) -> Any:
125
- self._warn_on_grpc_error_attribute_access()
125
+ self._attribute_warning()
126
126
  return self._grpc_details
127
127
 
128
128
  @details.setter
modal/sandbox.py CHANGED
@@ -268,22 +268,28 @@ class _Sandbox(_Object, type_prefix="sb"):
268
268
  if pty:
269
269
  pty_info = _Sandbox._default_pty_info()
270
270
 
271
- def _deps() -> list[_Object]:
272
- deps: list[_Object] = [image] + list(mounts) + list(secrets)
271
+ async def _load(
272
+ self: _Sandbox, resolver: Resolver, load_context: LoadContext, _existing_object_id: Optional[str]
273
+ ):
274
+ # An already-hydrated image (e.g. one returned by
275
+ # `Sandbox.snapshot_directory`) is skipped — there's nothing to load.
276
+ dep_tasks: list = []
277
+ if not image._is_hydrated:
278
+ dep_tasks.append(resolver.load(image, load_context))
279
+ for dep in list(mounts) + list(secrets):
280
+ dep_tasks.append(resolver.load(dep, load_context))
273
281
  for _, vol in validated_network_file_systems:
274
- deps.append(vol)
282
+ dep_tasks.append(resolver.load(vol, load_context))
275
283
  for _, vol in validated_volumes:
276
- deps.append(vol)
284
+ dep_tasks.append(resolver.load(vol, load_context))
277
285
  for _, cloud_bucket_mount in cloud_bucket_mounts:
278
286
  if cloud_bucket_mount.secret:
279
- deps.append(cloud_bucket_mount.secret)
287
+ dep_tasks.append(resolver.load(cloud_bucket_mount.secret, load_context))
280
288
  if proxy:
281
- deps.append(proxy)
282
- return deps
289
+ dep_tasks.append(resolver.load(proxy, load_context))
290
+ if dep_tasks:
291
+ await asyncio.gather(*dep_tasks)
283
292
 
284
- async def _load(
285
- self: _Sandbox, resolver: Resolver, load_context: LoadContext, _existing_object_id: Optional[str]
286
- ):
287
293
  # Validate that the same volume (by object_id) isn't mounted at multiple paths
288
294
  validate_volumes_by_object_id(validated_volumes)
289
295
 
@@ -363,7 +369,7 @@ class _Sandbox(_Object, type_prefix="sb"):
363
369
  sandbox_id = create_resp.sandbox_id
364
370
  self._hydrate(sandbox_id, load_context.client, None)
365
371
 
366
- return _Sandbox._from_loader(_load, "Sandbox()", deps=_deps, load_context_overrides=LoadContext.empty())
372
+ return _Sandbox._from_loader(_load, "Sandbox()", load_context_overrides=LoadContext.empty())
367
373
 
368
374
  @staticmethod
369
375
  async def create(
@@ -689,12 +695,17 @@ class _Sandbox(_Object, type_prefix="sb"):
689
695
  allowed_cidrs=cidr_allowlist,
690
696
  )
691
697
 
692
- def _deps() -> list[_Object]:
693
- return [image] + list(secrets)
694
-
695
698
  async def _load(
696
699
  self: _Sandbox, resolver: Resolver, load_context: LoadContext, _existing_object_id: Optional[str]
697
700
  ):
701
+ dep_tasks: list = []
702
+ if not image._is_hydrated:
703
+ dep_tasks.append(resolver.load(image, load_context))
704
+ for secret in secrets:
705
+ dep_tasks.append(resolver.load(secret, load_context))
706
+ if dep_tasks:
707
+ await asyncio.gather(*dep_tasks)
708
+
698
709
  definition = api_pb2.Sandbox(
699
710
  entrypoint_args=args,
700
711
  image_id=image.object_id,
@@ -732,7 +743,7 @@ class _Sandbox(_Object, type_prefix="sb"):
732
743
  for t in create_resp.tunnels
733
744
  }
734
745
 
735
- obj = _Sandbox._from_loader(_load, "Sandbox()", deps=_deps, load_context_overrides=LoadContext.empty())
746
+ obj = _Sandbox._from_loader(_load, "Sandbox()", load_context_overrides=LoadContext.empty())
736
747
 
737
748
  app_id: Optional[str] = None
738
749
  app_client: Optional[_Client] = None
@@ -906,19 +917,7 @@ class _Sandbox(_Object, type_prefix="sb"):
906
917
  if resp.result.status != api_pb2.GenericResult.GENERIC_STATUS_SUCCESS:
907
918
  raise ExecutionError(resp.result.exception)
908
919
 
909
- image_id = resp.image_id
910
- metadata = resp.image_metadata
911
-
912
- async def _load(self: _Image, resolver: Resolver, load_context: LoadContext, existing_object_id: Optional[str]):
913
- # no need to hydrate again since we do it eagerly below
914
- pass
915
-
916
- rep = "Image()"
917
- # TODO: use ._new_hydrated instead
918
- image = _Image._from_loader(_load, rep, hydrate_lazily=True, load_context_overrides=LoadContext.empty())
919
- image._hydrate(image_id, self._client, metadata) # hydrating eagerly since we have all of the data
920
-
921
- return image
920
+ return _Image._new_hydrated(resp.image_id, self._client, resp.image_metadata)
922
921
 
923
922
  async def mount_image(self, path: Union[PurePosixPath, str], image: _Image):
924
923
  """Mount an Image at a specified path in a running Sandbox.
@@ -1032,7 +1031,8 @@ class _Sandbox(_Object, type_prefix="sb"):
1032
1031
  raise InvalidError(f"Snapshot path must be absolute; got: {posix_path}")
1033
1032
  path_bytes = posix_path.as_posix().encode("utf8")
1034
1033
 
1035
- req = sr_pb2.TaskSnapshotDirectoryRequest(task_id=task_id, path=path_bytes)
1034
+ snapshot_id = str(uuid.uuid4())
1035
+ req = sr_pb2.TaskSnapshotDirectoryRequest(task_id=task_id, path=path_bytes, snapshot_id=snapshot_id)
1036
1036
  res = await command_router_client.snapshot_directory(req)
1037
1037
  return _Image._new_hydrated(res.image_id, self._client, None)
1038
1038
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.4.3.dev4
3
+ Version: 1.4.3.dev6
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License-Expression: Apache-2.0
@@ -26,7 +26,7 @@ modal/app.pyi,sha256=mysbOCD6OjZi938NeMY40RpdpQbnI43Bb4s5P79x5OQ,53773
26
26
  modal/billing.py,sha256=B2zXa7KeMnpqi2AQINycEk-KSXVYaLTTTAQTtuf2Gfs,257
27
27
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
28
28
  modal/client.py,sha256=jjT4eLFHGcvIF6Xw4kPptIx-VmExtphRN8XJ1JA7fWI,15502
29
- modal/client.pyi,sha256=A7qsAY2_5l2qqMZh9KCnN0cOcfl13ORT53PgufFLzAE,15701
29
+ modal/client.pyi,sha256=JmocfYAxcjZxGxINMhP8lx7BvYFLXWVXJbnr8Ibqqw8,15701
30
30
  modal/cloud_bucket_mount.py,sha256=KkaJVy5vpO_u2NtDYtv1JM-M3y4J0UtWBapTDKpQRcA,6034
31
31
  modal/cloud_bucket_mount.pyi,sha256=mGDeEd1XvxGpCE6O5jRBSfIvMXvZ5AtIybea5k-0w9w,7560
32
32
  modal/cls.py,sha256=Yrl5b_tQhZMhc5avInM-i5UlGuqeog6Gs4rX2d9lLjI,40390
@@ -38,7 +38,7 @@ modal/dict.py,sha256=3d7TD9zAAU_vZGFRYIsClBFAHSgJ6i0Z7JJykBjNvO0,23224
38
38
  modal/dict.pyi,sha256=3FgUEzuUDdIw16MlTKpE9GG8CoeBmZ1jnFiIFZunSaU,33803
39
39
  modal/environments.py,sha256=wMiMNpPkvIl_BdxRb81CY9Djzhczp_y4GEYKWp0JyBc,6135
40
40
  modal/environments.pyi,sha256=bMIxvwahckgaolGD3-hP2iovRHDXewvgbVs_nx4ze0o,3808
41
- modal/exception.py,sha256=S96LpZo7-s4er-h6YRgcYhPgCj23CFbMvBEjcXhOv5Q,11749
41
+ modal/exception.py,sha256=LMNcb5gAtIzosJvOxkr8O4RSMtuwRYue-xJI7Cxq1CA,11677
42
42
  modal/file_io.py,sha256=3HcVEXindYuprBIuOPaOlLDMBQtuoaHKjKIYIqh53y0,22256
43
43
  modal/file_io.pyi,sha256=DPaq0BhySaiCX3g56QHhyIMdU1izbfWsjpSp30JoJUU,15745
44
44
  modal/file_pattern_matcher.py,sha256=A_Kdkej6q7YQyhM_2-BvpFmPqJ0oHb54B6yf9VqvPVE,8116
@@ -68,7 +68,7 @@ modal/retries.py,sha256=vPWWKP-FRolJwTBuLPXdWqHV7aJfSQFgEW7vhlBBXRQ,5067
68
68
  modal/runner.py,sha256=yIB1PE5EGdvLWPPymyT4P0KYliREnFf-MAtULl3tVN0,30062
69
69
  modal/runner.pyi,sha256=ySefjmlMQ5FsvJgJkCWiUZKvcPNfEqdB5hwxI1fGtDo,9445
70
70
  modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
71
- modal/sandbox.py,sha256=Oz2KjJYQzthyu7fQs93UYMgDMFiJ5r-6CHkWxXLSDfI,83117
71
+ modal/sandbox.py,sha256=bp8W6xPBUpTIY3h-Y91nbxu_YBzJoRLSyMtvvj3xOhA,83377
72
72
  modal/sandbox.pyi,sha256=p1XMD7EjpLI8FCqyDjEaZHvbTKd6_DycwVq86WJPCZw,86306
73
73
  modal/sandbox_fs.py,sha256=1IN-bn9Ah67AqjUhvPBCJkYdaiTLueUBaj0E3h4tzBY,16757
74
74
  modal/sandbox_fs.pyi,sha256=0rQacbDOgHKQBKIAmVJwrJ6pBsP1BR3WL4QbTJRafhw,27604
@@ -176,7 +176,7 @@ modal/experimental/__init__.py,sha256=Wb1YoAKAnNxH_0c2wA0T12I7bSu9PSO2nS_LuLska7
176
176
  modal/experimental/flash.py,sha256=ATGhVO8AleJ-TOe2PGolI5T7zfCEtj0kl_ivMPp7Rqg,33362
177
177
  modal/experimental/flash.pyi,sha256=R4h2nQl7-oiwqq_twCp0YqID_LnPjPGqxywXvxbiLIk,17011
178
178
  modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
179
- modal-1.4.3.dev4.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
179
+ modal-1.4.3.dev6.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
180
180
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
181
181
  modal_docs/gen_cli_docs.py,sha256=bfUSLscHfoQoKkKjIqJvQMe3fURzqcQK7gF1h9WQLtM,3742
182
182
  modal_docs/gen_cli_docs_main.py,sha256=UPGr7O1DYTIRLwfINe2rbdh89J3cPVTU1OWL-SjxnOQ,198
@@ -187,21 +187,21 @@ modal_docs/mdmd/mdmd.py,sha256=z9T3lMktTq3N4r6T6MSSyw8lebbqKc3Igw8l9EdMJNM,9998
187
187
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
188
188
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
189
189
  modal_proto/api_grpc.py,sha256=H4Z21x81592KlGzgDIcgltk5WixY5vs5EyOH8Q89wvA,153140
190
- modal_proto/api_pb2.py,sha256=6beIxoMkmSpW9BR__3G4tA7vtp1w7VhW0tUcU6WAroo,423763
191
- modal_proto/api_pb2.pyi,sha256=v9IV9qfYwXSf3JVck3K2JK7ACMEhb8lqnlGsx1D3DEU,593027
190
+ modal_proto/api_pb2.py,sha256=P09tScxAvEid1BbXBAxC_N_IZJ7EpjfpFIub-RMgOHU,424105
191
+ modal_proto/api_pb2.pyi,sha256=9G3_MdFKOu-eE44LyV3Kt0c4wWCcTZUKwWoSWs-hlzY,593733
192
192
  modal_proto/api_pb2_grpc.py,sha256=dWnojBtfuaqHvBos1FL-JMNEB7LsNHM1UGUpKXO5IFY,329867
193
193
  modal_proto/api_pb2_grpc.pyi,sha256=qDqqKIs18olWaoBjLOJ8Z6Gn8_GjpNn3Z1Pw1yG_M4I,77024
194
194
  modal_proto/modal_api_grpc.py,sha256=bBPhTehvCriGANMHxXNxKa58ew_2QbSvO88zhKCr4CE,24177
195
195
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
196
196
  modal_proto/task_command_router_grpc.py,sha256=wbRjiCyx9MlvkmPKM_6UVU1KmJaynUO4Eyt6tDKtmRk,12572
197
- modal_proto/task_command_router_pb2.py,sha256=Kadayms1M02hoAtV4hom00t143GAHxUNvohOxTIRaCg,24322
198
- modal_proto/task_command_router_pb2.pyi,sha256=nnMXJQ81eSbgeA0SkBOcUHXiD5hRknYi5MK7wVkPlU0,27068
197
+ modal_proto/task_command_router_pb2.py,sha256=ZrDKDK9Kw2Ks4l9-gWXjUG8nW50pyDY5G-DOwTGfF1U,24363
198
+ modal_proto/task_command_router_pb2.pyi,sha256=qDvQBePeIQZcLmpYgEEiT5-7LnkpWTP9h-Lkzan5LXE,27289
199
199
  modal_proto/task_command_router_pb2_grpc.py,sha256=CW52Dj00YLRRAc2-KIz_aimGe7RuKvx0cROMs2No-b0,25002
200
200
  modal_proto/task_command_router_pb2_grpc.pyi,sha256=j4-VU3QFp8nUyx5_6F04T4IIU28KWHpAFMnY8Eg521g,8018
201
- modal_version/__init__.py,sha256=LrmWEF63LHXk_vLCXJqAVDla1_ZBciOXvSuNVIm3dzE,120
201
+ modal_version/__init__.py,sha256=DR5iSrR--sukzxn73D3siOvgejMcbtx7vHZNHZD4No4,120
202
202
  modal_version/__main__.py,sha256=nLUbubxKx7GXNzJIkTB7M7_u8080LyLM0IS0rzFkC_c,119
203
- modal-1.4.3.dev4.dist-info/METADATA,sha256=tUF2FJz9harPBNYPtksUtI0JwLNX-PF_GntHGa8RKc4,2338
204
- modal-1.4.3.dev4.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
205
- modal-1.4.3.dev4.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
206
- modal-1.4.3.dev4.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
207
- modal-1.4.3.dev4.dist-info/RECORD,,
203
+ modal-1.4.3.dev6.dist-info/METADATA,sha256=ikqFD2Asfy5v_rrqoy0oXBc30X4ivuZTAXTTjvnvHqo,2338
204
+ modal-1.4.3.dev6.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
205
+ modal-1.4.3.dev6.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
206
+ modal-1.4.3.dev6.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
207
+ modal-1.4.3.dev6.dist-info/RECORD,,