modal 0.76.2__py3-none-any.whl → 0.76.4__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/cli/app.py +13 -11
- modal/client.pyi +2 -2
- modal/volume.py +34 -78
- {modal-0.76.2.dist-info → modal-0.76.4.dist-info}/METADATA +1 -1
- {modal-0.76.2.dist-info → modal-0.76.4.dist-info}/RECORD +10 -10
- modal_version/_version_generated.py +1 -1
- {modal-0.76.2.dist-info → modal-0.76.4.dist-info}/WHEEL +0 -0
- {modal-0.76.2.dist-info → modal-0.76.4.dist-info}/entry_points.txt +0 -0
- {modal-0.76.2.dist-info → modal-0.76.4.dist-info}/licenses/LICENSE +0 -0
- {modal-0.76.2.dist-info → modal-0.76.4.dist-info}/top_level.txt +0 -0
modal/cli/app.py
CHANGED
@@ -224,10 +224,10 @@ async def history(
|
|
224
224
|
"Time deployed",
|
225
225
|
"Client",
|
226
226
|
"Deployed by",
|
227
|
+
"Commit",
|
228
|
+
"Tag",
|
227
229
|
]
|
228
230
|
rows = []
|
229
|
-
deployments_with_tags = False
|
230
|
-
deployments_with_commit_info = False
|
231
231
|
deployments_with_dirty_commit = False
|
232
232
|
for idx, app_stats in enumerate(resp.app_deployment_histories):
|
233
233
|
style = "bold green" if idx == 0 else ""
|
@@ -239,24 +239,26 @@ async def history(
|
|
239
239
|
Text(app_stats.deployed_by, style=style),
|
240
240
|
]
|
241
241
|
|
242
|
-
if app_stats.tag:
|
243
|
-
deployments_with_tags = True
|
244
|
-
row.append(Text(app_stats.tag, style=style))
|
245
|
-
|
246
242
|
if app_stats.commit_info.commit_hash:
|
247
|
-
deployments_with_commit_info = True
|
248
243
|
short_hash = app_stats.commit_info.commit_hash[:7]
|
249
244
|
if app_stats.commit_info.dirty:
|
250
245
|
deployments_with_dirty_commit = True
|
251
246
|
short_hash = f"{short_hash}*"
|
252
247
|
row.append(Text(short_hash, style=style))
|
248
|
+
else:
|
249
|
+
row.append(None)
|
250
|
+
|
251
|
+
if app_stats.tag:
|
252
|
+
row.append(Text(app_stats.tag, style=style))
|
253
|
+
else:
|
254
|
+
row.append(None)
|
253
255
|
|
254
256
|
rows.append(row)
|
255
257
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
columns
|
258
|
+
# Suppress tag information when no deployments used one
|
259
|
+
if not any(row[-1] for row in rows):
|
260
|
+
rows = [row[:-1] for row in rows]
|
261
|
+
columns = columns[:-1]
|
260
262
|
|
261
263
|
rows = sorted(rows, key=lambda x: int(str(x[0])[1:]), reverse=True)
|
262
264
|
display_table(columns, rows, json)
|
modal/client.pyi
CHANGED
@@ -27,7 +27,7 @@ class _Client:
|
|
27
27
|
_snapshotted: bool
|
28
28
|
|
29
29
|
def __init__(
|
30
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.76.
|
30
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.76.4"
|
31
31
|
): ...
|
32
32
|
def is_closed(self) -> bool: ...
|
33
33
|
@property
|
@@ -86,7 +86,7 @@ class Client:
|
|
86
86
|
_snapshotted: bool
|
87
87
|
|
88
88
|
def __init__(
|
89
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.76.
|
89
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.76.4"
|
90
90
|
): ...
|
91
91
|
def is_closed(self) -> bool: ...
|
92
92
|
@property
|
modal/volume.py
CHANGED
@@ -194,23 +194,19 @@ class _Volume(_Object, type_prefix="vo"):
|
|
194
194
|
if metadata and isinstance(metadata, api_pb2.VolumeMetadata):
|
195
195
|
self._metadata = metadata
|
196
196
|
else:
|
197
|
-
raise TypeError(
|
198
|
-
"_hydrate_metadata() requires an `api_pb2.VolumeMetadata` to determine volume version"
|
199
|
-
)
|
197
|
+
raise TypeError("_hydrate_metadata() requires an `api_pb2.VolumeMetadata` to determine volume version")
|
200
198
|
|
201
199
|
def _get_metadata(self) -> Optional[Message]:
|
202
200
|
return self._metadata
|
203
201
|
|
204
|
-
|
205
202
|
@property
|
206
203
|
def _is_v1(self) -> bool:
|
207
204
|
return self._metadata.version in [
|
208
205
|
None,
|
209
206
|
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_UNSPECIFIED,
|
210
|
-
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V1
|
207
|
+
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V1,
|
211
208
|
]
|
212
209
|
|
213
|
-
|
214
210
|
@classmethod
|
215
211
|
@asynccontextmanager
|
216
212
|
async def ephemeral(
|
@@ -369,21 +365,17 @@ class _Volume(_Object, type_prefix="vo"):
|
|
369
365
|
file's description. If `recursive` is set to True, list all files and folders under the path
|
370
366
|
recursively.
|
371
367
|
"""
|
372
|
-
from modal_version import major_number, minor_number
|
373
|
-
|
374
|
-
# This allows us to remove the server shim after 0.62 is no longer supported.
|
375
|
-
deprecation = deprecation_warning if (major_number, minor_number) <= (0, 62) else deprecation_error
|
376
368
|
if path.endswith("**"):
|
377
369
|
msg = (
|
378
370
|
"Glob patterns in `volume get` and `Volume.listdir()` are deprecated. "
|
379
371
|
"Please pass recursive=True instead. For the CLI, just remove the glob suffix."
|
380
372
|
)
|
381
|
-
|
373
|
+
deprecation_error(
|
382
374
|
(2024, 4, 23),
|
383
375
|
msg,
|
384
376
|
)
|
385
377
|
elif path.endswith("*"):
|
386
|
-
|
378
|
+
deprecation_error(
|
387
379
|
(2024, 4, 23),
|
388
380
|
(
|
389
381
|
"Glob patterns in `volume get` and `Volume.listdir()` are deprecated. "
|
@@ -423,7 +415,6 @@ class _Volume(_Object, type_prefix="vo"):
|
|
423
415
|
"""
|
424
416
|
return self._read_file1(path) if self._is_v1 else self._read_file2(path)
|
425
417
|
|
426
|
-
|
427
418
|
async def _read_file1(self, path: str) -> AsyncIterator[bytes]:
|
428
419
|
req = api_pb2.VolumeGetFileRequest(volume_id=self.object_id, path=path)
|
429
420
|
try:
|
@@ -438,7 +429,6 @@ class _Volume(_Object, type_prefix="vo"):
|
|
438
429
|
async for data in blob_iter(response.data_blob_id, self._client.stub):
|
439
430
|
yield data
|
440
431
|
|
441
|
-
|
442
432
|
async def _read_file2(self, path: str) -> AsyncIterator[bytes]:
|
443
433
|
req = api_pb2.VolumeGetFile2Request(volume_id=self.object_id, path=path)
|
444
434
|
|
@@ -462,18 +452,15 @@ class _Volume(_Object, type_prefix="vo"):
|
|
462
452
|
async for value in stream:
|
463
453
|
yield value
|
464
454
|
|
465
|
-
|
466
455
|
@live_method
|
467
456
|
async def read_file_into_fileobj(
|
468
|
-
self,
|
469
|
-
path: str,
|
470
|
-
fileobj: typing.IO[bytes],
|
471
|
-
progress_cb: Optional[Callable[..., Any]] = None
|
457
|
+
self, path: str, fileobj: typing.IO[bytes], progress_cb: Optional[Callable[..., Any]] = None
|
472
458
|
) -> int:
|
473
459
|
"""mdmd:hidden
|
474
460
|
Read volume file into file-like IO object.
|
475
461
|
"""
|
476
462
|
if progress_cb is None:
|
463
|
+
|
477
464
|
def progress_cb(*_, **__):
|
478
465
|
pass
|
479
466
|
|
@@ -482,12 +469,8 @@ class _Volume(_Object, type_prefix="vo"):
|
|
482
469
|
else:
|
483
470
|
return await self._read_file_into_fileobj2(path, fileobj, progress_cb)
|
484
471
|
|
485
|
-
|
486
472
|
async def _read_file_into_fileobj1(
|
487
|
-
self,
|
488
|
-
path: str,
|
489
|
-
fileobj: typing.IO[bytes],
|
490
|
-
progress_cb: Callable[..., Any]
|
473
|
+
self, path: str, fileobj: typing.IO[bytes], progress_cb: Callable[..., Any]
|
491
474
|
) -> int:
|
492
475
|
num_bytes_written = 0
|
493
476
|
|
@@ -504,12 +487,8 @@ class _Volume(_Object, type_prefix="vo"):
|
|
504
487
|
|
505
488
|
return num_bytes_written
|
506
489
|
|
507
|
-
|
508
490
|
async def _read_file_into_fileobj2(
|
509
|
-
self,
|
510
|
-
path: str,
|
511
|
-
fileobj: typing.IO[bytes],
|
512
|
-
progress_cb: Callable[..., Any]
|
491
|
+
self, path: str, fileobj: typing.IO[bytes], progress_cb: Callable[..., Any]
|
513
492
|
) -> int:
|
514
493
|
req = api_pb2.VolumeGetFile2Request(volume_id=self.object_id, path=path)
|
515
494
|
|
@@ -552,7 +531,6 @@ class _Volume(_Object, type_prefix="vo"):
|
|
552
531
|
|
553
532
|
return total_size
|
554
533
|
|
555
|
-
|
556
534
|
@live_method
|
557
535
|
async def remove_file(self, path: str, recursive: bool = False) -> None:
|
558
536
|
"""Remove a file or directory from a volume."""
|
@@ -607,13 +585,9 @@ class _Volume(_Object, type_prefix="vo"):
|
|
607
585
|
```
|
608
586
|
"""
|
609
587
|
return _AbstractVolumeUploadContextManager.resolve(
|
610
|
-
self._metadata.version,
|
611
|
-
self.object_id,
|
612
|
-
self._client,
|
613
|
-
force=force
|
588
|
+
self._metadata.version, self.object_id, self._client, force=force
|
614
589
|
)
|
615
590
|
|
616
|
-
|
617
591
|
@live_method
|
618
592
|
async def _instance_delete(self):
|
619
593
|
await retry_transient_errors(
|
@@ -642,30 +616,26 @@ class _Volume(_Object, type_prefix="vo"):
|
|
642
616
|
|
643
617
|
Volume = synchronize_api(_Volume)
|
644
618
|
|
619
|
+
|
645
620
|
# TODO(dflemstr): Find a way to add ABC or AbstractAsyncContextManager superclasses while keeping synchronicity happy.
|
646
621
|
class _AbstractVolumeUploadContextManager:
|
647
|
-
async def __aenter__(self):
|
648
|
-
...
|
649
|
-
|
650
|
-
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
651
|
-
...
|
622
|
+
async def __aenter__(self): ...
|
652
623
|
|
624
|
+
async def __aexit__(self, exc_type, exc_val, exc_tb): ...
|
653
625
|
|
654
626
|
def put_file(
|
655
627
|
self,
|
656
628
|
local_file: Union[Path, str, BinaryIO, BytesIO],
|
657
629
|
remote_path: Union[PurePosixPath, str],
|
658
630
|
mode: Optional[int] = None,
|
659
|
-
):
|
660
|
-
...
|
631
|
+
): ...
|
661
632
|
|
662
633
|
def put_directory(
|
663
634
|
self,
|
664
635
|
local_path: Union[Path, str],
|
665
636
|
remote_path: Union[PurePosixPath, str],
|
666
637
|
recursive: bool = True,
|
667
|
-
):
|
668
|
-
...
|
638
|
+
): ...
|
669
639
|
|
670
640
|
@staticmethod
|
671
641
|
def resolve(
|
@@ -673,13 +643,12 @@ class _AbstractVolumeUploadContextManager:
|
|
673
643
|
object_id: str,
|
674
644
|
client,
|
675
645
|
progress_cb: Optional[Callable[..., Any]] = None,
|
676
|
-
force: bool = False
|
646
|
+
force: bool = False,
|
677
647
|
) -> "_AbstractVolumeUploadContextManager":
|
678
|
-
|
679
648
|
if version in [
|
680
649
|
None,
|
681
650
|
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_UNSPECIFIED,
|
682
|
-
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V1
|
651
|
+
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V1,
|
683
652
|
]:
|
684
653
|
return _VolumeUploadContextManager(object_id, client, progress_cb=progress_cb, force=force)
|
685
654
|
elif version == api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V2:
|
@@ -690,6 +659,7 @@ class _AbstractVolumeUploadContextManager:
|
|
690
659
|
|
691
660
|
AbstractVolumeUploadContextManager = synchronize_api(_AbstractVolumeUploadContextManager)
|
692
661
|
|
662
|
+
|
693
663
|
class _VolumeUploadContextManager(_AbstractVolumeUploadContextManager):
|
694
664
|
"""Context manager for batch-uploading files to a Volume."""
|
695
665
|
|
@@ -845,6 +815,7 @@ VolumeUploadContextManager = synchronize_api(_VolumeUploadContextManager)
|
|
845
815
|
|
846
816
|
_FileUploader2 = Callable[[asyncio.Semaphore], Awaitable[FileUploadSpec2]]
|
847
817
|
|
818
|
+
|
848
819
|
class _VolumeUploadContextManager2(_AbstractVolumeUploadContextManager):
|
849
820
|
"""Context manager for batch-uploading files to a Volume version 2."""
|
850
821
|
|
@@ -898,7 +869,6 @@ class _VolumeUploadContextManager2(_AbstractVolumeUploadContextManager):
|
|
898
869
|
upload_specs = await gen_file_upload_specs()
|
899
870
|
await self._put_file_specs(upload_specs)
|
900
871
|
|
901
|
-
|
902
872
|
def put_file(
|
903
873
|
self,
|
904
874
|
local_file: Union[Path, str, BinaryIO, BytesIO],
|
@@ -918,17 +888,11 @@ class _VolumeUploadContextManager2(_AbstractVolumeUploadContextManager):
|
|
918
888
|
def gen():
|
919
889
|
if isinstance(local_file, str) or isinstance(local_file, Path):
|
920
890
|
yield lambda hash_semaphore: FileUploadSpec2.from_path(
|
921
|
-
local_file,
|
922
|
-
PurePosixPath(remote_path),
|
923
|
-
hash_semaphore,
|
924
|
-
mode
|
891
|
+
local_file, PurePosixPath(remote_path), hash_semaphore, mode
|
925
892
|
)
|
926
893
|
else:
|
927
894
|
yield lambda hash_semaphore: FileUploadSpec2.from_fileobj(
|
928
|
-
local_file,
|
929
|
-
PurePosixPath(remote_path),
|
930
|
-
hash_semaphore,
|
931
|
-
mode or 0o644
|
895
|
+
local_file, PurePosixPath(remote_path), hash_semaphore, mode or 0o644
|
932
896
|
)
|
933
897
|
|
934
898
|
self._uploader_generators.append(gen())
|
@@ -975,16 +939,15 @@ class _VolumeUploadContextManager2(_AbstractVolumeUploadContextManager):
|
|
975
939
|
for file_spec in file_specs:
|
976
940
|
blocks = [
|
977
941
|
api_pb2.VolumePutFiles2Request.Block(
|
978
|
-
contents_sha256=block_sha256,
|
979
|
-
|
980
|
-
|
942
|
+
contents_sha256=block_sha256, put_response=put_responses.get(block_sha256)
|
943
|
+
)
|
944
|
+
for block_sha256 in file_spec.blocks_sha256
|
981
945
|
]
|
982
|
-
files.append(
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
))
|
946
|
+
files.append(
|
947
|
+
api_pb2.VolumePutFiles2Request.File(
|
948
|
+
path=file_spec.path, mode=file_spec.mode, size=file_spec.size, blocks=blocks
|
949
|
+
)
|
950
|
+
)
|
988
951
|
|
989
952
|
request = api_pb2.VolumePutFiles2Request(
|
990
953
|
volume_id=self._volume_id,
|
@@ -1001,11 +964,7 @@ class _VolumeUploadContextManager2(_AbstractVolumeUploadContextManager):
|
|
1001
964
|
break
|
1002
965
|
|
1003
966
|
await _put_missing_blocks(
|
1004
|
-
file_specs,
|
1005
|
-
response.missing_blocks,
|
1006
|
-
put_responses,
|
1007
|
-
self._put_concurrency,
|
1008
|
-
self._progress_cb
|
967
|
+
file_specs, response.missing_blocks, put_responses, self._put_concurrency, self._progress_cb
|
1009
968
|
)
|
1010
969
|
else:
|
1011
970
|
raise RuntimeError("Did not succeed at uploading all files despite supplying all missing blocks")
|
@@ -1023,7 +982,7 @@ async def _put_missing_blocks(
|
|
1023
982
|
missing_blocks: list,
|
1024
983
|
put_responses: dict[bytes, bytes],
|
1025
984
|
put_concurrency: int,
|
1026
|
-
progress_cb: Callable[..., Any]
|
985
|
+
progress_cb: Callable[..., Any],
|
1027
986
|
):
|
1028
987
|
@dataclass
|
1029
988
|
class FileProgress:
|
@@ -1038,7 +997,7 @@ async def _put_missing_blocks(
|
|
1038
997
|
async def put_missing_block(
|
1039
998
|
# TODO(dflemstr): Type is `api_pb2.VolumePutFiles2Response.MissingBlock` but synchronicity gets confused
|
1040
999
|
# by the nested class (?)
|
1041
|
-
missing_block
|
1000
|
+
missing_block,
|
1042
1001
|
) -> (bytes, bytes):
|
1043
1002
|
# Lazily import to keep the eager loading time of this module down
|
1044
1003
|
from ._utils.bytes_io_segment_payload import BytesIOSegmentPayload
|
@@ -1067,8 +1026,8 @@ async def _put_missing_blocks(
|
|
1067
1026
|
block_start,
|
1068
1027
|
block_length,
|
1069
1028
|
# limit chunk size somewhat to not keep event loop busy for too long
|
1070
|
-
chunk_size=256*1024,
|
1071
|
-
progress_report_cb=task_progress_cb
|
1029
|
+
chunk_size=256 * 1024,
|
1030
|
+
progress_report_cb=task_progress_cb,
|
1072
1031
|
)
|
1073
1032
|
|
1074
1033
|
async with ClientSessionRegistry.get_session().put(
|
@@ -1085,10 +1044,7 @@ async def _put_missing_blocks(
|
|
1085
1044
|
|
1086
1045
|
return block_sha256, resp_data
|
1087
1046
|
|
1088
|
-
tasks = [
|
1089
|
-
asyncio.create_task(put_missing_block(missing_block))
|
1090
|
-
for missing_block in missing_blocks
|
1091
|
-
]
|
1047
|
+
tasks = [asyncio.create_task(put_missing_block(missing_block)) for missing_block in missing_blocks]
|
1092
1048
|
for task_result in asyncio.as_completed(tasks):
|
1093
1049
|
digest, resp = await task_result
|
1094
1050
|
put_responses[digest] = resp
|
@@ -22,7 +22,7 @@ modal/app.py,sha256=xojuGZv4LaQwZU5ntj7WbmMjeNuB9Gll8Mzqe2LyiEs,51323
|
|
22
22
|
modal/app.pyi,sha256=zNwR1_2LpmQc9AhemuAeVdk90XNYDw9keOkXAwAATeA,28732
|
23
23
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
24
24
|
modal/client.py,sha256=o-aQThHpvDHUzg_kUafyhWzACViUBhY2WLZ2EitnSHA,16787
|
25
|
-
modal/client.pyi,sha256=
|
25
|
+
modal/client.pyi,sha256=r3nU3OnZUoj5JW9qEMmXoiTZZiCCXrpM5F6lDHh3BtY,8383
|
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=LZMQdFZ06LpbLDbsCJknniU-393Jb44E1lqveLVM8F8,38365
|
@@ -78,7 +78,7 @@ 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=
|
81
|
+
modal/volume.py,sha256=DRmaIYwuRF3h1ZePevdYbHdwFUQRZgK0gaytkEkLAWg,43568
|
82
82
|
modal/volume.pyi,sha256=9hPIMRBzGZycVL8uRfGpjSmNu_pCbkGAOyrnE86bU2Y,21113
|
83
83
|
modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
|
84
84
|
modal/_runtime/asgi.py,sha256=_2xSTsDD27Cit7xnMs4lzkJA2wzer2_N4Oa3BkXFzVA,22521
|
@@ -117,7 +117,7 @@ modal/_vendor/tblib.py,sha256=g1O7QUDd3sDoLd8YPFltkXkih7r_fyZOjgmGuligv3s,9722
|
|
117
117
|
modal/cli/__init__.py,sha256=6FRleWQxBDT19y7OayO4lBOzuL6Bs9r0rLINYYYbHwQ,769
|
118
118
|
modal/cli/_download.py,sha256=tV8JFkncTtQKh85bSguQg6AW5aRRlynf-rvyN7ruigc,4337
|
119
119
|
modal/cli/_traceback.py,sha256=4ywtmFcmPnY3tqb4-3fA061N2tRiM01xs8fSagtkwhE,7293
|
120
|
-
modal/cli/app.py,sha256=
|
120
|
+
modal/cli/app.py,sha256=JH0_sMGMrG0qA9ToY1RztP8MT0QHX5nZpAH02LpNYcs,8432
|
121
121
|
modal/cli/cluster.py,sha256=EBDhkzfOtPSbwknYdYPBGYvRAwl4Gm7OJkD6_zxrcus,3106
|
122
122
|
modal/cli/config.py,sha256=QvFsqO4eUOtI7d_pQAOAyfq_ZitjhPtav3C6GIDQcZM,1680
|
123
123
|
modal/cli/container.py,sha256=FYwEgjf93j4NMorAjGbSV98i1wpebqdAeNU1wfrFp1k,3668
|
@@ -146,7 +146,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
|
|
146
146
|
modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
|
147
147
|
modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
|
148
148
|
modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
|
149
|
-
modal-0.76.
|
149
|
+
modal-0.76.4.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
150
150
|
modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
|
151
151
|
modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
|
152
152
|
modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
|
@@ -171,9 +171,9 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
|
|
171
171
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
172
172
|
modal_version/__init__.py,sha256=u-X2s_2GMkprLryPgSYm4nwqxeDjYDm_2mJ3SGySns4,470
|
173
173
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
174
|
-
modal_version/_version_generated.py,sha256=
|
175
|
-
modal-0.76.
|
176
|
-
modal-0.76.
|
177
|
-
modal-0.76.
|
178
|
-
modal-0.76.
|
179
|
-
modal-0.76.
|
174
|
+
modal_version/_version_generated.py,sha256=7iBCnOznnSgAM0IT8NXFVsQn9fAJbIohVT-badmMAis,148
|
175
|
+
modal-0.76.4.dist-info/METADATA,sha256=fVcPU0QU4KLk1RX4hZOYdZHHBO0WfflaoLEZF2ywcTo,2450
|
176
|
+
modal-0.76.4.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
177
|
+
modal-0.76.4.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
178
|
+
modal-0.76.4.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
|
179
|
+
modal-0.76.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|