modal 0.71.3__py3-none-any.whl → 0.71.7__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.
@@ -17,7 +17,14 @@ from modal_proto import api_pb2
17
17
  from .._serialization import deserialize, deserialize_data_format, serialize
18
18
  from .._traceback import append_modal_tb
19
19
  from ..config import config, logger
20
- from ..exception import DeserializationError, ExecutionError, FunctionTimeoutError, InvalidError, RemoteError
20
+ from ..exception import (
21
+ DeserializationError,
22
+ ExecutionError,
23
+ FunctionTimeoutError,
24
+ InternalFailure,
25
+ InvalidError,
26
+ RemoteError,
27
+ )
21
28
  from ..mount import ROOT_DIR, _is_modal_path, _Mount
22
29
  from .blob_utils import MAX_OBJECT_SIZE_BYTES, blob_download, blob_upload
23
30
  from .grpc_utils import RETRYABLE_GRPC_STATUS_CODES
@@ -463,6 +470,8 @@ async def _process_result(result: api_pb2.GenericResult, data_format: int, stub,
463
470
 
464
471
  if result.status == api_pb2.GenericResult.GENERIC_STATUS_TIMEOUT:
465
472
  raise FunctionTimeoutError(result.exception)
473
+ elif result.status == api_pb2.GenericResult.GENERIC_STATUS_INTERNAL_FAILURE:
474
+ raise InternalFailure(result.exception)
466
475
  elif result.status != api_pb2.GenericResult.GENERIC_STATUS_SUCCESS:
467
476
  if data:
468
477
  try:
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.71.3"
29
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.71.7"
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.71.3"
84
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.71.7"
85
85
  ): ...
86
86
  def is_closed(self) -> bool: ...
87
87
  @property
modal/exception.py CHANGED
@@ -108,6 +108,12 @@ class ServerWarning(UserWarning):
108
108
  """Warning originating from the Modal server and re-issued in client code."""
109
109
 
110
110
 
111
+ class InternalFailure(Error):
112
+ """
113
+ Retriable internal error.
114
+ """
115
+
116
+
111
117
  class _CliUserExecutionError(Exception):
