modal 0.68.31__py3-none-any.whl → 0.68.38__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/_traceback.py CHANGED
@@ -74,11 +74,15 @@ def append_modal_tb(exc: BaseException, tb_dict: TBDictType, line_cache: LineCac
74
74
 
75
75
  def reduce_traceback_to_user_code(tb: Optional[TracebackType], user_source: str) -> TracebackType:
76
76
  """Return a traceback that does not contain modal entrypoint or synchronicity frames."""
77
- # Step forward all the way through the traceback and drop any synchronicity frames
77
+
78
+ # Step forward all the way through the traceback and drop any "Modal support" frames
79
+ def skip_frame(filename: str) -> bool:
80
+ return "/site-packages/synchronicity/" in filename or "modal/_utils/deprecation" in filename
81
+
78
82
  tb_root = tb
79
83
  while tb is not None:
80
84
  while tb.tb_next is not None:
81
- if "/site-packages/synchronicity/" in tb.tb_next.tb_frame.f_code.co_filename:
85
+ if skip_frame(tb.tb_next.tb_frame.f_code.co_filename):
82
86
  tb.tb_next = tb.tb_next.tb_next
83
87
  else:
84
88
  break
@@ -1,7 +1,11 @@
1
1
  # Copyright Modal Labs 2024
2
+ import functools
2
3
  import sys
3
4
  import warnings
4
5
  from datetime import date
6
+ from typing import Any, Callable, TypeVar
7
+
8
+ from typing_extensions import ParamSpec # Needed for Python 3.9
5
9
 
6
10
  from ..exception import DeprecationError, PendingDeprecationError
7
11
 
@@ -42,3 +46,43 @@ def deprecation_warning(
42
46
 
43
47
  # This is a lower-level function that warnings.warn uses
44
48
  warnings.warn_explicit(f"{date(*deprecated_on)}: {msg}", warning_cls, filename, lineno)
49
+
50
+
51
+ P = ParamSpec("P")
52
+ R = TypeVar("R")
53
+
54
+
55
+ def renamed_parameter(
56
+ date: tuple[int, int, int],
57
+ old_name: str,
58
+ new_name: str,
59
+ ) -> Callable[[Callable[P, R]], Callable[P, R]]:
60
+ """Decorator for semi-gracefully changing a parameter name.
61
+
62
+ Functions wrapped with this decorator can be defined using only the `new_name` of the parameter.
63
+ If the function is invoked with the `old_name`, the wrapper will pass the value as a keyword
64
+ argument for `new_name` and issue a Modal deprecation warning about the change.
65
+
66
+ Note that this only prevents parameter renamings from breaking code at runtime.
67
+ Type checking will fail when code uses `old_name`. To avoid this, the `old_name` can be
68
+ preserved in the function signature with an `Annotated` type hint indicating the renaming.
69
+ """
70
+
71
+ def decorator(func: Callable[P, R]) -> Callable[P, R]:
72
+ @functools.wraps(func)
73
+ def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
74
+ mut_kwargs: dict[str, Any] = locals()["kwargs"] # Avoid referencing kwargs directly due to bug in sigtools
75
+ if old_name in mut_kwargs:
76
+ mut_kwargs[new_name] = mut_kwargs.pop(old_name)
77
+ func_name = func.__qualname__.removeprefix("_") # Avoid confusion when synchronicity-wrapped
78
+ message = (
79
+ f"The '{old_name}' parameter of `{func_name}` has been renamed to '{new_name}'."
80
+ "\nUsing the old name will become an error in a future release. Please update your code."
81
+ )
82
+ deprecation_warning(date, message, show_source=False)
83
+
84
+ return func(*args, **kwargs)
85
+
86
+ return wrapper
87
+
88
+ return decorator
modal/cli/dict.py CHANGED
@@ -89,6 +89,11 @@ async def get(name: str, key: str, *, env: Optional[str] = ENV_OPTION):
89
89
  console.print(val)
90
90
 
91
91
 
92
+ def _display(input: str, use_repr: bool) -> str:
93
+ val = repr(input) if use_repr else str(input)
94
+ return val[:80] + "..." if len(val) > 80 else val
95
+
96
+
92
97
  @dict_cli.command(name="items", rich_help_panel="Inspection")
93
98
  @synchronizer.create_blocking
94
99
  async def items(
@@ -117,8 +122,7 @@ async def items(
117
122
  if json:
118
123
  display_item = key, val
119
124
  else:
120
- cast = repr if use_repr else str
121
- display_item = cast(key), cast(val) # type: ignore # mypy/issue/12056
125
+ display_item = _display(key, use_repr), _display(val, use_repr) # type: ignore # mypy/issue/12056
122
126
  items.append(display_item)
123
127
 
124
128
  display_table(["Key", "Value"], items, json)
modal/cli/run.py CHANGED
@@ -482,6 +482,7 @@ def shell(
482
482
  volumes=function_spec.volumes,
483
483
  region=function_spec.scheduler_placement.proto.regions if function_spec.scheduler_placement else None,
484
484
  pty=pty,
485
+ proxy=function_spec.proxy,
485
486
  )
486
487
  else:
487
488
  modal_image = Image.from_registry(image, add_python=add_python) if image else None
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.31"
29
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.38"
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.31"
84
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.68.38"
85
85
  ): ...
86
86
  def is_closed(self) -> bool: ...
87
87
  @property
modal/functions.py CHANGED
@@ -346,6 +346,7 @@ class _FunctionSpec:
346
346
  memory: Optional[Union[int, tuple[int, int]]]
347
347
  ephemeral_disk: Optional[int]
348
348
  scheduler_placement: Optional[SchedulerPlacement]
349
+ proxy: Optional[_Proxy]
349
350
 
350
351
 
351
352
  P = typing_extensions.ParamSpec("P")
@@ -530,6 +531,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
530
531
  memory=memory,
531
532
  ephemeral_disk=ephemeral_disk,
532
533
  scheduler_placement=scheduler_placement,
534
+ proxy=proxy,
533
535
  )
534
536
 
535
537
  if info.user_cls and not is_auto_snapshot:
modal/functions.pyi CHANGED
@@ -100,6 +100,7 @@ class _FunctionSpec:
100
100
  memory: typing.Union[int, tuple[int, int], None]
101
101
  ephemeral_disk: typing.Optional[int]
102
102
  scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement]
103
+ proxy: typing.Optional[modal.proxy._Proxy]
103
104
 
104
105
  def __init__(
105
106
  self,
@@ -121,6 +122,7 @@ class _FunctionSpec:
121
122
  memory: typing.Union[int, tuple[int, int], None],
122
123
  ephemeral_disk: typing.Optional[int],
123
124
  scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement],
125
+ proxy: typing.Optional[modal.proxy._Proxy],
124
126
  ) -> None: ...
