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.
@@ -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
- return await _blob_upload(upload_hashes, payload, stub)
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
- # convenience function reading all of the downloaded file into memory
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
- return await _download_from_url(resp.download_url)
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.15"
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.15"
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: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.67.15
3
+ Version: 0.67.17
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -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=omuAq-oRdFMqcdb731dEYbDNBp3cThARcleAXFIPVZs,7354
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=8cZ7eArLvUeR7bmvb9-XuE08ij-wSd5rbLhspdkAA9Y,25015
64
- modal/sandbox.pyi,sha256=4sxZGsRpmXME9wGWWQOLukN0tCezdMSp3pVJWu6fe5g,17502
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=XJpFr6SfNoODZEjyGm7WH9R3pKsK4yqpzZOFR3YX6fc,15856
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=yW74Sph3leSunGQQCrZcsTL-NaIvPoOH06ZVkpapDHU,149
163
- modal-0.67.15.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
- modal-0.67.15.dist-info/METADATA,sha256=w0WCe3LaidFdAW4u8XBv2gJhK23l0q-q4JPZoFLzGvQ,2329
165
- modal-0.67.15.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
166
- modal-0.67.15.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
167
- modal-0.67.15.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
168
- modal-0.67.15.dist-info/RECORD,,
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,,
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2024
2
2
 
3
3
  # Note: Reset this value to -1 whenever you make a minor `0.X` release of the client.
4
- build_number = 15 # git: fb6eb81
4
+ build_number = 17 # git: aa49902