modal 0.69.0__py3-none-any.whl → 0.69.2__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.
@@ -464,7 +464,7 @@ def main(container_args: api_pb2.ContainerArguments, client: Client):
464
464
  batch_wait_ms = function_def.batch_linger_ms or 0
465
465
 
466
466
  # Get ids and metadata for objects (primarily functions and classes) on the app
467
- container_app: RunningApp = container_io_manager.get_app_objects()
467
+ container_app: RunningApp = container_io_manager.get_app_objects(container_args.app_layout)
468
468
 
469
469
  # Initialize objects on the app.
470
470
  # This is basically only functions and classes - anything else is deprecated and will be unsupported soon
@@ -21,7 +21,6 @@ from typing import (
21
21
  )
22
22
 
23
23
  from google.protobuf.empty_pb2 import Empty
24
- from google.protobuf.message import Message
25
24
  from grpclib import Status
26
25
  from synchronicity.async_wrap import asynccontextmanager
27
26
 
@@ -31,12 +30,12 @@ from modal._traceback import extract_traceback, print_exception
31
30
  from modal._utils.async_utils import TaskContext, asyncify, synchronize_api, synchronizer
32
31
  from modal._utils.blob_utils import MAX_OBJECT_SIZE_BYTES, blob_download, blob_upload
33
32
  from modal._utils.function_utils import _stream_function_call_data
34
- from modal._utils.grpc_utils import get_proto_oneof, retry_transient_errors
33
+ from modal._utils.grpc_utils import retry_transient_errors
35
34
  from modal._utils.package_utils import parse_major_minor_version
36
35
  from modal.client import HEARTBEAT_INTERVAL, HEARTBEAT_TIMEOUT, _Client
37
36
  from modal.config import config, logger
38
37
  from modal.exception import ClientClosed, InputCancellation, InvalidError, SerializationError
39
- from modal.running_app import RunningApp
38
+ from modal.running_app import RunningApp, running_app_from_layout
40
39
  from modal_proto import api_pb2
41
40
 
42
41
  if TYPE_CHECKING:
@@ -450,25 +449,19 @@ class _ContainerIOManager:
450
449
 
451
450
  await asyncio.sleep(DYNAMIC_CONCURRENCY_INTERVAL_SECS)
452
451
 
453
- async def get_app_objects(self) -> RunningApp:
454
- req = api_pb2.AppGetObjectsRequest(app_id=self.app_id, include_unindexed=True, only_class_function=True)
455
- resp = await retry_transient_errors(self._client.stub.AppGetObjects, req)
456
- logger.debug(f"AppGetObjects received {len(resp.items)} objects for app {self.app_id}")
452
+ async def get_app_objects(self, app_layout: api_pb2.AppLayout) -> RunningApp:
453
+ if len(app_layout.objects) == 0:
454
+ # TODO(erikbern): this is a temporary fallback until we flip the switch and the worker provides arguments
455
+ req = api_pb2.AppGetLayoutRequest(app_id=self.app_id)
456
+ resp = await retry_transient_errors(self._client.stub.AppGetLayout, req)
457
+ app_layout = resp.app_layout
458
+ logger.debug(f"AppGetLayout received {len(app_layout.objects)} objects for app {self.app_id}")
457
459
 
458
- tag_to_object_id = {}
459
- object_handle_metadata = {}
460
- for item in resp.items:
461
- handle_metadata: Optional[Message] = get_proto_oneof(item.object, "handle_metadata_oneof")
462
- object_handle_metadata[item.object.object_id] = handle_metadata
463
- if item.tag:
464
- tag_to_object_id[item.tag] = item.object.object_id
465
-
466
- return RunningApp(
460
+ return running_app_from_layout(
467
461
  self.app_id,
462
+ app_layout,
463
+ self._client,
468
464
  environment_name=self._environment_name,
469
- tag_to_object_id=tag_to_object_id,
470
- object_handle_metadata=object_handle_metadata,
471
- client=self._client,
472
465
  )
473
466
 
474
467
  async def get_serialized_function(self) -> tuple[Optional[Any], Optional[Callable[..., Any]]]:
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.69.0"
29
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.69.2"
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.69.0"
84
+ self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.69.2"
85
85
  ): ...
86
86
  def is_closed(self) -> bool: ...
87
87
  @property