125
127
  def __repr__(self): ...
126
128
  def __eq__(self, other): ...
modal/sandbox.py CHANGED
@@ -118,6 +118,8 @@ class _Sandbox(_Object, type_prefix="sb"):
118
118
  for _, cloud_bucket_mount in cloud_bucket_mounts:
119
119
  if cloud_bucket_mount.secret:
120
120
  deps.append(cloud_bucket_mount.secret)
121
+ if proxy:
122
+ deps.append(proxy)
121
123
  return deps
122
124
 
123
125
  async def _load(self: _Sandbox, resolver: Resolver, _existing_object_id: Optional[str]):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.68.31
3
+ Version: 0.68.38
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -21,7 +21,7 @@ Requires-Dist: fastapi
21
21
  Requires-Dist: grpclib (==0.4.7)
22
22
  Requires-Dist: protobuf (!=4.24.0,<6.0,>=3.19)
23
23
  Requires-Dist: rich (>=12.0.0)
24
- Requires-Dist: synchronicity (~=0.9.6)
24
+ Requires-Dist: synchronicity (~=0.9.7)
25
25
  Requires-Dist: toml
26
26
  Requires-Dist: typer (>=0.9)
27
27
  Requires-Dist: types-certifi
@@ -11,7 +11,7 @@ modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
11
11
  modal/_resolver.py,sha256=TtowKu2LdZ7NpiYkSXs058BZ4ivY8KVYdchqLfREkiA,6775
12
12
  modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
13
13
  modal/_serialization.py,sha256=qPLH6OUEBas1CT-a6i5pOP1hPGt5AfKr9q7RMUTFOMc,18722
14
- modal/_traceback.py,sha256=orZ7rsCk9ekV7ZoFjZTH_H00azCypwRKaLh0MZb1dR8,4898
14
+ modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
15
15
  modal/_tunnel.py,sha256=o-jJhS4vQ6-XswDhHcJWGMZZmD03SC0e9i8fEu1JTjo,6310
