modal 0.67.15__py3-none-any.whl → 0.67.17__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 +18 -4
- modal/client.pyi +2 -2
- modal/sandbox.py +3 -0
- modal/sandbox.pyi +3 -0
- {modal-0.67.15.dist-info → modal-0.67.17.dist-info}/METADATA +1 -1
- {modal-0.67.15.dist-info → modal-0.67.17.dist-info}/RECORD +11 -11
- modal_version/_version_generated.py +1 -1
- {modal-0.67.15.dist-info → modal-0.67.17.dist-info}/LICENSE +0 -0
- {modal-0.67.15.dist-info → modal-0.67.17.dist-info}/WHEEL +0 -0
- {modal-0.67.15.dist-info → modal-0.67.17.dist-info}/entry_points.txt +0 -0
- {modal-0.67.15.dist-info → modal-0.67.17.dist-info}/top_level.txt +0 -0
modal/_utils/blob_utils.py
CHANGED
@@ -5,6 +5,7 @@ import hashlib
|
|
5
5
|
import io
|
6
6
|
import os
|
7
7
|
import platform
|
8
|
+
import time
|
8
9
|
from collections.abc import AsyncIterator
|
9
10
|
from contextlib import AbstractContextManager, contextmanager
|
10
11
|
from pathlib import Path, PurePosixPath
|
@@ -289,11 +290,18 @@ async def _blob_upload(
|
|
289
290
|
|
290
291
|
|
291
292
|
async def blob_upload(payload: bytes, stub: ModalClientModal) -> str:
|
293
|
+
size_mib = len(payload) / 1024 / 1024
|
294
|
+
logger.debug(f"Uploading large blob of size {size_mib:.2f} MiB")
|
295
|
+
t0 = time.time()
|
292
296
|
if isinstance(payload, str):
|
293
297
|
logger.warning("Blob uploading string, not bytes - auto-encoding as utf8")
|
294
298
|
payload = payload.encode("utf8")
|
295
299
|
upload_hashes = get_upload_hashes(payload)
|
296
|
-
|
300
|
+
blob_id = await _blob_upload(upload_hashes, payload, stub)
|
301
|
+
dur_s = max(time.time() - t0, 0.001) # avoid division by zero
|
302
|
+
throughput_mib_s = (size_mib) / dur_s
|
303
|
+
logger.debug(f"Uploaded large blob of size {size_mib:.2f} MiB ({throughput_mib_s:.2f} MiB/s)." f" {blob_id}")
|
304
|
+
return blob_id
|
297
305
|
|
298
306
|
|
299
307
|
async def blob_upload_file(
|
@@ -318,11 +326,17 @@ async def _download_from_url(download_url: str) -> bytes:
|
|
318
326
|
|
319
327
|
|
320
328
|
async def blob_download(blob_id: str, stub: ModalClientModal) -> bytes:
|
321
|
-
|
329
|
+
"""Convenience function for reading all of the downloaded file into memory."""
|
330
|
+
logger.debug(f"Downloading large blob {blob_id}")
|
331
|
+
t0 = time.time()
|
322
332
|
req = api_pb2.BlobGetRequest(blob_id=blob_id)
|
323
333
|
resp = await retry_transient_errors(stub.BlobGet, req)
|
324
|
-
|
325
|
-
|
334
|
+
data = await _download_from_url(resp.download_url)
|
335
|
+
size_mib = len(data) / 1024 / 1024
|
336
|
+
dur_s = max(time.time() - t0, 0.001) # avoid division by zero
|
337
|
+
throughput_mib_s = size_mib / dur_s
|
338
|
+
logger.debug(f"Downloaded large blob {blob_id} of size {size_mib:.2f} MiB ({throughput_mib_s:.2f} MiB/s)")
|
339
|
+
return data
|
326
340
|
|
327
341
|
|
328
342
|
async def blob_iter(blob_id: str, stub: ModalClientModal) -> AsyncIterator[bytes]:
|
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.67.
|
29
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.17"
|
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.67.
|
84
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.17"
|
85
85
|
): ...
|
86
86
|
def is_closed(self) -> bool: ...
|
87
87
|
@property
|
modal/sandbox.py
CHANGED
@@ -211,6 +211,8 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
211
211
|
encrypted_ports: Sequence[int] = [],
|
212
212
|
# List of ports to tunnel into the sandbox without encryption.
|
213
213
|
unencrypted_ports: Sequence[int] = [],
|
214
|
+
# Reference to a Modal Proxy to use in front of this Sandbox.
|
215
|
+
proxy: Optional[_Proxy] = None,
|
214
216
|
_experimental_scheduler_placement: Optional[
|
215
217
|
SchedulerPlacement
|
216
218
|
] = None, # Experimental controls over fine-grained scheduling (alpha).
|
@@ -246,6 +248,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
246
248
|
pty_info=pty_info,
|
247
249
|
encrypted_ports=encrypted_ports,
|
248
250
|
unencrypted_ports=unencrypted_ports,
|
251
|
+
proxy=proxy,
|
249
252
|
_experimental_scheduler_placement=_experimental_scheduler_placement,
|
250
253
|
)
|
251
254
|
|
modal/sandbox.pyi
CHANGED
@@ -80,6 +80,7 @@ class _Sandbox(modal.object._Object):
|
|
80
80
|
pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
|
81
81
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
82
82
|
unencrypted_ports: collections.abc.Sequence[int] = [],
|
83
|
+
proxy: typing.Optional[modal.proxy._Proxy] = None,
|
83
84
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
84
85
|
client: typing.Optional[modal.client._Client] = None,
|
85
86
|
) -> _Sandbox: ...
|
@@ -199,6 +200,7 @@ class Sandbox(modal.object.Object):
|
|
199
200
|
pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
|
200
201
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
201
202
|
unencrypted_ports: collections.abc.Sequence[int] = [],
|
203
|
+
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
202
204
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
203
205
|
client: typing.Optional[modal.client.Client] = None,
|
204
206
|
) -> Sandbox: ...
|
@@ -229,6 +231,7 @@ class Sandbox(modal.object.Object):
|
|
229
231
|
pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
|
230
232
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
231
233
|
unencrypted_ports: collections.abc.Sequence[int] = [],
|
234
|
+
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
232
235
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
233
236
|
client: typing.Optional[modal.client.Client] = None,
|
234
237
|
) -> Sandbox: ...
|
@@ -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=VMg_aIuo_LOEe2ttxBHEND3PLhTp5lo-onH4wELhIyY,16375
|
22
|
-
modal/client.pyi,sha256=
|
22
|
+
modal/client.pyi,sha256=MqyW5icQNPlYAOrfTYGz_M65s06xoiT7acoxEacuCbY,7354
|
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=F2jk5zFCAA8h-GfM0dbdBG3Mu5wiG9k9Z9JLYRYuT2Q,24758
|
@@ -60,8 +60,8 @@ modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
|
|
60
60
|
modal/runner.py,sha256=7obU-Gq1ocpBGCuR6pvn1T-D6ggg1T48qFo2TNUGWkU,24089
|
61
61
|
modal/runner.pyi,sha256=RAtCvx_lXWjyFjIaZ3t9-X1c7rqpgAQlhl4Hww53OY8,5038
|
62
62
|
modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
|
63
|
-
modal/sandbox.py,sha256=
|
64
|
-
modal/sandbox.pyi,sha256=
|
63
|
+
modal/sandbox.py,sha256=25DvTWSgClANvk67HM3FHukRVLig_Fw_aQC1BLMCRhs,25150
|
64
|
+
modal/sandbox.pyi,sha256=JRh6Q-WdY6GgVSOGm0L_pgo5bfsi2UacsZezpT0-cDU,17685
|
65
65
|
modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
|
66
66
|
modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
|
67
67
|
modal/secret.py,sha256=Y1WgybQIkfkxdzH9CQ1h-Wd1DJJpzipigMhyyvSxTww,10007
|
@@ -82,7 +82,7 @@ modal/_runtime/user_code_imports.py,sha256=q_3JOYqCPDcVFZWCHEjyEqj8yzdFsQ49HzeqY
|
|
82
82
|
modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
|
83
83
|
modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
|
84
84
|
modal/_utils/async_utils.py,sha256=CYXogDVqqUtSe-DVP2A3F-6KztjPZaW6ez2lrYBCW_Y,24917
|
85
|
-
modal/_utils/blob_utils.py,sha256=
|
85
|
+
modal/_utils/blob_utils.py,sha256=0k_qUpO5GHnz538wjRhyRw4NdJ5O322N7QSilIu32jw,16601
|
86
86
|
modal/_utils/function_utils.py,sha256=SkT5emqGJ8NNASk0BlBmgDfDBUYAkUM851K74qCHL98,24641
|
87
87
|
modal/_utils/grpc_testing.py,sha256=iqM9n5M0cWUUIIWNaEDer_pIfPnzXdZBO4L8FVbNepQ,8309
|
88
88
|
modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
|
@@ -159,10 +159,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
|
|
159
159
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
160
160
|
modal_version/__init__.py,sha256=3IY-AWLH55r35_mQXIaut0jrJvoPuf1NZJBQQfSbPuo,470
|
161
161
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
162
|
-
modal_version/_version_generated.py,sha256=
|
163
|
-
modal-0.67.
|
164
|
-
modal-0.67.
|
165
|
-
modal-0.67.
|
166
|
-
modal-0.67.
|
167
|
-
modal-0.67.
|
168
|
-
modal-0.67.
|
162
|
+
modal_version/_version_generated.py,sha256=exQBnVDA5j1Jj6fzklgGVOVZLpL7m8ZbJ5fudjAV8N0,149
|
163
|
+
modal-0.67.17.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
164
|
+
modal-0.67.17.dist-info/METADATA,sha256=gg-bUIMgXTysTiCIGnmIHfqZbZwtifs8viZkfed8lFs,2329
|
165
|
+
modal-0.67.17.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
166
|
+
modal-0.67.17.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
167
|
+
modal-0.67.17.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
|
168
|
+
modal-0.67.17.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|