modal 0.73.67__py3-none-any.whl → 0.73.69__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/_functions.py CHANGED
@@ -1597,26 +1597,35 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
1597
1597
  fc._is_generator = is_generator
1598
1598
  return fc
1599
1599
 
1600
+ @staticmethod
1601
+ async def gather(*function_calls: "_FunctionCall[Any]") -> list[Any]:
1602
+ """Wait until all Modal FunctionCall objects have results before returning.
1600
1603
 
1601
- async def _gather(*function_calls: _FunctionCall[ReturnType]) -> typing.Sequence[ReturnType]:
1602
- """Wait until all Modal function calls have results before returning
1604
+ Accepts a variable number of `FunctionCall` objects, as returned by `Function.spawn()`.
1603
1605
 
1604
- Accepts a variable number of FunctionCall objects as returned by `Function.spawn()`.
1606
+ Returns a list of results from each FunctionCall, or raises an exception
1607
+ from the first failing function call.
1605
1608
 
1606
- Returns a list of results from each function call, or raises an exception
1607
- of the first failing function call.
1609
+ Examples:
1610
+
1611
+ ```python notest
1612
+ fc1 = slow_func_1.spawn()
1613
+ fc2 = slow_func_2.spawn()
1608
1614
 
1609
- E.g.
1615
+ result_1, result_2 = modal.FunctionCall.gather(fc1, fc2)
1616
+ ```
1617
+ """
1618
+ try:
1619
+ return await TaskContext.gather(*[fc.get() for fc in function_calls])
1620
+ except Exception as exc:
1621
+ # TODO: kill all running function calls
1622
+ raise exc
1610
1623
 
1611
- ```python notest
1612
- function_call_1 = slow_func_1.spawn()
1613
- function_call_2 = slow_func_2.spawn()
1614
1624
 
1615
- result_1, result_2 = gather(function_call_1, function_call_2)
1616
- ```
1617
- """
1618
- try:
1619
- return await TaskContext.gather(*[fc.get() for fc in function_calls])
1620
- except Exception as exc:
1621
- # TODO: kill all running function calls
1622
- raise exc
1625
+ async def _gather(*function_calls: _FunctionCall[ReturnType]) -> typing.Sequence[ReturnType]:
1626
+ """Deprecated: Please use `modal.FunctionCall.gather()` instead."""
1627
+ deprecation_warning(
1628
+ (2025, 2, 24),
1629
+ "`modal.functions.gather()` is deprecated; please use `modal.FunctionCall.gather()` instead.",
1630
+ )
1631
+ return await _FunctionCall.gather(*function_calls)
modal/cli/run.py CHANGED
@@ -526,6 +526,9 @@ def shell(
526
526
  ),
527
527
  ),
528
528
  pty: Optional[bool] = typer.Option(default=None, help="Run the command using a PTY."),
529
+ use_module_mode: bool = typer.Option(
530
+ False, "-m", help="Interpret argument as a Python module path instead of a file/script path"
531
+ ),
529
532
  ):