16
16
  modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
17
17
  modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
@@ -19,7 +19,7 @@ modal/app.py,sha256=nt25_TXlzG4Kw_Ev4cgGaQnJaMnXN9-23tUh8dtR5xk,45454
19
19
  modal/app.pyi,sha256=3h538rJ0Z2opldsKLuQhDnvop05TfzNG-Uw_n9rEHa4,25197
20
20
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
21
21
  modal/client.py,sha256=JAnd4-GCN093BwkvOFAK5a6iy5ycxofjpUncMxlrIMw,15253
22
- modal/client.pyi,sha256=qaus2Fah5EEsfJGBXrjVzb-fCwJ459fjrWGkXVDQQGs,7280
22
+ modal/client.pyi,sha256=Ng65Hf95fFrHO5vjeAr-cPWX6-YmthzK3k4osN3p_D4,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,8 +36,8 @@ modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
36
36
  modal/file_io.py,sha256=pDOFNQU5m-x-k3oJauck4fOp3bZ55Vc-_LvSaN5_Bow,16465
37
37
  modal/file_io.pyi,sha256=GMhCCRyMftXYI3HqI9EdGPOx70CbCNi-VC5Sfy5TYnc,7631
38
38
  modal/file_pattern_matcher.py,sha256=V6P74Vc7LAuBFe_uepIaZmoDJiuAvqjFibe0GcMJwxo,5119
39
- modal/functions.py,sha256=ig7FjNHrzsYzIgpagLGphQYLybvtx_4m0Exp0ribO1c,67669
40
- modal/functions.pyi,sha256=dsA-f4Jc-VvXWaKcPyzUSgDCBQ5ujKv55AL7rtkSCT4,25213
39
+ modal/functions.py,sha256=4-0Bs7Tn7IpMWfO6n94tcX3ga4Mt5dhzCPHDxuRBLNg,67722
40
+ modal/functions.pyi,sha256=G1saYF_6J-9JodKn9VsKoPwqs0u1Cmf4MKn7jH-rjvQ,25312
41
41
  modal/gpu.py,sha256=r4rL6uH3UJIQthzYvfWauXNyh01WqCPtKZCmmSX1fd4,6881
42
42
  modal/image.py,sha256=-swOPK80OXnFuhxoG3tT2zmJhas8yO-lr0jkOebBdKQ,82858
43
43
  modal/image.pyi,sha256=Ryd3x_Bic7j40DPe0MveGqqwvNtum2qA-6lUd5lnHvk,25503
@@ -63,7 +63,7 @@ modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
63
63
  modal/runner.py,sha256=qfkB0OM97kb_-oP-D5KPj_jUwfd8ePUA3R_zLkjSTBQ,24586
64
64
  modal/runner.pyi,sha256=BvMS1ZVzWSn8B8q0KnIZOJKPkN5L-i5b-USbV6SWWHQ,5177
65
65
  modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
66
- modal/sandbox.py,sha256=YJaAeeBiyf3k1loHpLyJ3kwobEhS0Jnr7voC9venNJA,28049
66
+ modal/sandbox.py,sha256=c-Qli3QJPN7bBQzsTk4iS51zurNlq--InZ2eRR-B6No,28106
67
67
  modal/sandbox.pyi,sha256=k8_vHjN3oigxSCF13Cm2HfcSHuliGuSb8ryd3CGqwoA,19815
68
68
  modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
69
69
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
@@ -87,7 +87,7 @@ modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
87
87
  modal/_utils/async_utils.py,sha256=9ubwMkwiDB4gzOYG2jL9j7Fs-5dxHjcifZe3r7JRg-k,25091
88
88
  modal/_utils/blob_utils.py,sha256=N66LtZI8PpCkZ7maA7GLW5CAmYUoNJdG-GjaAUR4_NQ,14509
89
89
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
90
- modal/_utils/deprecation.py,sha256=9yHc2_bIuvivx-oYOzg-kj6JIolPdxXBlEkOVgnZcFA,1556
90
+ modal/_utils/deprecation.py,sha256=RZjL__i8-8OsOCwbXUWzsSAGM9dXhJDokqEJoY0akLc,3390
91
91
  modal/_utils/function_utils.py,sha256=LgcveUUb4XU_dWxtqgK_3ujZBvS3cGVzcDOkljyFZ2w,25066
