modal 0.74.52__py3-none-any.whl → 0.74.54__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
@@ -1583,6 +1583,15 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
1583
1583
  fc._is_generator = self._is_generator if self._is_generator else False
1584
1584
  return fc
1585
1585
 
1586
+ @synchronizer.no_input_translation
1587
+ @live_method
1588
+ async def _spawn_map_inner(self, *args: P.args, **kwargs: P.kwargs) -> None:
1589
+ self._check_no_web_url("spawn_map")
1590
+ if self._is_generator:
1591
+ raise Exception("Cannot `spawn_map` over a generator function.")
1592
+
1593
+ await self._call_function_nowait(args, kwargs, api_pb2.FUNCTION_CALL_INVOCATION_TYPE_ASYNC, from_spawn_map=True)
1594
+
1586
1595
  @synchronizer.no_input_translation
1587
1596
  @live_method
1588
1597
  async def spawn(self, *args: P.args, **kwargs: P.kwargs) -> "_FunctionCall[ReturnType]":
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.74.52"
30
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.54"
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.74.52"
88
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.74.54"
89
89
  ): ...
90
90
  def is_closed(self) -> bool: ...
91
91
  @property
modal/config.py CHANGED
@@ -102,6 +102,9 @@ from ._utils.deprecation import deprecation_error
102
102
  from ._utils.logger import configure_logger
103
103
  from .exception import InvalidError
104
104
 
105
+ DEFAULT_SERVER_URL = "https://api.modal.com"
106
+
107
+
105
108
  # Locate config file and read it
106
109
 
107
110
  user_config_path: str = os.environ.get("MODAL_CONFIG_PATH") or os.path.expanduser("~/.modal.toml")
