modal 0.68.11__py3-none-any.whl → 0.68.12__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/_utils/blob_utils.py +5 -2
- modal/_utils/hash_utils.py +17 -9
- modal/client.pyi +2 -2
- modal/functions.pyi +6 -6
- modal/mount.py +1 -1
- modal/network_file_system.py +4 -1
- modal/volume.py +4 -1
- {modal-0.68.11.dist-info → modal-0.68.12.dist-info}/METADATA +1 -1
- {modal-0.68.11.dist-info → modal-0.68.12.dist-info}/RECORD +14 -14
- modal_version/_version_generated.py +1 -1
- {modal-0.68.11.dist-info → modal-0.68.12.dist-info}/LICENSE +0 -0
- {modal-0.68.11.dist-info → modal-0.68.12.dist-info}/WHEEL +0 -0
- {modal-0.68.11.dist-info → modal-0.68.12.dist-info}/entry_points.txt +0 -0
- {modal-0.68.11.dist-info → modal-0.68.12.dist-info}/top_level.txt +0 -0
modal/_utils/blob_utils.py
CHANGED
@@ -305,9 +305,12 @@ async def blob_upload(payload: bytes, stub: ModalClientModal) -> str:
|
|
305
305
|
|
306
306
|
|
307
307
|
async def blob_upload_file(
|
308
|
-
file_obj: BinaryIO,
|
308
|
+
file_obj: BinaryIO,
|
309
|
+
stub: ModalClientModal,
|
310
|
+
progress_report_cb: Optional[Callable] = None,
|
311
|
+
sha256_hex: Optional[str] = None,
|
309
312
|
) -> str:
|
310
|
-
upload_hashes = get_upload_hashes(file_obj)
|
313
|
+
upload_hashes = get_upload_hashes(file_obj, sha256_hex=sha256_hex)
|
311
314
|
return await _blob_upload(upload_hashes, file_obj, stub, progress_report_cb)
|
312
315
|
|
313
316
|
|
modal/_utils/hash_utils.py
CHANGED
@@ -3,7 +3,7 @@ import base64
|
|
3
3
|
import dataclasses
|
4
4
|
import hashlib
|
5
5
|
import time
|
6
|
-
from typing import BinaryIO, Callable, Union
|
6
|
+
from typing import BinaryIO, Callable, Optional, Union
|
7
7
|
|
8
8
|
from modal.config import logger
|
9
9
|
|
@@ -58,14 +58,22 @@ class UploadHashes:
|
|
58
58
|
sha256_base64: str
|
59
59
|
|
60
60
|
|
61
|
-
def get_upload_hashes(data: Union[bytes, BinaryIO]) -> UploadHashes:
|
61
|
+
def get_upload_hashes(data: Union[bytes, BinaryIO], sha256_hex: Optional[str] = None) -> UploadHashes:
|
62
62
|
t0 = time.monotonic()
|
63
63
|
md5 = hashlib.md5()
|
64
|
-
sha256
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
# If we already have the sha256 digest, do not compute it again
|
65
|
+
if sha256_hex:
|
66
|
+
hashes = UploadHashes(
|
67
|
+
md5_base64=get_md5_base64(data),
|
68
|
+
sha256_base64=base64.b64encode(bytes.fromhex(sha256_hex)).decode("ascii"),
|
69
|
+
)
|
70
|
+
logger.debug("get_upload_hashes took %.3fs (get_md5_base64)", time.monotonic() - t0)
|
71
|
+
else:
|
72
|
+
sha256 = hashlib.sha256()
|
73
|
+
_update([md5.update, sha256.update], data)
|
74
|
+
hashes = UploadHashes(
|
75
|
+
md5_base64=base64.b64encode(md5.digest()).decode("ascii"),
|
76
|
+
sha256_base64=base64.b64encode(sha256.digest()).decode("ascii"),
|
77
|
+
)
|
78
|
+
logger.debug("get_upload_hashes took %.3fs (md5 + sha256)", time.monotonic() - t0)
|
71
79
|
return hashes
|
modal/client.pyi
CHANGED
@@ -26,7 +26,7 @@ class _Client:
|
|
26
26
|
_stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
|
27
27
|
|
28
28
|
def __init__(
|
29
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.
|
29
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.12"
|
30
30
|
): ...
|
31
31
|
def is_closed(self) -> bool: ...
|
32
32
|
@property
|
@@ -81,7 +81,7 @@ class Client:
|
|
81
81
|
_stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
|
82
82
|
|
83
83
|
def __init__(
|
84
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.
|
84
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.12"
|
85
85
|
): ...
|
86
86
|
def is_closed(self) -> bool: ...
|
87
87
|
@property
|
modal/functions.pyi
CHANGED
@@ -456,11 +456,11 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
|
|
456
456
|
|
457
457
|
_call_generator_nowait: ___call_generator_nowait_spec
|
458
458
|
|
459
|
-
class __remote_spec(typing_extensions.Protocol[
|
459
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
460
460
|
def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
|
461
461
|
async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
|
462
462
|
|
463
|
-
remote: __remote_spec[
|
463
|
+
remote: __remote_spec[ReturnType, P]
|
464
464
|
|
465
465
|
class __remote_gen_spec(typing_extensions.Protocol):
|
466
466
|
def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
|
@@ -473,17 +473,17 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
|
|
473
473
|
def _get_obj(self) -> typing.Optional[modal.cls.Obj]: ...
|
474
474
|
def local(self, *args: P.args, **kwargs: P.kwargs) -> OriginalReturnType: ...
|
475
475
|
|
476
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
476
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
477
477
|
def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
|
478
478
|
async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
|
479
479
|
|
480
|
-
_experimental_spawn: ___experimental_spawn_spec[
|
480
|
+
_experimental_spawn: ___experimental_spawn_spec[ReturnType, P]
|
481
481
|
|
482
|
-
class __spawn_spec(typing_extensions.Protocol[
|
482
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
483
483
|
def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
|
484
484
|
async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
|
485
485
|
|
486
|
-
spawn: __spawn_spec[
|
486
|
+
spawn: __spawn_spec[ReturnType, P]
|
487
487
|
|
488
488
|
def get_raw_f(self) -> typing.Callable[..., typing.Any]: ...
|
489
489
|
|
modal/mount.py
CHANGED
@@ -483,7 +483,7 @@ class _Mount(_Object, type_prefix="mo"):
|
|
483
483
|
logger.debug(f"Creating blob file for {file_spec.source_description} ({file_spec.size} bytes)")
|
484
484
|
async with blob_upload_concurrency:
|
485
485
|
with file_spec.source() as fp:
|
486
|
-
blob_id = await blob_upload_file(fp, resolver.client.stub)
|
486
|
+
blob_id = await blob_upload_file(fp, resolver.client.stub, sha256_hex=file_spec.sha256_hex)
|
487
487
|
logger.debug(f"Uploading blob file {file_spec.source_description} as {remote_filename}")
|
488
488
|
request2 = api_pb2.MountPutFileRequest(data_blob_id=blob_id, sha256_hex=file_spec.sha256_hex)
|
489
489
|
else:
|
modal/network_file_system.py
CHANGED
@@ -245,7 +245,10 @@ class _NetworkFileSystem(_Object, type_prefix="sv"):
|
|
245
245
|
if data_size > LARGE_FILE_LIMIT:
|
246
246
|
progress_task_id = progress_cb(name=remote_path, size=data_size)
|
247
247
|
blob_id = await blob_upload_file(
|
248
|
-
fp,
|
248
|
+
fp,
|
249
|
+
self._client.stub,
|
250
|
+
progress_report_cb=functools.partial(progress_cb, progress_task_id),
|
251
|
+
sha256_hex=sha_hash,
|
249
252
|
)
|
250
253
|
req = api_pb2.SharedVolumePutFileRequest(
|
251
254
|
shared_volume_id=self.object_id,
|
modal/volume.py
CHANGED
@@ -632,7 +632,10 @@ class _VolumeUploadContextManager:
|
|
632
632
|
logger.debug(f"Creating blob file for {file_spec.source_description} ({file_spec.size} bytes)")
|
633
633
|
with file_spec.source() as fp:
|
634
634
|
blob_id = await blob_upload_file(
|
635
|
-
fp,
|
635
|
+
fp,
|
636
|
+
self._client.stub,
|
637
|
+
functools.partial(self._progress_cb, progress_task_id),
|
638
|
+
sha256_hex=file_spec.sha256_hex,
|
636
639
|
)
|
637
640
|
logger.debug(f"Uploading blob file {file_spec.source_description} as {remote_filename}")
|
638
641
|
request2 = api_pb2.MountPutFileRequest(data_blob_id=blob_id, sha256_hex=file_spec.sha256_hex)
|
@@ -19,7 +19,7 @@ modal/app.py,sha256=EJ7FUN6rWnSwLJoYJh8nmKg_t-8hdN8_rt0OrkP7JvQ,46084
|
|
19
19
|
modal/app.pyi,sha256=BE5SlR5tRECuc6-e2lUuOknDdov3zxgZ4N0AsLb5ZVQ,25270
|
20
20
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
21
21
|
modal/client.py,sha256=nyPjfromWBeOyurexpFP2QLQNk822RPggMCLyX9j1jA,15247
|
22
|
-
modal/client.pyi,sha256=
|
22
|
+
modal/client.pyi,sha256=VD-3BpaYTB-FpChjzLP7pK04fhyn-i1qkQYPAzqZkVA,7280
|
23
23
|
modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
|
24
24
|
modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
|
25
25
|
modal/cls.py,sha256=ONnrfZ2vPcaY2JuKypPiBA9eTiyg8Qfg-Ull40nn9zs,30956
|
@@ -36,15 +36,15 @@ modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
|
|
36
36
|
modal/file_io.py,sha256=q8s872qf6Ntdw7dPogDlpYbixxGkwCA0BlQn2UUoVhY,14637
|
37
37
|
modal/file_io.pyi,sha256=pfkmJiaBpMCZReE6-KCjYOzB1dVtyYDYokJoYX8ARK4,6932
|
38
38
|
modal/functions.py,sha256=IIdHw0FNOdoMksG1b2zvkn8f-xskhJu07ZvHMey9iq4,67667
|
39
|
-
modal/functions.pyi,sha256=
|
39
|
+
modal/functions.pyi,sha256=bHbJiWW5TbFKKjDn7bSCFvOcUcAjPFqTStS-NAHPSeM,25068
|
40
40
|
modal/gpu.py,sha256=r4rL6uH3UJIQthzYvfWauXNyh01WqCPtKZCmmSX1fd4,6881
|
41
41
|
modal/image.py,sha256=cQ6WP1xHXZT_nY8z3aEFiGwKzrTV0yxi3Ab8JzF91eo,79653
|
42
42
|
modal/image.pyi,sha256=PIKH6JBA4L5TfdJrQu3pm2ykyIITmiP920TpP8cdyQA,24585
|
43
43
|
modal/io_streams.py,sha256=QkQiizKRzd5bnbKQsap31LJgBYlAnj4-XkV_50xPYX0,15079
|
44
44
|
modal/io_streams.pyi,sha256=bCCVSxkMcosYd8O3PQDDwJw7TQ8JEcnYonLJ5t27TQs,4804
|
45
|
-
modal/mount.py,sha256=
|
45
|
+
modal/mount.py,sha256=oRqWXlbHvhmM1PFl1bBLeqvmwRsDReIsSFBKLad36PY,27689
|
46
46
|
modal/mount.pyi,sha256=3e4nkXUeeVmUmOyK8Tiyk_EQlHeWruN3yGJVnmDUVrI,9761
|
47
|
-
modal/network_file_system.py,sha256=
|
47
|
+
modal/network_file_system.py,sha256=kwwQLCJVO086FTiAWSF_jz9BkqijZLpSbEYXpFvS0Ik,14600
|
48
48
|
modal/network_file_system.pyi,sha256=8mHKXuRkxHPazF6ljIW7g4M5aVqLSl6eKUPLgDCug5c,7901
|
49
49
|
modal/object.py,sha256=HZs3N59C6JxlMuPQWJYvrWV1FEEkH9txUovVDorVUbs,9763
|
50
50
|
modal/object.pyi,sha256=MO78H9yFSE5i1gExPEwyyQzLdlshkcGHN1aQ0ylyvq0,8802
|
@@ -73,7 +73,7 @@ modal/serving.pyi,sha256=ncV-9jY_vZYFnGs5ZnMb3ffrX8LmcLdIMHBC56xRbtE,1711
|
|
73
73
|
modal/stream_type.py,sha256=A6320qoAAWhEfwOCZfGtymQTu5AfLfJXXgARqooTPvY,417
|
74
74
|
modal/token_flow.py,sha256=LcgSce_MSQ2p7j55DPwpVRpiAtCDe8GRSEwzO7muNR8,6774
|
75
75
|
modal/token_flow.pyi,sha256=gOYtYujrWt_JFZeiI8EmfahXPx5GCR5Na-VaPQcWgEY,1937
|
76
|
-
modal/volume.py,sha256=
|
76
|
+
modal/volume.py,sha256=q0LfC65Xn2VvdQRJJoJEgwQqJ2xsZNoKmlqByH48hXA,29265
|
77
77
|
modal/volume.pyi,sha256=St0mDiaojfep6Bs4sBbkRJmeacYHF6lh6FKOWGmheHA,11182
|
78
78
|
modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
|
79
79
|
modal/_runtime/asgi.py,sha256=GvuxZqWnIHMIR-Bx5f7toCQlkERaJO8CHjTPNM9IFIw,21537
|
@@ -84,11 +84,11 @@ modal/_runtime/user_code_imports.py,sha256=4fI0F9OIaNOcO_S4Tx2JcnYwZwZq6JdhMAkUz
|
|
84
84
|
modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
|
85
85
|
modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
|
86
86
|
modal/_utils/async_utils.py,sha256=9ubwMkwiDB4gzOYG2jL9j7Fs-5dxHjcifZe3r7JRg-k,25091
|
87
|
-
modal/_utils/blob_utils.py,sha256=
|
87
|
+
modal/_utils/blob_utils.py,sha256=cM0sJI7AKz4p7Jowmv8qZeRjp4GcIlIcs9Q7Px70mao,16671
|
88
88
|
modal/_utils/function_utils.py,sha256=LgcveUUb4XU_dWxtqgK_3ujZBvS3cGVzcDOkljyFZ2w,25066
|
89
89
|
modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
|
90
90
|
modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
|
91
|
-
modal/_utils/hash_utils.py,sha256=
|
91
|
+
modal/_utils/hash_utils.py,sha256=ScayPzDYgHbV-5vcF4pCEdH4jUcjrnov92MgTf869jA,2686
|
92
92
|
modal/_utils/http_utils.py,sha256=VKXYNPJtrSwZ1ttcXVGQUWmn8cLAXiOTv05g2ac3GbU,2179
|
93
93
|
modal/_utils/logger.py,sha256=ePzdudrtx9jJCjuO6-bcL_kwUJfi4AwloUmIiNtqkY0,1330
|
94
94
|
modal/_utils/mount_utils.py,sha256=J-FRZbPQv1i__Tob-FIpbB1oXWpFLAwZiB4OCiJpFG0,3206
|
@@ -161,10 +161,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
|
|
161
161
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
162
162
|
modal_version/__init__.py,sha256=RT6zPoOdFO99u5Wcxxaoir4ZCuPTbQ22cvzFAXl3vUY,470
|
163
163
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
164
|
-
modal_version/_version_generated.py,sha256=
|
165
|
-
modal-0.68.
|
166
|
-
modal-0.68.
|
167
|
-
modal-0.68.
|
168
|
-
modal-0.68.
|
169
|
-
modal-0.68.
|
170
|
-
modal-0.68.
|
164
|
+
modal_version/_version_generated.py,sha256=R9GtP7twzokYDnwjzVq8u1Y8TiPOLXIdXEWet3GXhyQ,149
|
165
|
+
modal-0.68.12.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
166
|
+
modal-0.68.12.dist-info/METADATA,sha256=oTw4NpBJkC0Ks6vgdO3Ui7KUxQoQ3c3rL4lV_SQqZco,2329
|
167
|
+
modal-0.68.12.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
168
|
+
modal-0.68.12.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
169
|
+
modal-0.68.12.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
|
170
|
+
modal-0.68.12.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|