92
92
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
93
93
  modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
@@ -110,7 +110,7 @@ modal/cli/_traceback.py,sha256=QlLa_iw3fAOA-mqCqjS8qAxvNT48J3YY3errtVVc2cw,7316
110
110
  modal/cli/app.py,sha256=HkwI38FZxx66jxiur4o_DRN3uwyO3L8hqgyo8oXKZxc,7726
111
111
  modal/cli/config.py,sha256=pXPLmX0bIoV57rQNqIPK7V-yllj-GPRY4jiBO_EklGg,1667
112
112
  modal/cli/container.py,sha256=nCySVD10VJPzmX3ghTsGmpxdYeVYYMW6ofjsyt2gQcM,3667
113
- modal/cli/dict.py,sha256=gwX4ZBsrr0dpWf_B5_5GN_ealcVzpcGyvY24dEY4y3Y,4455
113
+ modal/cli/dict.py,sha256=HaEcjfll7i3Uj3Fg56aj4407if5UljsYfr6fIq-D2W8,4589
114
114
  modal/cli/entry_point.py,sha256=aaNxFAqZcmtSjwzkYIA_Ba9CkL4cL4_i2gy5VjoXxkM,4228
115
115
  modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
116
116
  modal/cli/import_refs.py,sha256=wnqE5AMeyAN3IZmQvJCp54KRnJh8Nq_5fMqB6u6GEL8,9147
@@ -118,7 +118,7 @@ modal/cli/launch.py,sha256=uyI-ouGvYRjHLGxGQ2lYBZq32BiRT1i0L8ksz5iy7K8,2935
118
118
  modal/cli/network_file_system.py,sha256=3QbAxKEoRc6RCMsYE3OS-GcuiI4GMkz_wAKsIBbN1qg,8186
119
119
  modal/cli/profile.py,sha256=rLXfjJObfPNjaZvNfHGIKqs7y9bGYyGe-K7V0w-Ni0M,3110
120
120
  modal/cli/queues.py,sha256=MIh2OsliNE2QeL1erubfsRsNuG4fxqcqWA2vgIfQ4Mg,4494
121
- modal/cli/run.py,sha256=W9isFpIQTNCxKafVfI_PUjxNrDMl5V8N9y15F3wtPXk,17831
121
+ modal/cli/run.py,sha256=9SvPmBzB8ZZRaqUJc9LmL2tfT5OMiR4Ow0dLANVwuB8,17870
122
122
  modal/cli/secret.py,sha256=uQpwYrMY98iMCWeZOQTcktOYhPTZ8IHnyealDc2CZqo,4206
123
123
  modal/cli/token.py,sha256=mxSgOWakXG6N71hQb1ko61XAR9ZGkTMZD-Txn7gmTac,1924
124
124
  modal/cli/utils.py,sha256=hZmjyzcPjDnQSkLvycZD2LhGdcsfdZshs_rOU78EpvI,3717
@@ -164,10 +164,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
164
164
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
165
165
  modal_version/__init__.py,sha256=RT6zPoOdFO99u5Wcxxaoir4ZCuPTbQ22cvzFAXl3vUY,470
166
166
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
167
- modal_version/_version_generated.py,sha256=C9Vb_Q2jwc4JqXMWby_tAoXXSlH3UtNjbodotQ6GwxI,149
168
- modal-0.68.31.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
169
- modal-0.68.31.dist-info/METADATA,sha256=DBQM-eDw-6sWtFeC6cVRZvEPULWr_Grn0eYDBEcUmaM,2329
170
- modal-0.68.31.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
171
- modal-0.68.31.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
172
- modal-0.68.31.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
173
- modal-0.68.31.dist-info/RECORD,,
167
+ modal_version/_version_generated.py,sha256=ZLULBEgvh9optrCd0aXJbvDqnCFkH-7CUmRAH2ljLP8,149
168
+ modal-0.68.38.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
169
+ modal-0.68.38.dist-info/METADATA,sha256=oh-PsOlL0JKa8Hk8GhE_-BhhIEoYjcFgl-vCP5dztBE,2329
170
+ modal-0.68.38.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
171
+ modal-0.68.38.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
172
+ modal-0.68.38.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
173
+ modal-0.68.38.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 = 31 # git: f1e1cbf
4
+ build_number = 38 # git: 5ae1918