530
533
  """Run a command or interactive shell inside a Modal container.
531
534
 
@@ -584,7 +587,7 @@ def shell(
584
587
  exec(container_id=container_or_function, command=shlex.split(cmd), pty=pty)
585
588
  return
586
589
 
587
- import_ref = parse_import_ref(container_or_function)
590
+ import_ref = parse_import_ref(container_or_function, use_module_mode=use_module_mode)
588
591
  runnable, all_usable_commands = import_and_filter(
589
592
  import_ref, base_cmd="modal shell", accept_local_entrypoint=False, accept_webhook=True
590
593
  )
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.73.67"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.69"
31
31
  ): ...
32
32
  def is_closed(self) -> bool: ...
33
33
  @property
@@ -85,7 +85,7 @@ class Client:
85
85
  _snapshotted: bool
86
86
 
87
87
  def __init__(
88
- self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.67"
88
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.73.69"
89
89
  ): ...
90
90
  def is_closed(self) -> bool: ...
91
91
  @property
modal/functions.pyi CHANGED
@@ -198,11 +198,11 @@ class Function(
198
198
 
199
199
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
200
200
 
201
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
201
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
202
202
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
203
203
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
204
204
 
205
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
205
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
206
206
 
207
207
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
208
208
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -217,19 +217,19 @@ class Function(
217
217
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
218
218
  ) -> modal._functions.OriginalReturnType: ...
219
219
 
220
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
220
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
221
221
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
222
222
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
223
223
 
224
224
  _experimental_spawn: ___experimental_spawn_spec[
225
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
225
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
226
226
  ]
227
227
 
228
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
228
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
229
229
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
230
230
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
231
231
 
232
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
232
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
233
233
 
234
234
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
235
235
 
@@ -319,12 +319,14 @@ class FunctionCall(typing.Generic[modal._functions.ReturnType], modal.object.Obj
319
319
 
320
320
  from_id: __from_id_spec
321
321
 
322
+ class __gather_spec(typing_extensions.Protocol):
323
+ def __call__(self, *function_calls: FunctionCall[typing.Any]) -> list[typing.Any]: ...
324
+ async def aio(self, *function_calls: FunctionCall[typing.Any]) -> list[typing.Any]: ...
325
+
326
+ gather: __gather_spec
327
+
322
328
  class __gather_spec(typing_extensions.Protocol):
323
- def __call__(
324
- self, *function_calls: FunctionCall[modal._functions.ReturnType]
325
- ) -> typing.Sequence[modal._functions.ReturnType]: ...
326
- async def aio(
327
- self, *function_calls: FunctionCall[modal._functions.ReturnType]
328
- ) -> typing.Sequence[modal._functions.ReturnType]: ...
329
+ def __call__(self, *function_calls) -> typing.Sequence[modal._functions.ReturnType]: ...
330
+ async def aio(self, *function_calls) -> typing.Sequence[modal._functions.ReturnType]: ...
329
331
 
330
332
  gather: __gather_spec
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: modal
3
- Version: 0.73.67
3
+ Version: 0.73.69
4
4
  Summary: Python client library for Modal
5
5
  Author-email: Modal Labs <support@modal.com>
6
6
  License: Apache-2.0
@@ -3,7 +3,7 @@ modal/__main__.py,sha256=CgIjP8m1xJjjd4AXc-delmR6LdBCZclw2A_V38CFIio,2870
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
5
  modal/_container_entrypoint.py,sha256=arhkIoF8nQNfa4iwYGSoqN3QMDg5M38QNAODXC8TlKc,29301
6
- modal/_functions.py,sha256=2TcHq8h7vpsWUnzIGo7cL_wK2QbSog3vYNiDV68IqN4,70989
6
+ modal/_functions.py,sha256=34kHxFM4k1oSb0OV2Op6uDuiT-jEBG8cbo3NfqhAgew,71417
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=ItQcsMNkz9Y3kdTsvfNarbW-paJ2qabDyQ7njaqY0XI,11359
@@ -22,7 +22,7 @@ modal/app.py,sha256=o5mHoHtn41nkvskX_ekJkyfG6MXwj5rqerRi_nnPd0w,44725
22
22
  modal/app.pyi,sha256=0MMCgskIL4r3eq8oBcfm2lLyeao2gXjS3iXaIfmaJ-o,25959
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=8SQawr7P1PNUCq1UmJMUQXG2jIo4Nmdcs311XqrNLRE,15276
25
- modal/client.pyi,sha256=A73KWG_FODq0ns8Rj8B25VY41cP0TOWqUjxMt37FpJg,7593
25
+ modal/client.pyi,sha256=384pcY20zF-7aLAIE8yknf6pvF-OuMhnJWcLjhB_lLM,7593
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=wztMTYkhJyW9iUVqx4_Gga4bJJpUiPgGsS6iacUqy-A,30001
@@ -41,7 +41,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
41
41
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
42
42
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
43
43
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
44
- modal/functions.pyi,sha256=24XrtwZ3yqfv68bWH8zXWUdu-q4NbekyX_4h515faLE,14247
44
+ modal/functions.pyi,sha256=2z5Vt2U3KfmTWyC55hPVEgc4i83BiqAK0faJgumpe04,14405
45
45
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
46
46
  modal/image.py,sha256=Bs1ND2WkLr9CBtj0heO7e3w9uGCnijKU8owiQSRQXv0,90200
47
47
  modal/image.pyi,sha256=L7aZUOElSGtNHmFHz1RgKP1cG5paiXt_EzylrwBwzVk,25004
@@ -128,7 +128,7 @@ modal/cli/launch.py,sha256=0_sBu6bv2xJEPWi-rbGS6Ri9ggnkWQvrGlgpYSUBMyY,3097
128
128
  modal/cli/network_file_system.py,sha256=eq3JnwjbfFNsJodIyANHL06ByYc3BSavzdmu8C96cHA,7948
129
129
  modal/cli/profile.py,sha256=0TYhgRSGUvQZ5LH9nkl6iZllEvAjDniES264dE57wOM,3201
130
130
  modal/cli/queues.py,sha256=6gTu76dzBtPN5eQVsLrvQpuru5jI9ZCWK5Eh8J8XhaM,4498
131
- modal/cli/run.py,sha256=rCd-lB6p-l2vd0OrvXcioVN6wn_1EkCiRQLJRC3Z7J4,22764
131
+ modal/cli/run.py,sha256=v1_yj6fJ-W8hPi3z5tHsogsXjtuvwjnjV-EjTIJqXr8,22947
132
132
  modal/cli/secret.py,sha256=iDsaFUJBq3333ZBVzKPcqyey68w0j82PNddGhRgP2pA,4206
133
133
  modal/cli/token.py,sha256=mxSgOWakXG6N71hQb1ko61XAR9ZGkTMZD-Txn7gmTac,1924
134
134
  modal/cli/utils.py,sha256=hZmjyzcPjDnQSkLvycZD2LhGdcsfdZshs_rOU78EpvI,3717
@@ -168,10 +168,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
168
168
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
169
169
  modal_version/__init__.py,sha256=wiJQ53c-OMs0Xf1UeXOxQ7FwlV1VzIjnX6o-pRYZ_Pk,470
170
170
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
171
- modal_version/_version_generated.py,sha256=ynzFvSkZPxYjAUJ70yuwCaruZE93p8LxqS8lN864JEA,149
172
- modal-0.73.67.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
173
- modal-0.73.67.dist-info/METADATA,sha256=dynQP4EP-x-qL493ZTVocwqMT6mY3CllpMuLyOaHw6E,2452
174
- modal-0.73.67.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
175
- modal-0.73.67.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
176
- modal-0.73.67.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
177
- modal-0.73.67.dist-info/RECORD,,
171
+ modal_version/_version_generated.py,sha256=B7e7cKuQAdarzoqlv9H4qIIcUZ15iqjkqwjbRrAWK5w,149
172
+ modal-0.73.69.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
173
+ modal-0.73.69.dist-info/METADATA,sha256=z_3dOmx8pl3uZRcmXIFxa6nZ6P42tPdAT7lxK1K_B7U,2452
174
+ modal-0.73.69.dist-info/WHEEL,sha256=nn6H5-ilmfVryoAQl3ZQ2l8SH5imPWFpm1A5FgEuFV4,91
175
+ modal-0.73.69.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
176
+ modal-0.73.69.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
177
+ modal-0.73.69.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (75.8.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
 
3
3
  # Note: Reset this value to -1 whenever you make a minor `0.X` release of the client.
4
- build_number = 67 # git: 54fbd18
4
+ build_number = 69 # git: f83977d