modal 1.1.1.dev4__py3-none-any.whl → 1.1.1.dev6__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.

Potentially problematic release.


This version of modal might be problematic. Click here for more details.

modal/_functions.py CHANGED
@@ -451,6 +451,33 @@ class _InputPlaneInvocation:
451
451
  await_response.output.result, await_response.output.data_format, control_plane_stub, self.client
452
452
  )
453
453
 
454
+ async def run_generator(self):
455
+ items_received = 0
456
+ # populated when self.run_function() completes
457
+ items_total: Union[int, None] = None
458
+ async with aclosing(
459
+ async_merge(
460
+ _stream_function_call_data(
461
+ self.client,
462
+ self.stub,
463
+ "",
464
+ variant="data_out",
465
+ attempt_token=self.attempt_token,
466
+ ),
467
+ callable_to_agen(self.run_function),
468
+ )
469
+ ) as streamer:
470
+ async for item in streamer:
471
+ if isinstance(item, api_pb2.GeneratorDone):
472
+ items_total = item.items_total
473
+ else:
474
+ yield item
475
+ items_received += 1
476
+ # The comparison avoids infinite loops if a non-deterministic generator is retried
477
+ # and produces less data in the second run than what was already sent.
478
+ if items_total is not None and items_received >= items_total:
479
+ break
480
+
454
481
  @staticmethod
455
482
  async def _get_metadata(input_plane_region: str, client: _Client) -> list[tuple[str, str]]:
456
483
  if not input_plane_region:
@@ -1544,13 +1571,24 @@ Use the `Function.get_web_url()` method instead.
1544
1571
  @live_method_gen
1545
1572
  @synchronizer.no_input_translation
1546
1573
  async def _call_generator(self, args, kwargs):
1547
- invocation = await _Invocation.create(
1548
- self,
1549
- args,
1550
- kwargs,
1551
- client=self.client,
1552
- function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC_LEGACY,
1553
- )
1574
+ invocation: Union[_Invocation, _InputPlaneInvocation]
1575
+ if self._input_plane_url:
1576
+ invocation = await _InputPlaneInvocation.create(
1577
+ self,
1578
+ args,
1579
+ kwargs,
1580
+ client=self.client,
1581
+ input_plane_url=self._input_plane_url,
1582
+ input_plane_region=self._input_plane_region,
1583
+ )
1584
+ else:
1585
+ invocation = await _Invocation.create(
1586
+ self,
1587
+ args,
1588
+ kwargs,
1589
+ client=self.client,
1590
+ function_call_invocation_type=api_pb2.FUNCTION_CALL_INVOCATION_TYPE_SYNC_LEGACY,
1591
+ )
1554
1592
  async for res in invocation.run_generator():
1555
1593
  yield res
1556
1594
 
@@ -385,9 +385,16 @@ def callable_has_non_self_non_default_params(f: Callable[..., Any]) -> bool:
385
385
 
386
386
 
387
387
  async def _stream_function_call_data(
388
- client, stub, function_call_id: str, variant: Literal["data_in", "data_out"]
388
+ client,
389
+ stub,
390
+ function_call_id: Optional[str],
391
+ variant: Literal["data_in", "data_out"],
392
+ attempt_token: Optional[str] = None,
389
393
  ) -> AsyncGenerator[Any, None]:
390
394
  """Read from the `data_in` or `data_out` stream of a function call."""
395
+ if function_call_id is None and attempt_token is None:
396
+ raise ValueError("function_call_id or attempt_token is required for data_out stream")
397
+
391
398
  if stub is None:
392
399
  stub = client.stub
393
400
 
@@ -405,7 +412,11 @@ async def _stream_function_call_data(
405
412
  raise ValueError(f"Invalid variant {variant}")
406
413
 
407
414
  while True:
408
- req = api_pb2.FunctionCallGetDataRequest(function_call_id=function_call_id, last_index=last_index)
415
+ req = api_pb2.FunctionCallGetDataRequest(
416
+ function_call_id=function_call_id,
417
+ last_index=last_index,
418
+ attempt_token=attempt_token,
419
+ )
409
420
  try:
410
421
  async for chunk in stub_fn.unary_stream(req):
411
422
  if chunk.index <= last_index:
modal/client.pyi CHANGED
@@ -33,7 +33,7 @@ class _Client:
33
33
  server_url: str,
34
34
  client_type: int,
35
35
  credentials: typing.Optional[tuple[str, str]],
36
- version: str = "1.1.1.dev4",
36
+ version: str = "1.1.1.dev6",
37
37
  ):
38
38
  """mdmd:hidden
39
39
  The Modal client object is not intended to be instantiated directly by users.
@@ -163,7 +163,7 @@ class Client:
163
163
  server_url: str,
164
164
  client_type: int,
165
165
  credentials: typing.Optional[tuple[str, str]],
166
- version: str = "1.1.1.dev4",
166
+ version: str = "1.1.1.dev6",
167
167
  ):
168
168
  """mdmd:hidden
169
169
  The Modal client object is not intended to be instantiated directly by users.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: modal
3
- Version: 1.1.1.dev4
3
+ Version: 1.1.1.dev6
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=_QKM87tdYwcALSGth8a0-9qXl02fZK6zMfEGEoYz7eA,1007
5
5
  modal/_container_entrypoint.py,sha256=1qBMNY_E9ICC_sRCtillMxmKPsmxJl1J0_qOAG8rH-0,28288
