modal 1.0.2.dev7__py3-none-any.whl → 1.0.3__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

modal/volume.py CHANGED
@@ -45,7 +45,6 @@ from ._utils.blob_utils import (
45
45
  BLOCK_SIZE,
46
46
  FileUploadSpec,
47
47
  FileUploadSpec2,
48
- blob_iter,
49
48
  blob_upload_file,
50
49
  get_file_upload_spec_from_fileobj,
51
50
  get_file_upload_spec_from_path,
@@ -69,6 +68,8 @@ class FileEntryType(enum.IntEnum):
69
68
  FILE = 1
70
69
  DIRECTORY = 2
71
70
  SYMLINK = 3
71
+ FIFO = 4
72
+ SOCKET = 5
72
73
 
73
74
 
74
75
  @dataclass(frozen=True)
@@ -398,7 +399,7 @@ class _Volume(_Object, type_prefix="vo"):
398
399
  return [entry async for entry in self.iterdir(path, recursive=recursive)]
399
400
 
400
401
  @live_method_gen
401
- def read_file(self, path: str) -> AsyncIterator[bytes]:
402
+ async def read_file(self, path: str) -> AsyncIterator[bytes]:
402
403
  """
403
404
  Read a file from the modal.Volume.
404
405
 
@@ -412,23 +413,6 @@ class _Volume(_Object, type_prefix="vo"):
412
413
  print(len(data)) # == 1024 * 1024
413
414
  ```
414
415
  """
415
- return self._read_file1(path) if self._is_v1 else self._read_file2(path)
416
-
417
- async def _read_file1(self, path: str) -> AsyncIterator[bytes]:
418
- req = api_pb2.VolumeGetFileRequest(volume_id=self.object_id, path=path)
419
- try:
420
- response = await retry_transient_errors(self._client.stub.VolumeGetFile, req)
421
- except GRPCError as exc:
422
- raise FileNotFoundError(exc.message) if exc.status == Status.NOT_FOUND else exc
423
- # TODO(Jonathon): use ranged requests.
424
- if response.WhichOneof("data_oneof") == "data":
425
- yield response.data
426
- return
427
- else:
428
- async for data in blob_iter(response.data_blob_id, self._client.stub):
429
- yield data
430
-
431
- async def _read_file2(self, path: str) -> AsyncIterator[bytes]:
432
416
  req = api_pb2.VolumeGetFile2Request(volume_id=self.object_id, path=path)
433
417
 
434
418
  try:
@@ -459,36 +443,9 @@ class _Volume(_Object, type_prefix="vo"):
459
443
  Read volume file into file-like IO object.
460
444
  """
461
445
  if progress_cb is None:
462
-
463
446
  def progress_cb(*_, **__):
464
447
  pass
465
448
 
466
- if self._is_v1:
467
- return await self._read_file_into_fileobj1(path, fileobj, progress_cb)
468
- else:
469
- return await self._read_file_into_fileobj2(path, fileobj, progress_cb)
470
-
471
- async def _read_file_into_fileobj1(
472
- self, path: str, fileobj: typing.IO[bytes], progress_cb: Callable[..., Any]
473
- ) -> int:
474
- num_bytes_written = 0
475
-
476
- async for chunk in self._read_file1(path):
477
- num_chunk_bytes_written = 0
478
-
479
- while num_chunk_bytes_written < len(chunk):
480
- # TODO(dflemstr): this is a small write, but nonetheless might block the event loop for some time:
481
- n = fileobj.write(chunk)
482
- num_chunk_bytes_written += n
483
- progress_cb(advance=n)
484
-
485
- num_bytes_written += len(chunk)
486
-
487
- return num_bytes_written
488
-
489
- async def _read_file_into_fileobj2(
490
- self, path: str, fileobj: typing.IO[bytes], progress_cb: Callable[..., Any]
491
- ) -> int:
492
449
  req = api_pb2.VolumeGetFile2Request(volume_id=self.object_id, path=path)
493
450
 
494
451
  try:
@@ -541,7 +498,7 @@ class _Volume(_Object, type_prefix="vo"):
541
498
  await retry_transient_errors(self._client.stub.VolumeRemoveFile2, req)
542
499
 
543
500
  @live_method
544
- async def copy_files(self, src_paths: Sequence[str], dst_path: str) -> None:
501
+ async def copy_files(self, src_paths: Sequence[str], dst_path: str, recursive: bool = False) -> None:
545
502
  """
546
503
  Copy files within the volume from src_paths to dst_path.
547
504
  The semantics of the copy operation follow those of the UNIX cp command.
@@ -565,8 +522,19 @@ class _Volume(_Object, type_prefix="vo"):
565
522
  like `os.rename()` and then `commit()` the volume. The `copy_files()` method is useful when you don't have
566
523
  the volume mounted as a filesystem, e.g. when running a script on your local computer.
567
524
  """
568
- request = api_pb2.VolumeCopyFilesRequest(volume_id=self.object_id, src_paths=src_paths, dst_path=dst_path)
569
- await retry_transient_errors(self._client.stub.VolumeCopyFiles, request, base_delay=1)
525
+ if self._is_v1:
526
+ if recursive:
527
+ raise ValueError("`recursive` is not supported for V1 volumes")
528
+
529
+ request = api_pb2.VolumeCopyFilesRequest(
530
+ volume_id=self.object_id, src_paths=src_paths, dst_path=dst_path, recursive=recursive
531
+ )
532
+ await retry_transient_errors(self._client.stub.VolumeCopyFiles, request, base_delay=1)
533
+ else:
534
+ request = api_pb2.VolumeCopyFiles2Request(
535
+ volume_id=self.object_id, src_paths=src_paths, dst_path=dst_path, recursive=recursive
536
+ )
537
+ await retry_transient_errors(self._client.stub.VolumeCopyFiles2, request, base_delay=1)
570
538
 
571
539
  @live_method
572
540
  async def batch_upload(self, force: bool = False) -> "_AbstractVolumeUploadContextManager":
modal/volume.pyi CHANGED
@@ -20,6 +20,8 @@ class FileEntryType(enum.IntEnum):
20
20
  FILE = 1
21
21
  DIRECTORY = 2
22
22
  SYMLINK = 3
23
+ FIFO = 4
24
+ SOCKET = 5
23
25
 
24
26
  class FileEntry:
25
27
  path: str
@@ -85,22 +87,16 @@ class _Volume(modal._object._Object):
85
87
  def iterdir(self, path: str, *, recursive: bool = True) -> collections.abc.AsyncIterator[FileEntry]: ...
86
88
  async def listdir(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
87
89
  def read_file(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
88
- def _read_file1(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
89
- def _read_file2(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
90
90
  async def read_file_into_fileobj(
91
91
  self,
92
92
  path: str,
93
93
  fileobj: typing.IO[bytes],
94
94
  progress_cb: typing.Optional[collections.abc.Callable[..., typing.Any]] = None,
95
95
  ) -> int: ...
96
- async def _read_file_into_fileobj1(
97
- self, path: str, fileobj: typing.IO[bytes], progress_cb: collections.abc.Callable[..., typing.Any]
98
- ) -> int: ...
99
- async def _read_file_into_fileobj2(
100
- self, path: str, fileobj: typing.IO[bytes], progress_cb: collections.abc.Callable[..., typing.Any]
101
- ) -> int: ...
102
96
  async def remove_file(self, path: str, recursive: bool = False) -> None: ...
103
- async def copy_files(self, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
97
+ async def copy_files(
98
+ self, src_paths: collections.abc.Sequence[str], dst_path: str, recursive: bool = False
99
+ ) -> None: ...
104
100
  async def batch_upload(self, force: bool = False) -> _AbstractVolumeUploadContextManager: ...
105
101
  async def _instance_delete(self): ...
106
102
  @staticmethod
@@ -234,18 +230,6 @@ class Volume(modal.object.Object):
234
230
 
235
231
  read_file: __read_file_spec[typing_extensions.Self]
236
232
 
237
- class ___read_file1_spec(typing_extensions.Protocol[SUPERSELF]):
238
- def __call__(self, /, path: str) -> typing.Iterator[bytes]: ...
239
- def aio(self, /, path: str) -> collections.abc.AsyncIterator[bytes]: ...
240
-
241
- _read_file1: ___read_file1_spec[typing_extensions.Self]
242
-
243
- class ___read_file2_spec(typing_extensions.Protocol[SUPERSELF]):
244
- def __call__(self, /, path: str) -> typing.Iterator[bytes]: ...
245
- def aio(self, /, path: str) -> collections.abc.AsyncIterator[bytes]: ...
246
-
247
- _read_file2: ___read_file2_spec[typing_extensions.Self]
248
-
249
233
  class __read_file_into_fileobj_spec(typing_extensions.Protocol[SUPERSELF]):
250
234
  def __call__(
251
235
  self,
@@ -264,26 +248,6 @@ class Volume(modal.object.Object):
264
248
 
265
249
  read_file_into_fileobj: __read_file_into_fileobj_spec[typing_extensions.Self]
266
250
 
267
- class ___read_file_into_fileobj1_spec(typing_extensions.Protocol[SUPERSELF]):
268
- def __call__(
269
- self, /, path: str, fileobj: typing.IO[bytes], progress_cb: collections.abc.Callable[..., typing.Any]
270
- ) -> int: ...
271
- async def aio(
272
- self, /, path: str, fileobj: typing.IO[bytes], progress_cb: collections.abc.Callable[..., typing.Any]
273
- ) -> int: ...
274
-
275
- _read_file_into_fileobj1: ___read_file_into_fileobj1_spec[typing_extensions.Self]
276
-
277
- class ___read_file_into_fileobj2_spec(typing_extensions.Protocol[SUPERSELF]):
278
- def __call__(
279
- self, /, path: str, fileobj: typing.IO[bytes], progress_cb: collections.abc.Callable[..., typing.Any]
280
- ) -> int: ...
281
- async def aio(
282
- self, /, path: str, fileobj: typing.IO[bytes], progress_cb: collections.abc.Callable[..., typing.Any]
283
- ) -> int: ...
284
-
285
- _read_file_into_fileobj2: ___read_file_into_fileobj2_spec[typing_extensions.Self]
286
-
287
251
  class __remove_file_spec(typing_extensions.Protocol[SUPERSELF]):
288
252
  def __call__(self, /, path: str, recursive: bool = False) -> None: ...
289
253
  async def aio(self, /, path: str, recursive: bool = False) -> None: ...
@@ -291,8 +255,12 @@ class Volume(modal.object.Object):
291
255
  remove_file: __remove_file_spec[typing_extensions.Self]
292
256
 
293
257
  class __copy_files_spec(typing_extensions.Protocol[SUPERSELF]):
294
- def __call__(self, /, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
295
- async def aio(self, /, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
258
+ def __call__(
259
+ self, /, src_paths: collections.abc.Sequence[str], dst_path: str, recursive: bool = False
260
+ ) -> None: ...
261
+ async def aio(
262
+ self, /, src_paths: collections.abc.Sequence[str], dst_path: str, recursive: bool = False
263
+ ) -> None: ...
296
264
 
297
265
  copy_files: __copy_files_spec[typing_extensions.Self]
298
266
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.0.2.dev7
3
+ Version: 1.0.3
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -22,7 +22,7 @@ Requires-Dist: click~=8.1.0
22
22
  Requires-Dist: grpclib==0.4.7
23
23
  Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
24
24
  Requires-Dist: rich>=12.0.0
25
- Requires-Dist: synchronicity~=0.9.12
25
+ Requires-Dist: synchronicity~=0.9.13
26
26
  Requires-Dist: toml
27
27
  Requires-Dist: typer>=0.9
28
28
  Requires-Dist: types-certifi
@@ -3,7 +3,7 @@ modal/__main__.py,sha256=sTJcc9EbDuCKSwg3tL6ZckFw9WWdlkXW8mId1IvJCNc,2846
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=2aWxN2v5WUnj-R-sk6BzJ-3AvggkQGQjwhtvbDH3pds,777
5
5
  modal/_container_entrypoint.py,sha256=2Zx9O_EMJg0H77EdnC2vGKs6uFMWwbP1NLFf-qYmWmU,28962
6
- modal/_functions.py,sha256=f8MhqxCzqBSUfrR_5uo60p1UHwNmPi_oEdZKDkFv2yw,78874
6
+ modal/_functions.py,sha256=4UDJaBh5S0A24V5-whnzQGamXxGbKZAk2HWc7jH3rAY,78955
7
7
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
8
8
  modal/_location.py,sha256=joiX-0ZeutEUDTrrqLF1GHXCdVLF-rHzstocbMcd_-k,366
9
9
  modal/_object.py,sha256=KzzzZoM41UQUiY9TKOrft9BtZKgjWG_ukdlyLGjB4UY,10758
@@ -22,7 +22,7 @@ modal/app.py,sha256=NZ_rJ9TuMfiNiLg8-gOFgufD5flGtXWPHOZI0gdD3hE,46585
22
22
  modal/app.pyi,sha256=4-b_vbe3lNAqQPcMRpQCEDsE1zsVkQRJGUql9B7HvbM,22659
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=OwISJvkgMb-rHm9Gc4i-7YcDgGiZgwJ7F_PzwZH7a6Q,16847
25
- modal/client.pyi,sha256=IFHVoiQH4U-2TuDXrc8PryTzufS663548yLTM6QNvhQ,8457
25
+ modal/client.pyi,sha256=084gq1YD_ML9sRSbshMSkKWSVlu1p6IALJLeXmvXTQ8,8381
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=30T3K1a89l6wzmEJ_J9iWv9SknoGqaZDx59Xs-ZQcmk,1607
28
28
  modal/cls.py,sha256=dBbeARwOWftlKd1cwtM0cHFtQWSWkwVXwVmOV4w0SyI,37907
@@ -41,18 +41,18 @@ modal/file_pattern_matcher.py,sha256=wov-otB5M1oTdrYDtR2_VgacYin2srdtAP4McA1Cqzw
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
42
  modal/functions.pyi,sha256=iqdp5ixtOOlm8bF-QYbD_G8VKqSRt_AVLT7AWjpn6pQ,16236
43
43
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
44
- modal/image.py,sha256=-ia4ELkIh4sxOSqdYETAPV8EEb58Nue6DLdAxhM2C_Y,92687
44
+ modal/image.py,sha256=yrI9DCw7GAck3d788GCHJom-_yU55zNu7reNapBhlgE,93284
45
45
  modal/image.pyi,sha256=2xjB6XOZDtm_chDdd90UoIj8pnDt5hCg6bOmu5fNaA4,25625
46
46
  modal/io_streams.py,sha256=YDZVQSDv05DeXg5TwcucC9Rj5hQBx2GXdluan9rIUpw,15467
47
47
  modal/io_streams.pyi,sha256=1UK6kWLREASQfq-wL9wSp5iqjLU0egRZPDn4LXs1PZY,5136
48
- modal/mount.py,sha256=HbpGQbqqT5pTP4dh8j6USWXb2Fr1ro3V1uHIardkya4,30726
49
- modal/mount.pyi,sha256=_qDhjR8Xg0ArdCw0JCivhhLCQO-Q-n_RlG5Ct4yJBQ0,12528
48
+ modal/mount.py,sha256=HbSN-45SWLB7MvIeGcBDKa5nP0Z3wFyKIRX-B37Epw4,34637
49
+ modal/mount.pyi,sha256=h4yzzppRKvD3JuTTjm9hE2Ye_aUKueTV09F5I_Regjg,13364
50
50
  modal/network_file_system.py,sha256=lgtmHYjzA5gDMx0tysH0-WJB2Ao9JD2W15NyYK2A7_w,14612
51
51
  modal/network_file_system.pyi,sha256=58DiUqHGlARmI3cz-Yo7IFObKKFIiGh5UIU5JxGNFfc,8333
52
52
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
53
53
  modal/object.pyi,sha256=UkR8NQ1jCIaw3hBUPxBRc6vvrOqtV37G_hsW2O5-4wE,5378
54
54
  modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
55
- modal/parallel_map.py,sha256=zU2zL8_9PmmNC9Ny2GB7K2_HbAdPU7RiVLN0GtzaDls,35923
55
+ modal/parallel_map.py,sha256=zlJTh3NuqlrmxkcZMSXerM2dKytYX3Pr737vBLr9AX4,37428
56
56
  modal/parallel_map.pyi,sha256=mhYGQmufQEJbjNrX7vNhBS2gUdfBrpmuWNUHth_Dz6U,6140
57
57
  modal/partial_function.py,sha256=SwuAAj2wj4SO6F6nkSnwNZrczEmm9w9YdlQTHh6hr04,1195
58
58
  modal/partial_function.pyi,sha256=NFWz1aCAs2B3-GnPf1cTatWRZOLnYpFKCnjP_X9iNRs,6411
@@ -62,12 +62,12 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
62
62
  modal/queue.py,sha256=lu-QYW8GTqhZgX0TPTndmltT9uIWgLFV5mKZ_yTfmd4,18829
63
63
  modal/queue.pyi,sha256=O0f0S5kM1P0GVgzUzgsN0XsI46B9cJem4kkWluFndjM,10632
64
64
  modal/retries.py,sha256=IvNLDM0f_GLUDD5VgEDoN09C88yoxSrCquinAuxT1Sc,5205
65
- modal/runner.py,sha256=nvpnU7U2O5d2WqME1QUTTwu-NkSLLwblytlGk7HXPAw,24152
65
+ modal/runner.py,sha256=VV-PC03waAdSc_tAwpVN427TelOgs-cKeYS2GFeVRuA,24029
66
66
  modal/runner.pyi,sha256=1AnEu48SUPnLWp3raQ2zJCV5lc85EGLkX2nL0bHWaB0,5162
67
67
  modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
68
- modal/sandbox.py,sha256=zUldeCA98GLObLT1N9v1IILomcPYeLrQJRCRUMTtbLE,35734
69
- modal/sandbox.pyi,sha256=stxwoLcyQNToPISj6umlU8sDUgqzeooLdMs3BwIr740,28195
70
- modal/schedule.py,sha256=ewa7hb9NKYnoeSCW2PujZAbGGJL8btX6X3KalCFpc_M,2626
68
+ modal/sandbox.py,sha256=6Ki2aBANqqN7THC1U7ymzJEUN7bPRqixAX9TBFh05Mc,36250
69
+ modal/sandbox.pyi,sha256=KvIYfLIvWdTEbuu0oWoS2I_8UiT6HU2hNsEaS7AjFR4,28688
70
+ modal/schedule.py,sha256=SdH8jk6S0zoc1bTRVblrVw0zBsNwPlSC2gNpVxMet9g,3061
71
71
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
72
72
  modal/secret.py,sha256=I2z-rgKWl_Ix107d2_Y2OWGXdFOuJ7zMOyDfIOdFI1A,10374
73
73
  modal/secret.pyi,sha256=NY_dz0UjiYyn4u4LaBZwPP3Ji7SlTLpEyzrYK2sj9HQ,3103
@@ -78,22 +78,22 @@ modal/snapshot.pyi,sha256=dIEBdTPb7O3VwkQ8TMPjfyU17RLuS9i0DnACxxHy8X4,676
78
78
  modal/stream_type.py,sha256=A6320qoAAWhEfwOCZfGtymQTu5AfLfJXXgARqooTPvY,417
79
79
  modal/token_flow.py,sha256=0_4KabXKsuE4OXTJ1OuLOtA-b1sesShztMZkkRFK7tA,7605
80
80
  modal/token_flow.pyi,sha256=ILbRv6JsZq-jK8jcJM7eB74e0PsbzwBm7hyPcV9lBlQ,2121
81
- modal/volume.py,sha256=LO8hYt2y0BOXsWzjMUUfOhSxBs7eILgTP5Lvi0IRjxM,44092
82
- modal/volume.pyi,sha256=fM1RRKz521eIzM3Cd7osAhQ3UQEboQEjXWLQKerjSzY,21117
81
+ modal/volume.py,sha256=KOucCFS5uBTJ5IDUNYhBZfpAYp7U36YynpCdyyEmzpU,42825
82
+ modal/volume.pyi,sha256=Os4MESmmUPkLF5jOW6nbrozMILDh6Uzb1VB_nLm-pLQ,19242
83
83
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
84
84
  modal/_runtime/asgi.py,sha256=_2xSTsDD27Cit7xnMs4lzkJA2wzer2_N4Oa3BkXFzVA,22521
85
- modal/_runtime/container_io_manager.py,sha256=6j0jO2-s9ShckM4SK45OapoQxWW9HQwQjFaBkXPJPwU,44763
85
+ modal/_runtime/container_io_manager.py,sha256=qKYtd52I0JAmiw1Wfy_EQXHuHsbmt-XwLqKDLBhWrZc,44289
86
86
  modal/_runtime/container_io_manager.pyi,sha256=OKvrccBxawjF0PHZuN5eXeh266fS7qZH8yAIG0P02cY,16349
87
87
  modal/_runtime/execution_context.py,sha256=73Y5zH_o-MhVCrkJXakYVlFkKqCa2CWvqoHjOfJrJGg,3034
88
88
  modal/_runtime/execution_context.pyi,sha256=AlRGyocfQlb4UpEuI_VmRRtvaBTbhjgyKSRFUePi8J0,667
89
- modal/_runtime/gpu_memory_snapshot.py,sha256=tA3m1d1cwnmHpvpCeN_WijDd6n8byn7LWlpicbIxiOI,3144
89
+ modal/_runtime/gpu_memory_snapshot.py,sha256=HXgqPHQj0LARhmie_h62V95L-M2R1Kg21INUm_IStn8,7574
90
90
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
91
91
  modal/_runtime/user_code_imports.py,sha256=78wJyleqY2RVibqcpbDQyfWVBVT9BjyHPeoV9WdwV5Y,17720
92
92
  modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
93
93
  modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
94
94
  modal/_utils/async_utils.py,sha256=zjdtdA54zvNL_RuREmN5NWFhhiRcNh8z0jT2rBc5RgY,28001
95
95
  modal/_utils/blob_utils.py,sha256=IexC2Jbtqp_Tkmy62ayfgzTYte0UPCNufB_v-DO21g8,18585
96
- modal/_utils/bytes_io_segment_payload.py,sha256=DT4roLCafjexASGyM1lPOR0HlwOYLA9UQqlxzTgUttE,3614
96
+ modal/_utils/bytes_io_segment_payload.py,sha256=vaXPq8b52-x6G2hwE7SrjS58pg_aRm7gV3bn3yjmTzQ,4261
97
97
  modal/_utils/deprecation.py,sha256=EXP1beU4pmEqEzWMLw6E3kUfNfpmNA_VOp6i0EHi93g,4856
98
98
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
99
99
  modal/_utils/function_utils.py,sha256=bhrjyOHPPXm6fAyJx3bzI1Yh56j6xh8eeMSFKdAWrHQ,26978
@@ -130,15 +130,15 @@ modal/cli/launch.py,sha256=0_sBu6bv2xJEPWi-rbGS6Ri9ggnkWQvrGlgpYSUBMyY,3097
130
130
  modal/cli/network_file_system.py,sha256=DoIdY8I42DjFdTtaYuRKNm7GC6vY0QtA4mk6694fbuU,7983
131
131
  modal/cli/profile.py,sha256=0TYhgRSGUvQZ5LH9nkl6iZllEvAjDniES264dE57wOM,3201
132
132
  modal/cli/queues.py,sha256=1OzC9HdCkbNz6twF3US4FZmIhuVRQ01GOfBY42ux61A,4533
133
- modal/cli/run.py,sha256=DPa-yQ9o7vjqwvs_TAOvVJxS51yVn__ZGCnbkORL37g,23972
134
- modal/cli/secret.py,sha256=oLFEPZoyyeMUKPaJZ9JKKl5mfkQU80DGF9p0atotqig,5002
133
+ modal/cli/run.py,sha256=vB4Qc0w9-8778Kme038DPxpFLLVAGo_KcJ7403ikMJY,24325
134
+ modal/cli/secret.py,sha256=2bngl3Gb6THXkQ2eWZIN9pOHeOFJqiSNo_waUCVYgns,6611
135
135
  modal/cli/token.py,sha256=mxSgOWakXG6N71hQb1ko61XAR9ZGkTMZD-Txn7gmTac,1924
136
136
  modal/cli/utils.py,sha256=9Q7DIUX78-c19zBQNA7EtkgqIFatvHWUVGHwUIeBX_0,3366
137
- modal/cli/volume.py,sha256=_QYbB52LLD3Q8eKHFn7bW3Xu0il5A4UkwjjU63hKjEQ,10534
137
+ modal/cli/volume.py,sha256=W7i4zJyHSPmvP4e4CEv739KpoDCmFO3aIXxPQuuetXg,10840
138
138
  modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
139
139
  modal/cli/programs/run_jupyter.py,sha256=44Lpvqk2l3hH-uOkmAOzw60NEsfB5uaRDWDKVshvQhs,2682
140
140
  modal/cli/programs/vscode.py,sha256=KbTAaIXyQBVCDXxXjmBHmKpgXkUw0q4R4KkJvUjCYgk,3380
141
- modal/experimental/__init__.py,sha256=GYWLyYHpO0xWxo1s-uP5ZuD8IBFKbhCUAke3kq3jv_4,8272
141
+ modal/experimental/__init__.py,sha256=qO5CqJNSIqSRD5WaoN8l1D-qZ7HRSrGzg85BH6hroiI,8410
142
142
  modal/experimental/ipython.py,sha256=epLUZeDSdE226TH_tU3igRKCiVuQi99mUOrIJ4SemOE,2792
143
143
  modal/requirements/2023.12.312.txt,sha256=zWWUVgVQ92GXBKNYYr2-5vn9rlnXcmkqlwlX5u1eTYw,400
144
144
  modal/requirements/2023.12.txt,sha256=OjsbXFkCSdkzzryZP82Q73osr5wxQ6EUzmGcK7twfkA,502
@@ -147,7 +147,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
147
147
  modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
148
148
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
149
149
  modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
150
- modal-1.0.2.dev7.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
150
+ modal-1.0.3.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
151
151
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
152
152
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
153
153
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -155,10 +155,10 @@ modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,2
155
155
  modal_docs/mdmd/mdmd.py,sha256=Irx49MCCTlBOP4FBdLR--JrpA3-WhsVeriq0LGgsRic,6232
156
156
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
157
157
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
158
- modal_proto/api.proto,sha256=TZU4O7rl6_3p0kPhwtCFpUzF2ev7nogfT_dJia1q0YA,95957
158
+ modal_proto/api.proto,sha256=W-cvTWRT5LWw6FvfZUWGORQMEkUV4hqBpmbDD24N3C4,96314
159
159
  modal_proto/api_grpc.py,sha256=iY5o_Tm4VDP-Wa1JgA_NpQa_Y-4FYB_RN9wdSUExjwI,117469
160
- modal_proto/api_pb2.py,sha256=05O5ZucslpXNOq5JMbC8HkqYl4YNJt_h6fqHQuK9yXw,338105
161
- modal_proto/api_pb2.pyi,sha256=u-YdDR8e6cjSSID-wRuCUeOiEZuhVP9XNY_pTlrC820,462457
160
+ modal_proto/api_pb2.py,sha256=C0eUCmX2r7X7UgXkNkK30zA8GqQE9JgzShaJz_eay8Q,338564
161
+ modal_proto/api_pb2.pyi,sha256=51bFLZW74Cy5F4wEm36ZXHKfFht-cfB4RCre4WWAteo,463616
162
162
  modal_proto/api_pb2_grpc.py,sha256=NL5prOS_hh_pA1hVvQP_ZRE1w49N-PR8iNPRZ65i6nA,254089
163
163
  modal_proto/api_pb2_grpc.pyi,sha256=Xxgdcnv1mBnu5_AQxJ6fo0yz7GnqVU0HVObNfZWHVfM,59440
164
164
  modal_proto/modal_api_grpc.py,sha256=0ir2lnwT3-IgPcAWw98yWMAiqZPkjvNro9UBk4u8hnk,17763
@@ -170,10 +170,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
170
170
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
171
171
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
172
172
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
- modal_version/__init__.py,sha256=LrqnzPGRtSa2NTB6joxhCn57VhaIcPxD3pO9FGvf-1o,120
173
+ modal_version/__init__.py,sha256=k3og2Mm-mpLO-xy6Qtp2TAi9VSyvTMAr-BbqP-95ElQ,115
174
174
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
175
- modal-1.0.2.dev7.dist-info/METADATA,sha256=LL0K520dCRhZwQOf3adi1EvRvswmmg3DU3hG9Bz6SR4,2454
176
- modal-1.0.2.dev7.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
- modal-1.0.2.dev7.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
- modal-1.0.2.dev7.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
- modal-1.0.2.dev7.dist-info/RECORD,,
175
+ modal-1.0.3.dist-info/METADATA,sha256=SwaTzgYATN6jHCHsmIhIw9-iOLROjVu3TI7bJ8iFZvY,2449
176
+ modal-1.0.3.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
177
+ modal-1.0.3.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
178
+ modal-1.0.3.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
179
+ modal-1.0.3.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -253,6 +253,11 @@ enum TaskState {
253
253
  TASK_STATE_LOADING_CHECKPOINT_IMAGE = 11;
254
254
  }
255
255
 
256
+ enum TunnelType {
257
+ TUNNEL_TYPE_UNSPECIFIED = 0;
258
+ TUNNEL_TYPE_H2 = 1; // HTTP/2 tunnel
259
+ }
260
+
256
261
  enum VolumeFsVersion {
257
262
  VOLUME_FS_VERSION_UNSPECIFIED = 0;
258
263
  VOLUME_FS_VERSION_V1 = 1;
@@ -1216,6 +1221,8 @@ message FileEntry {
1216
1221
  FILE = 1;
1217
1222
  DIRECTORY = 2;
1218
1223
  SYMLINK = 3;
1224
+ FIFO = 4;
1225
+ SOCKET = 5;
1219
1226
  }
1220
1227
  string path = 1;
1221
1228
  FileType type = 2;
@@ -1945,13 +1952,21 @@ message ImageJoinStreamingResponse {
1945
1952
  message ImageMetadata {
1946
1953
  // The output of `python -VV. Not set if missing
1947
1954
  optional string python_version_info = 1;
1955
+
1948
1956
  // Installed python packages, as listed by by `pip list`.
1949
1957
  // package name -> version. Empty if missing
1950
1958
  map<string, string> python_packages = 2;
1951
- // The work directory of the image, defaulting to "/". Not set if missing
1959
+
1960
+ // The working directory of the image, as an absolute file path.
1961
+ //
1962
+ // For most images, this is not set, which means to use the default workdir:
1963
+ // - On function runners, the default is `/root` (home directory).
1964
+ // - For image builds and sandbox environments, it is `/`.
1952
1965
  optional string workdir = 3;
1953
- // The image's libc version
1966
+
1967
+ // The version of glibc in this image, if any.
1954
1968
  optional string libc_version_info = 4;
1969
+
1955
1970
  // The builder version for/with which the image was created.
1956
1971
  optional string image_builder_version = 5;
1957
1972
  }
@@ -2153,7 +2168,7 @@ message PTYInfo {
2153
2168
  message PortSpec {
2154
2169
  uint32 port = 1;
2155
2170
  bool unencrypted = 2;
2156
- optional string tunnel_type = 3;
2171
+ optional TunnelType tunnel_type = 3;
2157
2172
  }
2158
2173
 
2159
2174
  message PortSpecs {
@@ -2878,7 +2893,7 @@ message TunnelData {
2878
2893
  message TunnelStartRequest {
2879
2894
  uint32 port = 1;
2880
2895
  bool unencrypted = 2;
2881
- optional string tunnel_type = 3;
2896
+ optional TunnelType tunnel_type = 3;
2882
2897
  }
2883
2898
 
2884
2899
  message TunnelStartResponse {