112
118
  """mdmd:hidden
113
119
  Private wrapper for exceptions during when importing or running stubs from the CLI.
modal/functions.py CHANGED
@@ -59,7 +59,14 @@ from .call_graph import InputInfo, _reconstruct_call_graph
59
59
  from .client import _Client
60
60
  from .cloud_bucket_mount import _CloudBucketMount, cloud_bucket_mounts_to_proto
61
61
  from .config import config
62
- from .exception import ExecutionError, FunctionTimeoutError, InvalidError, NotFoundError, OutputExpiredError
62
+ from .exception import (
63
+ ExecutionError,
64
+ FunctionTimeoutError,
65
+ InternalFailure,
66
+ InvalidError,
67
+ NotFoundError,
68
+ OutputExpiredError,
69
+ )
63
70
  from .gpu import GPU_T, parse_gpu_config
64
71
  from .image import _Image
65
72
  from .mount import _get_client_mount, _Mount, get_auto_mounts
@@ -174,7 +181,7 @@ class _Invocation:
174
181
  return _Invocation(client.stub, function_call_id, client, retry_context)
175
182
 
176
183
  async def pop_function_call_outputs(
177
- self, timeout: Optional[float], clear_on_success: bool
184
+ self, timeout: Optional[float], clear_on_success: bool, input_jwts: Optional[list[str]] = None
178
185
  ) -> api_pb2.FunctionGetOutputsResponse:
179
186
  t0 = time.time()
180
187
  if timeout is None:
@@ -190,6 +197,7 @@ class _Invocation:
190
197
  last_entry_id="0-0",
191
198
  clear_on_success=clear_on_success,
192
199
  requested_at=time.time(),
200
+ input_jwts=input_jwts,
193
201
  )
194
202
  response: api_pb2.FunctionGetOutputsResponse = await retry_transient_errors(
195
203
  self.stub.FunctionGetOutputs,
@@ -219,10 +227,14 @@ class _Invocation:
219
227
  request,
220
228
  )
221
229
 
222
- async def _get_single_output(self) -> Any:
230
+ async def _get_single_output(self, expected_jwt: Optional[str] = None) -> Any:
223
231
  # waits indefinitely for a single result for the function, and clear the outputs buffer after
224
232
  item: api_pb2.FunctionGetOutputsItem = (
225
- await self.pop_function_call_outputs(timeout=None, clear_on_success=True)
233
+ await self.pop_function_call_outputs(
234
+ timeout=None,
235
+ clear_on_success=True,
236
+ input_jwts=[expected_jwt] if expected_jwt else None,
237
+ )
226
238
  ).outputs[0]
227
239
  return await _process_result(item.result, item.data_format, self.stub, self.client)
228
240
 
@@ -242,9 +254,12 @@ class _Invocation:
242
254
 
243
255
  while True:
244
256
  try:
245
- return await self._get_single_output()
257
+ return await self._get_single_output(ctx.input_jwt)
246
258
  except (UserCodeException, FunctionTimeoutError) as exc:
247
259
  await user_retry_manager.raise_or_sleep(exc)
260
+ except InternalFailure:
261
+ # For system failures on the server, we retry immediately.
262
+ pass
248
263
  await self._retry_input()
249
264
 
250
265
  async def poll_function(self, timeout: Optional[float] = None):
modal/functions.pyi CHANGED
@@ -61,10 +61,10 @@ class _Invocation:
61
61
  function: _Function, args, kwargs, *, client: modal.client._Client, function_call_invocation_type: int
62
62
  ) -> _Invocation: ...
63
63
  async def pop_function_call_outputs(
64
- self, timeout: typing.Optional[float], clear_on_success: bool
64
+ self, timeout: typing.Optional[float], clear_on_success: bool, input_jwts: typing.Optional[list[str]] = None
65
65
  ) -> modal_proto.api_pb2.FunctionGetOutputsResponse: ...
66
66
  async def _retry_input(self) -> None: ...
67
- async def _get_single_output(self) -> typing.Any: ...
67
+ async def _get_single_output(self, expected_jwt: typing.Optional[str] = None) -> typing.Any: ...
68
68
  async def run_function(self) -> typing.Any: ...
69
69
  async def poll_function(self, timeout: typing.Optional[float] = None): ...
70
70
  def run_generator(self): ...
modal/image.py CHANGED
@@ -832,6 +832,24 @@ class _Image(_Object, type_prefix="im"):
832
832
  ),
833
833
  )
834
834
 
835
+ @staticmethod
836
+ async def from_id(image_id: str, client: Optional[_Client] = None) -> "_Image":
837
+ """Construct an Image from an id and look up the Image result.
838
+
839
+ The ID of an Image object can be accessed using `.object_id`.
840
+ """
841
+ if client is None:
842
+ client = await _Client.from_env()
843
+
844
+ async def _load(self: _Image, resolver: Resolver, existing_object_id: Optional[str]):
845
+ resp = await retry_transient_errors(client.stub.ImageFromId, api_pb2.ImageFromIdRequest(image_id=image_id))
846
+ self._hydrate(resp.image_id, resolver.client, resp.metadata)
847
+
848
+ rep = "Image()"
849
+ obj = _Image._from_loader(_load, rep)
850
+
851
+ return obj
852
+
835
853
  def pip_install(
836
854
  self,
837
855
  *packages: Union[str, list[str]], # A list of Python packages, eg. ["numpy", "matplotlib>=3.5.0"]
modal/image.pyi CHANGED
@@ -126,6 +126,8 @@ class _Image(modal.object._Object):
126
126
  remote_path: typing.Union[str, pathlib.Path] = ".",
127
127
  ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]] = [],
128
128
  ) -> _Image: ...
129
+ @staticmethod
130
+ async def from_id(image_id: str, client: typing.Optional[modal.client._Client] = None) -> _Image: ...
129
131
  def pip_install(
130
132
  self,
131
133
  *packages: typing.Union[str, list[str]],
@@ -387,6 +389,13 @@ class Image(modal.object.Object):
387
389
  remote_path: typing.Union[str, pathlib.Path] = ".",
388
390
  ignore: typing.Union[collections.abc.Sequence[str], typing.Callable[[pathlib.Path], bool]] = [],
389
391
  ) -> Image: ...
392
+
393
+ class __from_id_spec(typing_extensions.Protocol):
394
+ def __call__(self, image_id: str, client: typing.Optional[modal.client.Client] = None) -> Image: ...
395
+ async def aio(self, image_id: str, client: typing.Optional[modal.client.Client] = None) -> Image: ...
396
+
397
+ from_id: __from_id_spec
398
+
390
399
  def pip_install(
391
400
  self,
392
401
  *packages: typing.Union[str, list[str]],
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.71.3
3
+ Version: 0.71.7
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=vEE0cK5QPF6_cdW5AJvcuWxz5KmeprHwBEtlDkVRHgE,45582
19
19
  modal/app.pyi,sha256=Gx7gxjfQ70sxhbwfpx1VjvzEON-ZEMTJ_Vy8qt0oQvo,25302
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=g36AUvqxWl-M3qym800n9bscsG3V5qM0scNEJ0nBWlk,7278
22
+ modal/client.pyi,sha256=BemCZNYj-Ol_UF2iZJVU15N3VIKhxO2CPtgxitRJWw4,7278
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=3hjb0JcoPjxKZNeK22f5rR43bZRBjoRI7_EMZXY7YrE,31172
@@ -31,16 +31,16 @@ modal/dict.py,sha256=ei9jsA5iTj4UFGPJxTAed6vjd49W47ezDtj0koUmVts,12497
31
31
  modal/dict.pyi,sha256=VmbzxltA2vFlIHZCxpNGtd-ieXwcUwdw3iyy3WCweqU,7115
32
32
  modal/environments.py,sha256=wbv9ttFCbzATGfwcmvYiG608PfHovx0AQmawsg-jmic,6660
33
33
  modal/environments.pyi,sha256=rF7oaaELoSNuoD6qImGnIbuGPtgWwR5SlcExyYJ61hQ,3515
34
- modal/exception.py,sha256=GEV6xMnVnkle0gsFZVLB4B7cUMyw8HzVDvAvPr34ZV4,5185
34
+ modal/exception.py,sha256=4JyO-SACaLNDe2QC48EjsK8GMkZ8AgEurZ8j1YdRu8E,5263
35
35
  modal/experimental.py,sha256=npfKbyMpI41uZZs9HW_QiB3E4ykWfDXZbACXXbw6qeA,2385
36
36
  modal/file_io.py,sha256=ZR8VBCDsDt5uB9TNN9XbEh7sniJzM_5YL47m8WP0m5c,19617
37
37
  modal/file_io.pyi,sha256=79Fg75BjmMEeCX0Lx-Z8C4XSNPCotwNdK6ZLIDFm2f4,9770
38
38
  modal/file_pattern_matcher.py,sha256=LaI7Paxg0xR9D-D7Tgc60xR0w1KZee22LjGbFie1Vms,5571
39
- modal/functions.py,sha256=aXXXr3rk7BCeh5OWMvxGksGm8FQoYCyrBDGV74FPoPE,67827
40
- modal/functions.pyi,sha256=oMmcExtQxHwPej06jQ3uBe1tUlSR3VbAx7u3Vm-Ohhg,25317
39
+ modal/functions.py,sha256=3uJPbrEAWhpFfLfUnoRjGmvEUC-_wVh-8yNJBx8eVeM,68249
40
+ modal/functions.pyi,sha256=3ESJ61f8oEDycDmrpnuNB2vjFKuLBG_aqyliXPTdY7M,25407
41
41
  modal/gpu.py,sha256=MTxj6ql8EpgfBg8YmZ5a1cLznyuZFssX1qXbEX4LKVM,7503
42
- modal/image.py,sha256=Krvcsclomp9YsqSNwFj2FoAyg10OvU47RDnsNCwjGbQ,84550
43
- modal/image.pyi,sha256=1fgGvsL5Rb0Sa-_2OCgIyJ_QgHcL0_9MWD_oY7cyFFM,24937
42
+ modal/image.py,sha256=oKqqLhc3Ap2XMG5MKVlERKkMTwJPkNMNcSzxoZh4zuw,85259
43
+ modal/image.pyi,sha256=Pa1_LVr3FyNsnu_MhBO08fBgCeLazTEe25phYdu0bzE,25365
44
44
  modal/io_streams.py,sha256=Xxc5grJiO94nBA48FFWH3S3g6SPR0xFVgZ_DZ1oFmvI,14428
45
45
  modal/io_streams.pyi,sha256=bCCVSxkMcosYd8O3PQDDwJw7TQ8JEcnYonLJ5t27TQs,4804
46
46
  modal/io_streams_helper.py,sha256=B5Ui56ph7LkRpZX0tAF80Q-gOMsvPPLx5bpIPX0kgDc,1772
@@ -90,7 +90,7 @@ modal/_utils/blob_utils.py,sha256=N66LtZI8PpCkZ7maA7GLW5CAmYUoNJdG-GjaAUR4_NQ,14
90
90
  modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
91
91
  modal/_utils/deprecation.py,sha256=dycySRBxyZf3ITzEqPNM6MxXTk9-0VVLA8oCPQ5j_Os,3426
92
92
  modal/_utils/docker_utils.py,sha256=FLz1q0YicL6i_Iq-4inkgDVFfEINVG6YPT2s_P6ly0o,2264
93
- modal/_utils/function_utils.py,sha256=4LYFbNY5aHc96QitwP4Ty-dBl45SD1HjfZrvBFUF-ko,25343
93
+ modal/_utils/function_utils.py,sha256=q68HhFH16MwhHRnGD8jvIgqDjduRQVp3a_qMWXPyrgU,25518
94
94
  modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
95
95
  modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
96
96
  modal/_utils/hash_utils.py,sha256=zg3J6OGxTFGSFri1qQ12giDz90lWk8bzaxCTUCRtiX4,3034
@@ -149,13 +149,13 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
149
149
  modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
150
150
  modal_global_objects/mounts/python_standalone.py,sha256=SL_riIxpd8mP4i4CLDCWiFFNj0Ltknm9c_UIGfX5d60,1836
151
151
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
152
- modal_proto/api.proto,sha256=B7UvK-bWmAcBuqMMWmUBubAdstblzWgMqmUUco-1fEE,79926
153
- modal_proto/api_grpc.py,sha256=AiUCWTHQQFC9RFB_XuavB_OnVMr7GJMRLEwcf4FSTio,102088
154
- modal_proto/api_pb2.py,sha256=EEvj9MRiYAGiGP9lZqkQs7TIP7eepBKhAtL0eJAjpRM,293669
155
- modal_proto/api_pb2.pyi,sha256=kdIvhfjCdoMP-uLw1MvQOIwE3m2xAenexGCXuo-SX0M,392331
156
- modal_proto/api_pb2_grpc.py,sha256=dFxVTgosyp_o8NCI1JIySlR0qTzG4ILm9mq8MNo4jYc,220795
157
- modal_proto/api_pb2_grpc.pyi,sha256=yJgwEl-1YU42m7MU_Sm5SK3rB9xdkisPk3nZB-mlqkg,51463
158
- modal_proto/modal_api_grpc.py,sha256=MyNzvY_WqB7QTMOQjoH6lsqCY5-6_s1HP-knsOSjANs,13640
152
+ modal_proto/api.proto,sha256=ERfCFygQvpd09LyVtpZ-eInPfJ4p6UIDh_z3za_rbsw,80174
153
+ modal_proto/api_grpc.py,sha256=MLsxlZXikcv36aSs0iVZywIOANMWstVZMWJGQTDjdM0,102823
154
+ modal_proto/api_pb2.py,sha256=dJJ88RIIPlwyTBQk9rKfSfbAxeZXDZn7FpszS6mF0Qs,294984
155
+ modal_proto/api_pb2.pyi,sha256=I1cHME11tDMerj_8DzHF2SEwN1QorEfdjziW3_v-omA,393699
156
+ modal_proto/api_pb2_grpc.py,sha256=4d5SwJPLldCqqHz_BGqmJLlX-BMG592WFKUQ6IBg5rg,222415
157
+ modal_proto/api_pb2_grpc.pyi,sha256=C4c3jndI6TKEgVnx3vAmT86In4T9JKmB1CImiye_aQk,51822
158
+ modal_proto/modal_api_grpc.py,sha256=eeH1vHXgwO768tM7DXqvj-P37u15SI00gZtm8_EK15I,13732
159
159
  modal_proto/modal_options_grpc.py,sha256=qJ1cuwA54oRqrdTyPTbvfhFZYd9HhJKK5UCwt523r3Y,120
160
160
  modal_proto/options.proto,sha256=a-siq4swVbZPfaFRXAipRZzGP2bq8OsdUvjlyzAeodQ,488
161
161
  modal_proto/options_grpc.py,sha256=M18X3d-8F_cNYSVM3I25dUTO5rZ0rd-vCCfynfh13Nc,125
@@ -166,10 +166,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
166
166
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
167
167
  modal_version/__init__.py,sha256=BEBWj9tcbFUwzEjUrqly601rauw5cYsHdcmJHs3iu0s,470
168
168
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
169
- modal_version/_version_generated.py,sha256=GVYfkFxvwUpfzdmWO8cxk57L2ZM-JzQISmGvWDKjz_o,148
170
- modal-0.71.3.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
171
- modal-0.71.3.dist-info/METADATA,sha256=V79Ksg3YCSNCVVjx5Sn60NhaB0o4DMJ7BbnBtQ3lbzU,2328
172
- modal-0.71.3.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
173
- modal-0.71.3.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
174
- modal-0.71.3.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
175
- modal-0.71.3.dist-info/RECORD,,
169
+ modal_version/_version_generated.py,sha256=vCubBvI9-d34zmRrXH9kK-02zZQnqA3cVMw5ONOUPds,148
170
+ modal-0.71.7.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
171
+ modal-0.71.7.dist-info/METADATA,sha256=a3pklm2HmEel6rdqBnRdP8yR4-pVDyljfp9i_JULRvU,2328
172
+ modal-0.71.7.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
173
+ modal-0.71.7.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
174
+ modal-0.71.7.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
175
+ modal-0.71.7.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -298,6 +298,7 @@ message AppDeploymentHistory {
298
298
  string client_version = 3;
299
299
  double deployed_at = 4;
300
300
  string deployed_by = 5;
301
+ string deployed_by_avatar_url = 9;
301
302
  string tag = 6;
302
303
  uint32 rollback_version = 7;
303
304
  bool rollback_allowed = 8;
@@ -1730,6 +1731,15 @@ message ImageContextFile {
1730
1731
  bytes data = 2;
1731
1732
  }
1732
1733
 
1734
+ message ImageFromIdRequest {
1735
+ string image_id = 1;
1736
+ }
1737
+
1738
+ message ImageFromIdResponse {
1739
+ string image_id = 1;
1740
+ ImageMetadata metadata = 2;
1741
+ }
1742
+
1733
1743
  message ImageGetOrCreateRequest {
1734
1744
  Image image = 2;
1735
1745
  string app_id = 4 [ (modal.options.audit_target_attr) = true ];
@@ -2797,6 +2807,7 @@ service ModalClient {
2797
2807
  rpc FunctionUpdateSchedulingParams(FunctionUpdateSchedulingParamsRequest) returns (FunctionUpdateSchedulingParamsResponse);
2798
2808
 
2799
2809
  // Images
2810
+ rpc ImageFromId(ImageFromIdRequest) returns (ImageFromIdResponse);
2800
2811
  rpc ImageGetOrCreate(ImageGetOrCreateRequest) returns (ImageGetOrCreateResponse);
2801
2812
  rpc ImageJoinStreaming(ImageJoinStreamingRequest) returns (stream ImageJoinStreamingResponse);
2802
2813
 
modal_proto/api_grpc.py CHANGED
@@ -309,6 +309,10 @@ class ModalClientBase(abc.ABC):
309
309
  async def FunctionUpdateSchedulingParams(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionUpdateSchedulingParamsRequest, modal_proto.api_pb2.FunctionUpdateSchedulingParamsResponse]') -> None:
310
310
  pass
311
311
 
312
+ @abc.abstractmethod
313
+ async def ImageFromId(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.ImageFromIdRequest, modal_proto.api_pb2.ImageFromIdResponse]') -> None:
314
+ pass
315
+
312
316
  @abc.abstractmethod
313
317
  async def ImageGetOrCreate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.ImageGetOrCreateRequest, modal_proto.api_pb2.ImageGetOrCreateResponse]') -> None:
314
318
  pass
@@ -989,6 +993,12 @@ class ModalClientBase(abc.ABC):
989
993
  modal_proto.api_pb2.FunctionUpdateSchedulingParamsRequest,
990
994
  modal_proto.api_pb2.FunctionUpdateSchedulingParamsResponse,
991
995
  ),
996
+ '/modal.client.ModalClient/ImageFromId': grpclib.const.Handler(
997
+ self.ImageFromId,
998
+ grpclib.const.Cardinality.UNARY_UNARY,
999
+ modal_proto.api_pb2.ImageFromIdRequest,
1000
+ modal_proto.api_pb2.ImageFromIdResponse,
1001
+ ),
992
1002
  '/modal.client.ModalClient/ImageGetOrCreate': grpclib.const.Handler(
993
1003
  self.ImageGetOrCreate,
994
1004
  grpclib.const.Cardinality.UNARY_UNARY,
@@ -1793,6 +1803,12 @@ class ModalClientStub:
1793
1803
  modal_proto.api_pb2.FunctionUpdateSchedulingParamsRequest,
1794
1804
  modal_proto.api_pb2.FunctionUpdateSchedulingParamsResponse,
1795
1805
  )
1806
+ self.ImageFromId = grpclib.client.UnaryUnaryMethod(
1807
+ channel,
1808
+ '/modal.client.ModalClient/ImageFromId',
1809
+ modal_proto.api_pb2.ImageFromIdRequest,
1810
+ modal_proto.api_pb2.ImageFromIdResponse,
1811
+ )
1796
1812
  self.ImageGetOrCreate = grpclib.client.UnaryUnaryMethod(
1797
1813
  channel,
1798
1814
  '/modal.client.ModalClient/ImageGetOrCreate',