modal/runner.py CHANGED
@@ -30,7 +30,7 @@ from .exception import InteractiveTimeoutError, InvalidError, RemoteError, _CliU
30
30
  from .functions import _Function
31
31
  from .object import _get_environment_name, _Object
32
32
  from .output import _get_output_manager, enable_output
33
- from .running_app import RunningApp
33
+ from .running_app import RunningApp, running_app_from_layout
34
34
  from .sandbox import _Sandbox
35
35
  from .secret import _Secret
36
36
  from .stream_type import StreamType
@@ -54,15 +54,19 @@ async def _heartbeat(client: _Client, app_id: str) -> None:
54
54
 
55
55
  async def _init_local_app_existing(client: _Client, existing_app_id: str, environment_name: str) -> RunningApp:
56
56
  # Get all the objects first
57
- obj_req = api_pb2.AppGetObjectsRequest(app_id=existing_app_id, only_class_function=True)
57
+ obj_req = api_pb2.AppGetLayoutRequest(app_id=existing_app_id)
58
58
  obj_resp, _ = await gather_cancel_on_exc(
59
- retry_transient_errors(client.stub.AppGetObjects, obj_req),
59
+ retry_transient_errors(client.stub.AppGetLayout, obj_req),
60
60
  # Cache the environment associated with the app now as we will use it later
61
61
  _get_environment_cached(environment_name, client),
62
62
  )
63
63
  app_page_url = f"https://modal.com/apps/{existing_app_id}" # TODO (elias): this should come from the backend
64
- object_ids = {item.tag: item.object.object_id for item in obj_resp.items}
65
- return RunningApp(existing_app_id, app_page_url=app_page_url, tag_to_object_id=object_ids, client=client)
64
+ return running_app_from_layout(
65
+ existing_app_id,
66
+ obj_resp.app_layout,
67
+ client,
68
+ app_page_url=app_page_url,
69
+ )
66
70
 
67
71
 