@@ -222,7 +225,7 @@ _SETTINGS = {
222
225
  "loglevel": _Setting("WARNING", lambda s: s.upper()),
223
226
  "log_format": _Setting("STRING", lambda s: s.upper()),
224
227
  "log_pattern": _Setting(), # optional override of the formatting pattern
225
- "server_url": _Setting("https://api.modal.com"),
228
+ "server_url": _Setting(DEFAULT_SERVER_URL),
226
229
  "token_id": _Setting(),
227
230
  "token_secret": _Setting(),
228
231
  "task_id": _Setting(),
@@ -316,7 +319,9 @@ configure_logger(logger, config["loglevel"], config["log_format"])
316
319
 
317
320
 
318
321
  def _store_user_config(
319
- new_settings: dict[str, Any], profile: Optional[str] = None, active_profile: Optional[str] = None
322
+ new_settings: dict[str, Any],
323
+ profile: Optional[str] = None,
324
+ active_profile: Optional[str] = None,
320
325
  ):
321
326
  """Internal method, used by the CLI to set tokens."""
322
327
  if profile is None:
modal/functions.pyi CHANGED
@@ -222,11 +222,11 @@ class Function(
222
222
 
223
223
  _call_generator_nowait: ___call_generator_nowait_spec[typing_extensions.Self]
224
224
 
225
- class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
225
+ class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
226
226
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
227
227
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER: ...
228
228
 
229
- remote: __remote_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
229
+ remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
230
230
 
231
231
  class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
232
232
  def __call__(self, *args, **kwargs) -> typing.Generator[typing.Any, None, None]: ...
@@ -241,19 +241,25 @@ class Function(
241
241
  self, *args: modal._functions.P.args, **kwargs: modal._functions.P.kwargs
242
242
  ) -> modal._functions.OriginalReturnType: ...
243
243
 
244
- class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
244
+ class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
245
245
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
246
246
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
247
247
 
248
248
  _experimental_spawn: ___experimental_spawn_spec[
249
- modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
249
+ modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
250
250
  ]
251
251
 
252
- class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
252
+ class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
253
+ def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
254
+ async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
255
+
256
+ _spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
257
+
258
+ class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
253
259
  def __call__(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
254
260
  async def aio(self, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]: ...
255
261
 
256
- spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
262
+ spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
257
263
 
258
264
  def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]: ...
259
265
 
modal/parallel_map.py CHANGED
@@ -496,9 +496,7 @@ async def _spawn_map_async(self, *input_iterators, kwargs={}) -> None:
496
496
  errors, log a warning that the function call is waiting to be created.
497
497
  """
498
498
 
499
- return self._call_function_nowait.aio(
500
- args, kwargs, api_pb2.FUNCTION_CALL_INVOCATION_TYPE_ASYNC, from_spawn_map=True
501
- )
499
+ return self._spawn_map_inner.aio(args, kwargs, api_pb2.FUNCTION_CALL_INVOCATION_TYPE_ASYNC)
502
500
 
503
501
  input_gen = async_zip(*[sync_or_async_iter(it) for it in input_iterators])
504
502
 
modal/token_flow.py CHANGED
@@ -14,7 +14,7 @@ from modal_proto import api_pb2
14
14
  from ._utils.async_utils import synchronize_api
15
15
  from ._utils.http_utils import run_temporary_http_server
16
16
  from .client import _Client
17
- from .config import _lookup_workspace, _store_user_config, config, config_profiles, user_config_path
17
+ from .config import DEFAULT_SERVER_URL, _lookup_workspace, _store_user_config, config, config_profiles, user_config_path
18
18
  from .exception import AuthError
19
19
 
20
20
 
@@ -108,6 +108,8 @@ async def _new_token(
108
108
 
109
109
  console.print("[green]Web authentication finished successfully![/green]")
110
110
 
111
+ server_url = client.server_url
112
+
111
113
  assert result is not None
112
114
 
113
115
  if result.workspace_username:
@@ -115,7 +117,9 @@ async def _new_token(
115
117
  f"[green]Token is connected to the [magenta]{result.workspace_username}[/magenta] workspace.[/green]"
116
118
  )
117
119
 
118
- await _set_token(result.token_id, result.token_secret, profile=profile, activate=activate, verify=verify)
120
+ await _set_token(
121
+ result.token_id, result.token_secret, profile=profile, activate=activate, verify=verify, server_url=server_url
122
+ )
119
123
 
120
124
 
121
125
  async def _set_token(
@@ -125,6 +129,7 @@ async def _set_token(
125
129
  profile: Optional[str] = None,
126
130
  activate: bool = True,
127
131
  verify: bool = True,
132
+ server_url: Optional[str] = None,
128
133
  ):
129
134
  # TODO add server_url as a parameter for verification?
130
135
  server_url = config.get("server_url", profile=profile)
@@ -149,6 +154,8 @@ async def _set_token(
149
154
  profile = workspace.username
150
155
 
151
156
  config_data = {"token_id": token_id, "token_secret": token_secret}
157
+ if server_url is not None and server_url != DEFAULT_SERVER_URL:
158
+ config_data["server_url"] = server_url
152
159
  # Activate the profile when requested or if no other profiles currently exist
153
160
  active_profile = profile if (activate or not config_profiles()) else None
154
161
  with console.status("Storing token", spinner="dots"):
modal/token_flow.pyi CHANGED
@@ -53,5 +53,6 @@ async def _set_token(
53
53
  profile: typing.Optional[str] = None,
54
54
  activate: bool = True,
55
55
  verify: bool = True,
56
+ server_url: typing.Optional[str] = None,
56
57
  ): ...
57
58
  def _open_url(url: str) -> bool: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 0.74.52
3
+ Version: 0.74.54
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=sTJcc9EbDuCKSwg3tL6ZckFw9WWdlkXW8mId1IvJCNc,2846
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=2Zx9O_EMJg0H77EdnC2vGKs6uFMWwbP1NLFf-qYmWmU,28962
6
- modal/_functions.py,sha256=3Nx7snIerJEqcyCRGMTr3MReWklMpURItVz-o5qX7tE,77262
6
+ modal/_functions.py,sha256=gxkLeVvj21akFNzHLeSH0F8AvjEnqRkD_2WIM3NymvE,77674
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=6ve4sI2nRAnjPCuAXdSoUplaXfzC9MqRlF_ZLULwwy0,11472
@@ -22,12 +22,12 @@ modal/app.py,sha256=r-9vVU1lrR1CWtJEo60fuaianvxY_oOXZyv1Qx1DEkI,51231
22
22
  modal/app.pyi,sha256=0QNtnUpAFbOPcbwCt119ge7OmoBqMFw5SajLgdE5eOw,28600
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=U-YKSw0n7J1ZLREt9cbEJCtmHe5YoPKFxl0xlkan2yc,15565
25
- modal/client.pyi,sha256=GnzHvxzfIFRi4doitEOYBh156ga2jvW6gdQoh6joQkE,7593
25
+ modal/client.pyi,sha256=1q7e8YKblg2MBMnR2CGqd7e78IQ-YSnKQvBIsrXWcOc,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=aHoMEWMZUN7bOezs3tRPxzS1FP3gTxZBORVjbPmtxyg,35338
29
29
  modal/cls.pyi,sha256=B--Y4xEOo3GRE3QiiFdIE8jnIKEeBcOtwAbXvg2Z8H4,12012
30
- modal/config.py,sha256=_2KU5jG-vZQ4vDLYQ83r4aQdnjnN00TY12DtSJMGYsA,12617
30
+ modal/config.py,sha256=OOMEJ5LHNFbHRW5wUpuhl0TH6EPW8D1XV9I3OJXrZrk,12668
31
31
  modal/container_process.py,sha256=vvyK3DVPUMsuqvkKdUiQ49cDLF9JawGrxpglLk5vfgI,6208
32
32
  modal/container_process.pyi,sha256=bXs2KHe7nxVuLAm6RRBqXCvDKelANGX9gFY8qIuZYDs,2898
33
33
  modal/dict.py,sha256=7NJVI05hisF9gTuJMYestH9X0LIOaE9PPqbCeYtwSRs,13365
@@ -39,7 +39,7 @@ modal/file_io.py,sha256=lcMs_E9Xfm0YX1t9U2wNIBPnqHRxmImqjLW1GHqVmyg,20945
39
39
  modal/file_io.pyi,sha256=NTRft1tbPSWf9TlWVeZmTlgB5AZ_Zhu2srWIrWr7brk,9445
40
40
  modal/file_pattern_matcher.py,sha256=trosX-Bp7dOubudN1bLLhRAoidWy1TcoaR4Pv8CedWw,6497
41
41
  modal/functions.py,sha256=kcNHvqeGBxPI7Cgd57NIBBghkfbeFJzXO44WW0jSmao,325
42
- modal/functions.pyi,sha256=N0vF8PfDKQLsWEKjtr0oWU6Ls6a07hj_1G8Bj2grdvk,16010
42
+ modal/functions.pyi,sha256=GBO82WpHwMdtb3n7hezIC-PXMCDCflemkEWm38hXswA,16360
43
43
  modal/gpu.py,sha256=Kbhs_u49FaC2Zi0TjCdrpstpRtT5eZgecynmQi5IZVE,6752
44
44
  modal/image.py,sha256=ZCghS6l1O7pezXcdMHk6RoJpW3qWszfWGJTW38lNXaU,92797
45
45
  modal/image.pyi,sha256=ddbegF532pDLiVANOJdtJiYoDbbF3mAFrsCiyvIu7jU,25632
@@ -52,7 +52,7 @@ modal/network_file_system.pyi,sha256=C_ZiXmpdkTObapVhAPlRmB4ofmM2D7SdKlUCZVg-1IQ
52
52
  modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
53
53
  modal/object.pyi,sha256=kyJkRQcVv3ct7zSAxvvXcuhBVeH914v80uSlqeS7cA4,5632
54
54
  modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
55
- modal/parallel_map.py,sha256=UAqwhlsMQzhVtc9b2xzwH0__T3auN5tPX0h8a9ZHIMA,35737
55
+ modal/parallel_map.py,sha256=sHx1lZfj7Q5xNk--RrPgClbtu_Qh8XLwehlWHb2IwQM,35689
56
56
  modal/parallel_map.pyi,sha256=bLh_D57e5KOIkmP4WW-C_rMSzfxRUNfdtpNJKj4jWA4,5865
57
57
  modal/partial_function.py,sha256=SwuAAj2wj4SO6F6nkSnwNZrczEmm9w9YdlQTHh6hr04,1195
58
58
  modal/partial_function.pyi,sha256=NFWz1aCAs2B3-GnPf1cTatWRZOLnYpFKCnjP_X9iNRs,6411
@@ -76,8 +76,8 @@ modal/serving.pyi,sha256=KGSaZhg0qwygLmDkhgJedUfWeNSkXsyoOipq10vYffU,1978
76
76
  modal/snapshot.py,sha256=6rQvDP3iX9hdiAudKTy0-m0JESt4kk0q2gusXbaRA-8,1279
77
77
  modal/snapshot.pyi,sha256=Ypd4NKsjOTnnnqXyTGGLKq5lkocRrUURYjY5Pi67_qA,670
78
78
  modal/stream_type.py,sha256=A6320qoAAWhEfwOCZfGtymQTu5AfLfJXXgARqooTPvY,417
79
- modal/token_flow.py,sha256=ZYCa-uVP6jrJmUKA6wAG4lngqNem8Mgm2HXz1DR19BM,7355
80
- modal/token_flow.pyi,sha256=0XV3d-9CGQL3qjPdw3RgwIFVqqxo8Z-u044_mkgAM3o,2064
79
+ modal/token_flow.py,sha256=0_4KabXKsuE4OXTJ1OuLOtA-b1sesShztMZkkRFK7tA,7605
80
+ modal/token_flow.pyi,sha256=7WBDuk9l_VNLxUwr6zDZg2gLyujTiGlAkjmjPV_7FWc,2109
81
81
  modal/volume.py,sha256=d8x6i2qJgacJQ5qbNMvzeNFrK7ap4jPtjxZEpWstpCw,40624
82
82
  modal/volume.pyi,sha256=rjlkEt9zuCy7GLe1TuVDSTiGJliFX9v6_KGKqL8HaeM,18760
83
83
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
@@ -145,7 +145,7 @@ modal/requirements/2024.10.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddR
145
145
  modal/requirements/PREVIEW.txt,sha256=qD-5cVIVM9wXesJ6JC89Ew-3m2KjEElUz3jaw_MddRo,296
146
146
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
147
147
  modal/requirements/base-images.json,sha256=57vMSqzMbLBxw5tFWSaMiIkkVEps4JfX5PAtXGnkS4U,740
148
- modal-0.74.52.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
148
+ modal-0.74.54.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
149
149
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
150
150
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
151
151
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -170,9 +170,9 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
170
170
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
171
171
  modal_version/__init__.py,sha256=m94xZNWIjH8oUtJk4l9xfovzDJede2o7X-q0MHVECtM,470
172
172
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
173
- modal_version/_version_generated.py,sha256=eXSB8gCxTkcU2MxdGdT252KQWhl4kk9fKdZvDJ7V214,149
174
- modal-0.74.52.dist-info/METADATA,sha256=UWSJgolE5wO7C0lYRtNP4R5ZokML-2OHpPJWsld-FR8,2451
175
- modal-0.74.52.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
176
- modal-0.74.52.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
- modal-0.74.52.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
- modal-0.74.52.dist-info/RECORD,,
173
+ modal_version/_version_generated.py,sha256=p1a3wkeLB9g09pRIXRyXY4bpyJvEQ6gASJs0pERc5i0,149
174
+ modal-0.74.54.dist-info/METADATA,sha256=rN1sfw0v9CbEi8q2dH4tVneJJKJh4zk4s9el97jEFN4,2451
175
+ modal-0.74.54.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
176
+ modal-0.74.54.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
177
+ modal-0.74.54.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
178
+ modal-0.74.54.dist-info/RECORD,,
@@ -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 = 52 # git: 191bebc
4
+ build_number = 54 # git: 756e8cf