modal 0.70.2__py3-none-any.whl → 0.71.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.
modal/runner.py CHANGED
@@ -6,7 +6,7 @@ import time
6
6
  import typing
7
7
  from collections.abc import AsyncGenerator
8
8
  from multiprocessing.synchronize import Event
9
- from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar
9
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar
10
10
 
11
11
  from grpclib import GRPCError, Status
12
12
  from synchronicity.async_wrap import asynccontextmanager
@@ -64,7 +64,6 @@ async def _init_local_app_existing(client: _Client, existing_app_id: str, enviro
64
64
  return running_app_from_layout(
65
65
  existing_app_id,
66
66
  obj_resp.app_layout,
67
- client,
68
67
  app_page_url=app_page_url,
69
68
  )
70
69
 
@@ -89,10 +88,8 @@ async def _init_local_app_new(
89
88
  logger.debug(f"Created new app with id {app_resp.app_id}")
90
89
  return RunningApp(
91
90
  app_resp.app_id,
92
- client=client,
93
91
  app_page_url=app_resp.app_page_url,
94
92
  app_logs_url=app_resp.app_logs_url,
95
- environment_name=environment_name,
96
93
  interactive=interactive,
97
94
  )
98
95
 
@@ -124,10 +121,12 @@ async def _init_local_app_from_name(
124
121
  async def _create_all_objects(
125
122
  client: _Client,
126
123
  running_app: RunningApp,
127
- indexed_objects: dict[str, _Object],
124
+ functions: dict[str, _Function],
125
+ classes: dict[str, _Cls],
128
126
  environment_name: str,
129
127
  ) -> None:
130
128
  """Create objects that have been defined but not created on the server."""
129
+ indexed_objects: dict[str, _Object] = {**functions, **classes}
131
130
  resolver = Resolver(
132
131
  client,
133
132
  environment_name=environment_name,
@@ -135,8 +134,9 @@ async def _create_all_objects(
135
134
  )
136
135
  with resolver.display():
137
136
  # Get current objects, and reset all objects
138
- tag_to_object_id = running_app.tag_to_object_id
139
- running_app.tag_to_object_id = {}
137
+ tag_to_object_id = {**running_app.function_ids, **running_app.class_ids}
138
+ running_app.function_ids = {}
139
+ running_app.class_ids = {}
140
140
 
141
141
  # Assign all objects
142
142
  for tag, obj in indexed_objects.items():
@@ -163,7 +163,12 @@ async def _create_all_objects(
163
163
  async def _load(tag, obj):
164
164
  existing_object_id = tag_to_object_id.get(tag)
165
165
  await resolver.load(obj, existing_object_id)
166
- running_app.tag_to_object_id[tag] = obj.object_id
166
+ if _Function._is_id_type(obj.object_id):
167
+ running_app.function_ids[tag] = obj.object_id
168
+ elif _Cls._is_id_type(obj.object_id):
169
+ running_app.class_ids[tag] = obj.object_id
170
+ else:
171
+ raise RuntimeError(f"Unexpected object {obj.object_id}")
167
172
 
168
173
  await TaskContext.gather(*(_load(tag, obj) for tag, obj in indexed_objects.items()))
169
174
 
@@ -172,30 +177,22 @@ async def _publish_app(
172
177
  client: _Client,
173
178
  running_app: RunningApp,
174
179
  app_state: int, # api_pb2.AppState.value
175
- indexed_objects: dict[str, _Object],
180
+ functions: dict[str, _Function],
181
+ classes: dict[str, _Cls],
176
182
  name: str = "", # Only relevant for deployments
177
183
  tag: str = "", # Only relevant for deployments
178
184
  ) -> tuple[str, list[api_pb2.Warning]]:
179
185
  """Wrapper for AppPublish RPC."""
180
186
 
181
- # Could simplify this function some changing the internal representation to use
182
- # function_ids / class_ids rather than the current tag_to_object_id (i.e. "indexed_objects")
183
- def filter_values(full_dict: dict[str, V], condition: Callable[[V], bool]) -> dict[str, V]:
184
- return {k: v for k, v in full_dict.items() if condition(v)}
185
-
186
- function_ids = filter_values(running_app.tag_to_object_id, _Function._is_id_type)
187
- class_ids = filter_values(running_app.tag_to_object_id, _Cls._is_id_type)
188
-
189
- function_objs = filter_values(indexed_objects, lambda v: v.object_id in function_ids.values())
190
- definition_ids = {obj.object_id: obj._get_metadata().definition_id for obj in function_objs.values()} # type: ignore
187
+ definition_ids = {obj.object_id: obj._get_metadata().definition_id for obj in functions.values()} # type: ignore
191
188
 
192
189
  request = api_pb2.AppPublishRequest(
193
190
  app_id=running_app.app_id,
194
191
  name=name,
195
192
  deployment_tag=tag,
196
193
  app_state=app_state, # type: ignore : should be a api_pb2.AppState.value
197
- function_ids=function_ids,
198
- class_ids=class_ids,
194
+ function_ids=running_app.function_ids,
195
+ class_ids=running_app.class_ids,
199
196
  definition_ids=definition_ids,
200
197
  )
201
198
  try:
@@ -329,13 +326,11 @@ async def _run_app(
329
326
  )
330
327
 
331
328
  try:
332
- indexed_objects = dict(**app._functions, **app._classes) # TODO(erikbern): remove
333
-
334
329
  # Create all members
335
- await _create_all_objects(client, running_app, indexed_objects, environment_name)
330
+ await _create_all_objects(client, running_app, app._functions, app._classes, environment_name)
336
331
 
337
332
  # Publish the app
338
- await _publish_app(client, running_app, app_state, indexed_objects)
333
+ await _publish_app(client, running_app, app_state, app._functions, app._classes)
339
334
  except asyncio.CancelledError as e:
340
335
  # this typically happens on sigint/ctrl-C during setup (the KeyboardInterrupt happens in the main thread)
341
336
  if output_mgr := _get_output_manager():
@@ -428,18 +423,17 @@ async def _serve_update(
428
423
  try:
429
424
  running_app: RunningApp = await _init_local_app_existing(client, existing_app_id, environment_name)
430
425
 
431
- indexed_objects = dict(**app._functions, **app._classes) # TODO(erikbern): remove
432
-
433
426
  # Create objects
434
427
  await _create_all_objects(
435
428
  client,
436
429
  running_app,
437
- indexed_objects,
430
+ app._functions,
431
+ app._classes,
438
432
  environment_name,
439
433
  )
440
434
 
441
435
  # Publish the updated app
442
- await _publish_app(client, running_app, api_pb2.APP_STATE_UNSPECIFIED, indexed_objects)
436
+ await _publish_app(client, running_app, api_pb2.APP_STATE_UNSPECIFIED, app._functions, app._classes)
443
437
 
444
438
  # Communicate to the parent process
445
439
  is_ready.set()
@@ -527,19 +521,18 @@ async def _deploy_app(
527
521
 
528
522
  tc.infinite_loop(heartbeat, sleep=HEARTBEAT_INTERVAL)
529
523
 
530
- indexed_objects = dict(**app._functions, **app._classes) # TODO(erikbern): remove
531
-
532
524
  try:
533
525
  # Create all members
534
526
  await _create_all_objects(
535
527
  client,
536
528
  running_app,
537
- indexed_objects,
529
+ app._functions,
530
+ app._classes,
538
531
  environment_name=environment_name,
539
532
  )
540
533
 
541
534
  app_url, warnings = await _publish_app(
542
- client, running_app, api_pb2.APP_STATE_DEPLOYED, indexed_objects, name, tag
535
+ client, running_app, api_pb2.APP_STATE_DEPLOYED, app._functions, app._classes, name, tag
543
536
  )
544
537
  except Exception as e:
545
538
  # Note that AppClientDisconnect only stops the app if it's still initializing, and is a no-op otherwise.
modal/runner.pyi CHANGED
@@ -1,5 +1,6 @@
1
1
  import modal.client
2
- import modal.object
2
+ import modal.cls
3
+ import modal.functions
3
4
  import modal.running_app
4
5
  import modal_proto.api_pb2
5
6
  import multiprocessing.synchronize
@@ -28,14 +29,16 @@ async def _init_local_app_from_name(
28
29
  async def _create_all_objects(
29
30
  client: modal.client._Client,
30
31
  running_app: modal.running_app.RunningApp,
31
- indexed_objects: dict[str, modal.object._Object],
32
+ functions: dict[str, modal.functions._Function],
33
+ classes: dict[str, modal.cls._Cls],
32
34
  environment_name: str,
33
35
  ) -> None: ...
34
36
  async def _publish_app(
35
37
  client: modal.client._Client,
36
38
  running_app: modal.running_app.RunningApp,
37
39
  app_state: int,
38
- indexed_objects: dict[str, modal.object._Object],
40
+ functions: dict[str, modal.functions._Function],
41
+ classes: dict[str, modal.cls._Cls],
39
42
  name: str = "",
40
43
  tag: str = "",
41
44
  ) -> tuple[str, list[modal_proto.api_pb2.Warning]]: ...
modal/running_app.py CHANGED
@@ -7,17 +7,14 @@ from google.protobuf.message import Message
7
7
  from modal._utils.grpc_utils import get_proto_oneof
8
8
  from modal_proto import api_pb2
9
9
 
10
- from .client import _Client
11
-
12
10
 
13
11
  @dataclass
14
12
  class RunningApp:
15
13
  app_id: str
16
- client: _Client
17
- environment_name: Optional[str] = None
18
14
  app_page_url: Optional[str] = None
19
15
  app_logs_url: Optional[str] = None
20
- tag_to_object_id: dict[str, str] = field(default_factory=dict)
16
+ function_ids: dict[str, str] = field(default_factory=dict)
17
+ class_ids: dict[str, str] = field(default_factory=dict)
21
18
  object_handle_metadata: dict[str, Optional[Message]] = field(default_factory=dict)
22
19
  interactive: bool = False
23
20
 
@@ -25,11 +22,8 @@ class RunningApp:
25
22
  def running_app_from_layout(
26
23
  app_id: str,
27
24
  app_layout: api_pb2.AppLayout,
28
- client: _Client,
29
- environment_name: Optional[str] = None,
30
25
  app_page_url: Optional[str] = None,
31
26
  ) -> RunningApp:
32
- tag_to_object_id = dict(**app_layout.function_ids, **app_layout.class_ids)
33
27
  object_handle_metadata = {}
34
28
  for obj in app_layout.objects:
35
29
  handle_metadata: Optional[Message] = get_proto_oneof(obj, "handle_metadata_oneof")
@@ -37,9 +31,8 @@ def running_app_from_layout(
37
31
 
38
32
  return RunningApp(
39
33
  app_id,
40
- client,
41
- environment_name=environment_name,
42
- tag_to_object_id=tag_to_object_id,
34
+ function_ids=dict(app_layout.function_ids),
35
+ class_ids=dict(app_layout.class_ids),
43
36
  object_handle_metadata=object_handle_metadata,
44
37
  app_page_url=app_page_url,
45
38
  )
modal/sandbox.py CHANGED
@@ -2,7 +2,7 @@
2
2
  import asyncio
3
3
  import os
4
4
  from collections.abc import AsyncGenerator, Sequence
5
- from typing import TYPE_CHECKING, Literal, Optional, Union, overload
5
+ from typing import TYPE_CHECKING, AsyncIterator, Literal, Optional, Union, overload
6
6
 
7
7
  if TYPE_CHECKING:
8
8
  import _typeshed
@@ -26,7 +26,7 @@ from .client import _Client
26
26
  from .config import config
27
27
  from .container_process import _ContainerProcess
28
28
  from .exception import ExecutionError, InvalidError, SandboxTerminatedError, SandboxTimeoutError
29
- from .file_io import _FileIO
29
+ from .file_io import FileWatchEvent, FileWatchEventType, _FileIO
30
30
  from .gpu import GPU_T
31
31
  from .image import _Image
32
32
  from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
@@ -276,9 +276,9 @@ class _Sandbox(_Object, type_prefix="sb"):
276
276
 
277
277
  app_id = app.app_id
278
278
  app_client = app._client
279
- elif _App._container_app is not None:
280
- app_id = _App._container_app.app_id
281
- app_client = _App._container_app.client
279
+ elif (container_app := _App._get_container_app()) is not None:
280
+ app_id = container_app.app_id
281
+ app_client = container_app._client
282
282
  else:
283
283
  arglist = ", ".join(repr(s) for s in entrypoint_args)
284
284
  deprecation_error(
@@ -320,7 +320,9 @@ class _Sandbox(_Object, type_prefix="sb"):
320
320
  resp = await retry_transient_errors(client.stub.SandboxWait, req)
321
321
 
322
322
  obj = _Sandbox._new_hydrated(sandbox_id, client, None)
323
- obj._result = resp.result
323
+
324
+ if resp.result.status:
325
+ obj._result = resp.result
324
326
 
325
327
  return obj
326
328
 
@@ -579,6 +581,17 @@ class _Sandbox(_Object, type_prefix="sb"):
579
581
  task_id = await self._get_task_id()
580
582
  return await _FileIO.rm(path, self._client, task_id, recursive)
581
583
 
584
+ async def watch(
585
+ self,
586
+ path: str,
587
+ filter: Optional[list[FileWatchEventType]] = None,
588
+ recursive: Optional[bool] = None,
589
+ timeout: Optional[int] = None,
590
+ ) -> AsyncIterator[FileWatchEvent]:
591
+ task_id = await self._get_task_id()
592
+ async for event in _FileIO.watch(path, self._client, task_id, filter, recursive, timeout):
593
+ yield event
594
+
582
595
  @property
583
596
  def stdout(self) -> _StreamReader[str]:
584
597
  """
modal/sandbox.pyi CHANGED
@@ -131,6 +131,13 @@ class _Sandbox(modal.object._Object):
131
131
  async def ls(self, path: str) -> list[str]: ...
132
132
  async def mkdir(self, path: str, parents: bool = False) -> None: ...
133
133
  async def rm(self, path: str, recursive: bool = False) -> None: ...
134
+ def watch(
135
+ self,
136
+ path: str,
137
+ filter: typing.Optional[list[modal.file_io.FileWatchEventType]] = None,
138
+ recursive: typing.Optional[bool] = None,
139
+ timeout: typing.Optional[int] = None,
140
+ ) -> typing.AsyncIterator[modal.file_io.FileWatchEvent]: ...
134
141
  @property
135
142
  def stdout(self) -> modal.io_streams._StreamReader[str]: ...
136
143
  @property
@@ -388,6 +395,24 @@ class Sandbox(modal.object.Object):
388
395
 
389
396
  rm: __rm_spec
390
397
 
398
+ class __watch_spec(typing_extensions.Protocol):
399
+ def __call__(
400
+ self,
401
+ path: str,
402
+ filter: typing.Optional[list[modal.file_io.FileWatchEventType]] = None,
403
+ recursive: typing.Optional[bool] = None,
404
+ timeout: typing.Optional[int] = None,
405
+ ) -> typing.Iterator[modal.file_io.FileWatchEvent]: ...
406
+ def aio(
407
+ self,
408
+ path: str,
409
+ filter: typing.Optional[list[modal.file_io.FileWatchEventType]] = None,
410
+ recursive: typing.Optional[bool] = None,
411
+ timeout: typing.Optional[int] = None,
412
+ ) -> typing.AsyncIterator[modal.file_io.FileWatchEvent]: ...
413
+
414
+ watch: __watch_spec
415
+
391
416
  @property
392
417
  def stdout(self) -> modal.io_streams.StreamReader[str]: ...
393
418
  @property
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.70.2
3
+ Version: 0.71.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=7EAMe-85a-uWDaRAjRy9m4nnCAmjRJnh9x7FgW_QjLU,28935
5
+ modal/_container_entrypoint.py,sha256=-zUa567FgOKmF0TtFWQ6DgehUD2CMfABDBQ8oLSpjyc,29171
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
@@ -15,11 +15,11 @@ 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
18
- modal/app.py,sha256=JWefPs4yB70BKQwSZejB_4_muhxn63cC9UmnNvpQ9XY,45526
19
- modal/app.pyi,sha256=FYPCEJNhof4YF6HIuNP_2yG6s2PgZnKW9tO1hFE6sfA,25194
18
+ modal/app.py,sha256=vEE0cK5QPF6_cdW5AJvcuWxz5KmeprHwBEtlDkVRHgE,45582
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=WXHQoJWWNrFs3BR6wW3LRHc5XaH4_KTOFt0eo7HGJGs,7278
22
+ modal/client.pyi,sha256=Hytz6ByaqDhEWzURBLckQhgx5lj1VGnSG5DWq6wf6O0,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
@@ -32,17 +32,18 @@ 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
34
  modal/exception.py,sha256=GEV6xMnVnkle0gsFZVLB4B7cUMyw8HzVDvAvPr34ZV4,5185
35
- modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
36
- modal/file_io.py,sha256=QXACorWL9NAfvRcnBcP34e5H7u9xf7g5zt2BHj9quC8,16713
37
- modal/file_io.pyi,sha256=GMhCCRyMftXYI3HqI9EdGPOx70CbCNi-VC5Sfy5TYnc,7631
35
+ modal/experimental.py,sha256=npfKbyMpI41uZZs9HW_QiB3E4ykWfDXZbACXXbw6qeA,2385
36
+ modal/file_io.py,sha256=ZR8VBCDsDt5uB9TNN9XbEh7sniJzM_5YL47m8WP0m5c,19617
37
+ modal/file_io.pyi,sha256=79Fg75BjmMEeCX0Lx-Z8C4XSNPCotwNdK6ZLIDFm2f4,9770
38
38
  modal/file_pattern_matcher.py,sha256=LaI7Paxg0xR9D-D7Tgc60xR0w1KZee22LjGbFie1Vms,5571
39
39
  modal/functions.py,sha256=aXXXr3rk7BCeh5OWMvxGksGm8FQoYCyrBDGV74FPoPE,67827
40
- modal/functions.pyi,sha256=oMmcExtQxHwPej06jQ3uBe1tUlSR3VbAx7u3Vm-Ohhg,25317
40
+ modal/functions.pyi,sha256=snttn47K81lKhmrCLWNVZelZTDhNsbxtw4l1DlLDR74,25317
41
41
  modal/gpu.py,sha256=MTxj6ql8EpgfBg8YmZ5a1cLznyuZFssX1qXbEX4LKVM,7503
42
42
  modal/image.py,sha256=Krvcsclomp9YsqSNwFj2FoAyg10OvU47RDnsNCwjGbQ,84550
43
43
  modal/image.pyi,sha256=1fgGvsL5Rb0Sa-_2OCgIyJ_QgHcL0_9MWD_oY7cyFFM,24937
44
- modal/io_streams.py,sha256=QkQiizKRzd5bnbKQsap31LJgBYlAnj4-XkV_50xPYX0,15079
44
+ modal/io_streams.py,sha256=Xxc5grJiO94nBA48FFWH3S3g6SPR0xFVgZ_DZ1oFmvI,14428
45
45
  modal/io_streams.pyi,sha256=bCCVSxkMcosYd8O3PQDDwJw7TQ8JEcnYonLJ5t27TQs,4804
46
+ modal/io_streams_helper.py,sha256=B5Ui56ph7LkRpZX0tAF80Q-gOMsvPPLx5bpIPX0kgDc,1772
46
47
  modal/mount.py,sha256=wOr-2vmKImsE3lHBII8hL2gYy5ng46R58QwId4JultQ,29313
47
48
  modal/mount.pyi,sha256=FiNV1wIKFvd0ZMZ0tm1mz6ZSA5Hjsge-kFSA5tPWfcI,10503
48
49
  modal/network_file_system.py,sha256=INj1TfN_Fsmabmlte7anvey1epodjbMmjBW_TIJSST4,14406
@@ -60,11 +61,11 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
61
  modal/queue.py,sha256=zMUQtdAyqZzBg-2iAo3c3G54HLP7TEWfVhiQXLjewb4,18556
61
62
  modal/queue.pyi,sha256=gGV97pWelSSYqMV9Bl4ys3mSP7q82fS71oqSWeAwyDE,9818
62
63
  modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
63
- modal/runner.py,sha256=1nPBsIfef2sOr2ebQ348EmDemvYFDhp1-_Gr3BKsjdM,24542
64
- modal/runner.pyi,sha256=BvMS1ZVzWSn8B8q0KnIZOJKPkN5L-i5b-USbV6SWWHQ,5177
65
- modal/running_app.py,sha256=FSr0XoL4mPLPCBMj2TozWuEvcvApdY_t68nUowwf8x4,1372
66
- modal/sandbox.py,sha256=c-Qli3QJPN7bBQzsTk4iS51zurNlq--InZ2eRR-B6No,28106
67
- modal/sandbox.pyi,sha256=k8_vHjN3oigxSCF13Cm2HfcSHuliGuSb8ryd3CGqwoA,19815
64
+ modal/runner.py,sha256=mhqgRdjD5cUDpBQIokiX7OCfVblpGV6aWmZ-WvWJgGg,24114
65
+ modal/runner.pyi,sha256=YmP4EOCNjjkwSIPi2Gl6hF_ji_ytkxz9dw3iB9KXaOI,5275
66
+ modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
67
+ modal/sandbox.py,sha256=H63K3MTcgdb9KkKc79sMKe6UzFMGBNI7HB2TUwBbE_U,28609
68
+ modal/sandbox.pyi,sha256=lceWDeXqzdeRc1iIuM5YmpoZlBJcVBpQO1Jc3AT1AQI,20809
68
69
  modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
69
70
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
70
71
  modal/secret.py,sha256=lebVTZi4fC9PXQpLVmsvgQLzy-2Kzxv1WBD0Jr2wsxQ,10117
@@ -78,7 +79,7 @@ modal/volume.py,sha256=T-pLxCYqmqRO6OolpAXlPxomMu0RWjti2e4kUpaj2cQ,29229
78
79
  modal/volume.pyi,sha256=eekb2dnAAwFK_NO9ciAOOTthl8NP1iAmMFrCGgjDA2k,11100
79
80
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
80
81
  modal/_runtime/asgi.py,sha256=Mjs859pSgOmtZL-YmEsSKN557v1A2Ax_5-ERgPfj55E,21920
81
- modal/_runtime/container_io_manager.py,sha256=8k84QF8dNPY344tm0jz6DySCnIwIlUH66KKKh95FjWY,43878
82
+ modal/_runtime/container_io_manager.py,sha256=HgDLjE78yy1P7WZTmsEVDf89YnFFWG63Ddes8uYLVDY,43764
82
83
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
83
84
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
84
85
  modal/_runtime/user_code_imports.py,sha256=n4CQOojzSdf0jwSKSy6MEnVX3IWl3t3Dq54-x9VS2Ds,14663
@@ -148,10 +149,10 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
148
149
  modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
149
150
  modal_global_objects/mounts/python_standalone.py,sha256=SL_riIxpd8mP4i4CLDCWiFFNj0Ltknm9c_UIGfX5d60,1836
150
151
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
151
- modal_proto/api.proto,sha256=LdD5XC5IhLP4rL_7nLeO0FL3emTs7jpEZGON2JIJDs4,79741
152
+ modal_proto/api.proto,sha256=B7UvK-bWmAcBuqMMWmUBubAdstblzWgMqmUUco-1fEE,79926
152
153
  modal_proto/api_grpc.py,sha256=AiUCWTHQQFC9RFB_XuavB_OnVMr7GJMRLEwcf4FSTio,102088
153
- modal_proto/api_pb2.py,sha256=rvBtjxpHVIXZmecc0OZS5PgZm4n1DcI4q1EHE675iW0,293583
154
- modal_proto/api_pb2.pyi,sha256=LNvol6MFzFuG1J_wKA4AKPiSKSLkYfNW1kF7c5XXABk,391781
154
+ modal_proto/api_pb2.py,sha256=EEvj9MRiYAGiGP9lZqkQs7TIP7eepBKhAtL0eJAjpRM,293669
155
+ modal_proto/api_pb2.pyi,sha256=kdIvhfjCdoMP-uLw1MvQOIwE3m2xAenexGCXuo-SX0M,392331
155
156
  modal_proto/api_pb2_grpc.py,sha256=dFxVTgosyp_o8NCI1JIySlR0qTzG4ILm9mq8MNo4jYc,220795
156
157
  modal_proto/api_pb2_grpc.pyi,sha256=yJgwEl-1YU42m7MU_Sm5SK3rB9xdkisPk3nZB-mlqkg,51463
157
158
  modal_proto/modal_api_grpc.py,sha256=MyNzvY_WqB7QTMOQjoH6lsqCY5-6_s1HP-knsOSjANs,13640
@@ -163,12 +164,12 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
163
164
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
164
165
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
165
166
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
166
- modal_version/__init__.py,sha256=N9Kh4DrM2649_INTJG4Lp3NKdux7cxGuiDtXpq_hkFY,470
167
+ modal_version/__init__.py,sha256=BEBWj9tcbFUwzEjUrqly601rauw5cYsHdcmJHs3iu0s,470
167
168
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
168
- modal_version/_version_generated.py,sha256=-cO-pRiLwIwgch5Ik_s4Jq9WJA6bUJuOEZ1MivmPWJ8,148
169
- modal-0.70.2.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
170
- modal-0.70.2.dist-info/METADATA,sha256=FuikYBU1iOwsYxHyv1pnYclfrOMwXJgY7JkfqndJnnQ,2328
171
- modal-0.70.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
172
- modal-0.70.2.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
173
- modal-0.70.2.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
174
- modal-0.70.2.dist-info/RECORD,,
169
+ modal_version/_version_generated.py,sha256=mfMCToZpTuPxzuVuuvViSp1od7EJVezkQVZIUWWSBic,148
170
+ modal-0.71.2.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
171
+ modal-0.71.2.dist-info/METADATA,sha256=pF1LUr5t33VWn4eEb59j6Is9NTrmoT9Wr-lZF4ciHf0,2328
172
+ modal-0.71.2.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
173
+ modal-0.71.2.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
174
+ modal-0.71.2.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
175
+ modal-0.71.2.dist-info/RECORD,,
modal_proto/api.proto CHANGED
@@ -1479,6 +1479,8 @@ message FunctionGetOutputsRequest {
1479
1479
  string last_entry_id = 6;
1480
1480
  bool clear_on_success = 7; // expires *any* remaining outputs soon after this call, not just the returned ones
1481
1481
  double requested_at = 8; // Used for waypoints.
1482
+ // The jwts the client expects the server to be processing. This is optional and used for sync inputs only.
1483
+ repeated string input_jwts = 9;
1482
1484
  }
1483
1485
 
1484
1486
  message FunctionGetOutputsResponse {
@@ -1678,6 +1680,7 @@ message GenericResult { // Used for both tasks and function outputs
1678
1680
  // Used when the user's function fails to initialize (ex. S3 mount failed due to invalid credentials).
1679
1681
  // Terminates the function and all remaining inputs.
1680
1682
  GENERIC_STATUS_INIT_FAILURE = 5;
1683
+ GENERIC_STATUS_INTERNAL_FAILURE = 6;
1681
1684
  }
1682
1685
 
1683
1686
  GenericStatus status = 1; // Status of the task or function output.