6
- modal/_functions.py,sha256=sfE0cYRMGIr22zhCNGH2VBVLuuxQx4WNM7h1LqdTYNI,80869
6
+ modal/_functions.py,sha256=AjaKmH9hz_ii9VxdxPj4OGP5Hzjgq4iMCEJmw5R9ETg,82388
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=vzRWhAcFJDM8ZmiUSDgSj9gJhLZJA-wjLVvTl984N4A,11295
@@ -22,7 +22,7 @@ modal/app.py,sha256=BBR2NmGzZbFGfhKAmtzllD0o4TbVDBbOEs0O2ysSdQo,48277
22
22
  modal/app.pyi,sha256=h6JtBA6a7wobdZAuS3QuXrWCUZqfyKPuGV3XdjCqT3k,43753
23
23
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
24
24
  modal/client.py,sha256=pBSZ7lv5dezIL9U9H4tpE0Yz6qA1n0NoNbnJ3KCQMMA,18252
25
- modal/client.pyi,sha256=Cn1yHzML2_Ob9_OujCEM52hIVuWHGNsA7bvHnAqylDQ,15388
25
+ modal/client.pyi,sha256=shwOM1cRURg_svEKF7KfRLQsiPdYlO_yor3R7HMfsJg,15388
26
26
  modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
27
27
  modal/cloud_bucket_mount.pyi,sha256=-qSfYAQvIoO_l2wsCCGTG5ZUwQieNKXdAO00yP1-LYU,7394
28
28
  modal/cls.py,sha256=7A0xGnugQzm8dOfnKMjLjtqekRlRtQ0jPFRYgq6xdUM,40018
@@ -97,7 +97,7 @@ modal/_utils/blob_utils.py,sha256=v2NAQVVGx1AQjHQ7-2T64x5rYtwjFFykxDXb-0grrzA,21
97
97
  modal/_utils/bytes_io_segment_payload.py,sha256=vaXPq8b52-x6G2hwE7SrjS58pg_aRm7gV3bn3yjmTzQ,4261
98
98
  modal/_utils/deprecation.py,sha256=-Bgg7jZdcJU8lROy18YyVnQYbM8hue-hVmwJqlWAGH0,5504
99
99
  modal/_utils/docker_utils.py,sha256=h1uETghR40mp_y3fSWuZAfbIASH1HMzuphJHghAL6DU,3722
100
- modal/_utils/function_utils.py,sha256=mFdEKMAgMC_1jgnH9_-0N0DgIlrIlKO6bBeseWbM3TE,27026
100
+ modal/_utils/function_utils.py,sha256=9QIDlMpSKh3dH1lNZxTYIkTuGdt3WdiPrESzMhCwOFE,27320
101
101
  modal/_utils/git_utils.py,sha256=qtUU6JAttF55ZxYq51y55OR58B0tDPZsZWK5dJe6W5g,3182
102
102
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
103
103
  modal/_utils/grpc_utils.py,sha256=HBZdMcBHCk6uozILYTjGnR0mV8fg7WOdJldoyZ-ZhSg,10137
@@ -151,7 +151,7 @@ modal/requirements/2025.06.txt,sha256=KxDaVTOwatHvboDo4lorlgJ7-n-MfAwbPwxJ0zcJqr
151
151
  modal/requirements/PREVIEW.txt,sha256=KxDaVTOwatHvboDo4lorlgJ7-n-MfAwbPwxJ0zcJqrs,312
152
152
  modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,854
153
153
  modal/requirements/base-images.json,sha256=JYSDAgHTl-WrV_TZW5icY-IJEnbe2eQ4CZ_KN6EOZKU,1304
154
- modal-1.1.1.dev4.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
154
+ modal-1.1.1.dev6.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
155
155
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
156
156
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
157
157
  modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
@@ -174,10 +174,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
174
174
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
175
175
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
176
176
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
177
- modal_version/__init__.py,sha256=7l0gBNbxYTxFEtanxGB_DQR1WiHDd4JbDIMYjuXVxn0,120
177
+ modal_version/__init__.py,sha256=Pss9B3-pcb6UOAvatY6lxHmP4KK6ABEjGqwppssJcqU,120
178
178
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
179
- modal-1.1.1.dev4.dist-info/METADATA,sha256=8lO94lXYPCi3v2Sfs35lySEOMSljVUSECSxN7_8p_OA,2461
180
- modal-1.1.1.dev4.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
181
- modal-1.1.1.dev4.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
182
- modal-1.1.1.dev4.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
183
- modal-1.1.1.dev4.dist-info/RECORD,,
179
+ modal-1.1.1.dev6.dist-info/METADATA,sha256=KdpHgleqGBzAzBtAo8QqcoVOm6qGx98UPQk5U_vdDcw,2461
180
+ modal-1.1.1.dev6.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
181
+ modal-1.1.1.dev6.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
182
+ modal-1.1.1.dev6.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
183
+ modal-1.1.1.dev6.dist-info/RECORD,,
modal_version/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # Copyright Modal Labs 2025
2
2
  """Supplies the current version of the modal client library."""
3
3
 
4
- __version__ = "1.1.1.dev4"
4
+ __version__ = "1.1.1.dev6"