68
72
  async def _init_local_app_new(
modal/running_app.py CHANGED
@@ -4,16 +4,42 @@ from typing import Optional
4
4
 
5
5
  from google.protobuf.message import Message
6
6
 
7
+ from modal._utils.grpc_utils import get_proto_oneof
8
+ from modal_proto import api_pb2
9
+
7
10
  from .client import _Client
8
11
 
9
12
 
10
13
  @dataclass
11
14
  class RunningApp:
12
15
  app_id: str
16
+ client: _Client
13
17
  environment_name: Optional[str] = None
14
18
  app_page_url: Optional[str] = None
15
19
  app_logs_url: Optional[str] = None
16
20
  tag_to_object_id: dict[str, str] = field(default_factory=dict)
17
21
  object_handle_metadata: dict[str, Optional[Message]] = field(default_factory=dict)
18
22
  interactive: bool = False
19
- client: Optional[_Client] = None
23
+
24
+
25
+ def running_app_from_layout(
26
+ app_id: str,
27
+ app_layout: api_pb2.AppLayout,
28
+ client: _Client,
29
+ environment_name: Optional[str] = None,
30
+ app_page_url: Optional[str] = None,
31
+ ) -> RunningApp:
32
+ tag_to_object_id = dict(**app_layout.function_ids, **app_layout.class_ids)
33
+ object_handle_metadata = {}
34
+ for obj in app_layout.objects:
35
+ handle_metadata: Optional[Message] = get_proto_oneof(obj, "handle_metadata_oneof")
36
+ object_handle_metadata[obj.object_id] = handle_metadata
37
+
38
+ return RunningApp(
39
+ app_id,
40
+ client,
41
+ environment_name=environment_name,
42
+ tag_to_object_id=tag_to_object_id,
43
+ object_handle_metadata=object_handle_metadata,
44
+ app_page_url=app_page_url,
45
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.69.0
3
+ Version: 0.69.2
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -2,7 +2,7 @@ modal/__init__.py,sha256=3NJLLHb0TRc2tc68kf8NHzORx38GbtbZvPEWDWrQ6N4,2234
2
2
  modal/__main__.py,sha256=scYhGFqh8OJcVDo-VOxIT6CCwxOgzgflYWMnIZiMRqE,2871
3
3
  modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
4
4
  modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
5
- modal/_container_entrypoint.py,sha256=wk10vA5vRZZsVwQ0yINOLd0i-NwH7x6XbhTslumvGjo,28910
5
+ modal/_container_entrypoint.py,sha256=7EAMe-85a-uWDaRAjRy9m4nnCAmjRJnh9x7FgW_QjLU,28935
6
6
  modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
7
7
  modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
8
8
  modal/_output.py,sha256=0fWX_KQwhER--U81ys16CL-pA5A-LN20C0EZjElKGJQ,25410
@@ -19,7 +19,7 @@ modal/app.py,sha256=JWefPs4yB70BKQwSZejB_4_muhxn63cC9UmnNvpQ9XY,45526
19
19
  modal/app.pyi,sha256=FYPCEJNhof4YF6HIuNP_2yG6s2PgZnKW9tO1hFE6sfA,25194
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=ENRyoE3k_U_QuPDY05eVI2GtuzNXWIk-vXgehbI4WjE,7278
22
+ modal/client.pyi,sha256=8kavXFZwpujj_fyLm28-OFOfpYyDAglsImnwppyVXxQ,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
@@ -60,9 +60,9 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  modal/queue.py,sha256=zMUQtdAyqZzBg-2iAo3c3G54HLP7TEWfVhiQXLjewb4,18556
61
61
  modal/queue.pyi,sha256=gGV97pWelSSYqMV9Bl4ys3mSP7q82fS71oqSWeAwyDE,9818
62
62
  modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
63
- modal/runner.py,sha256=qfkB0OM97kb_-oP-D5KPj_jUwfd8ePUA3R_zLkjSTBQ,24586
63
+ modal/runner.py,sha256=1nPBsIfef2sOr2ebQ348EmDemvYFDhp1-_Gr3BKsjdM,24542
64
64
  modal/runner.pyi,sha256=BvMS1ZVzWSn8B8q0KnIZOJKPkN5L-i5b-USbV6SWWHQ,5177
65
- modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
65
+ modal/running_app.py,sha256=FSr0XoL4mPLPCBMj2TozWuEvcvApdY_t68nUowwf8x4,1372
66
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
@@ -78,7 +78,7 @@ modal/volume.py,sha256=T-pLxCYqmqRO6OolpAXlPxomMu0RWjti2e4kUpaj2cQ,29229
78
78
  modal/volume.pyi,sha256=eekb2dnAAwFK_NO9ciAOOTthl8NP1iAmMFrCGgjDA2k,11100
79
79
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
80
80
  modal/_runtime/asgi.py,sha256=Mjs859pSgOmtZL-YmEsSKN557v1A2Ax_5-ERgPfj55E,21920
81
- modal/_runtime/container_io_manager.py,sha256=ctgyNFiHjq1brCrabXmlurkAXjnrCeWPRvTVa735vRw,44215
81
+ modal/_runtime/container_io_manager.py,sha256=7Xyi_lKmCAsVXRmxXYMUZAQPm8Qnu0vkP_FULktFM6A,43931
82
82
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
83
83
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
84
84
  modal/_runtime/user_code_imports.py,sha256=n4CQOojzSdf0jwSKSy6MEnVX3IWl3t3Dq54-x9VS2Ds,14663
@@ -165,10 +165,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
165
165
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
166
166
  modal_version/__init__.py,sha256=aBl2c-5ZPst-0n_E9DeJEfYYSifFGrDOwo9tpDwhyK8,470
167
167
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
168
- modal_version/_version_generated.py,sha256=ej60GT5kCy2xu-Nl85c2H_C-xPKpmO4Qq9WS8px9udc,148
169
- modal-0.69.0.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
170
- modal-0.69.0.dist-info/METADATA,sha256=wbnWG0YWB7VwZLgG4dlmiSCrCNuDpJCu27lz6qrU9X4,2328
171
- modal-0.69.0.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
172
- modal-0.69.0.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
173
- modal-0.69.0.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
174
- modal-0.69.0.dist-info/RECORD,,
168
+ modal_version/_version_generated.py,sha256=tRKJkUG5jXmmMESPTZ_2SdjmPG8SWmbjeCYjD5Pc9Ek,148
169
+ modal-0.69.2.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
170
+ modal-0.69.2.dist-info/METADATA,sha256=sUCcaTOsI6EI364Y3ddMZEy6uooqrAVNnkOKbV2gLRU,2328
171
+ modal-0.69.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
172
+ modal-0.69.2.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
173
+ modal-0.69.2.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
174
+ modal-0.69.2.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 = 0 # git: 8b60408
4
+ build_number = 2 # git: ca23238
File without changes