modal 0.67.43__py3-none-any.whl → 0.68.11__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.pyi CHANGED
@@ -157,7 +157,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.
157
157
  image: modal.image._Image,
158
158
  secrets: collections.abc.Sequence[modal.secret._Secret] = (),
159
159
  schedule: typing.Optional[modal.schedule.Schedule] = None,
160
- is_generator=False,
160
+ is_generator: bool = False,
161
161
  gpu: typing.Union[
162
162
  None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
163
163
  ] = None,
@@ -234,7 +234,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.
234
234
  @property
235
235
  async def web_url(self) -> str: ...
236
236
  @property
237
- def is_generator(self) -> bool: ...
237
+ async def is_generator(self) -> bool: ...
238
238
  @property
239
239
  def cluster_size(self) -> int: ...
240
240
  def _map(
@@ -246,6 +246,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.
246
246
  async def _call_generator_nowait(self, args, kwargs): ...
247
247
  async def remote(self, *args: P.args, **kwargs: P.kwargs) -> ReturnType: ...
248
248
  def remote_gen(self, *args, **kwargs) -> collections.abc.AsyncGenerator[typing.Any, None]: ...
249
+ def _is_local(self): ...
249
250
  def _get_info(self) -> modal._utils.function_utils.FunctionInfo: ...
250
251
  def _get_obj(self) -> typing.Optional[modal.cls._Obj]: ...
251
252
  def local(self, *args: P.args, **kwargs: P.kwargs) -> OriginalReturnType: ...
@@ -325,7 +326,7 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
325
326
  image: modal.image.Image,
326
327
  secrets: collections.abc.Sequence[modal.secret.Secret] = (),
327
328
  schedule: typing.Optional[modal.schedule.Schedule] = None,
328
- is_generator=False,
329
+ is_generator: bool = False,
329
330
  gpu: typing.Union[
330
331
  None, bool, str, modal.gpu._GPUConfig, list[typing.Union[None, bool, str, modal.gpu._GPUConfig]]
331
332
  ] = None,
@@ -467,6 +468,7 @@ class Function(typing.Generic[P, ReturnType, OriginalReturnType], modal.object.O
467
468
 
468
469
  remote_gen: __remote_gen_spec
469
470
 
471
+ def _is_local(self): ...
470
472
  def _get_info(self) -> modal._utils.function_utils.FunctionInfo: ...
471
473
  def _get_obj(self) -> typing.Optional[modal.cls.Obj]: ...
472
474
  def local(self, *args: P.args, **kwargs: P.kwargs) -> OriginalReturnType: ...
modal/object.py CHANGED
@@ -96,7 +96,9 @@ class _Object:
96
96
 
97
97
  def _initialize_from_other(self, other):
98
98
  # default implementation, can be overriden in subclasses
99
- pass
99
+ self._object_id = other._object_id
100
+ self._is_hydrated = other._is_hydrated
101
+ self._client = other._client
100
102
 
101
103
  def _hydrate(self, object_id: str, client: _Client, metadata: Optional[Message]):
102
104
  assert isinstance(object_id, str)
@@ -139,7 +141,7 @@ class _Object:
139
141
 
140
142
  # Object to clone must already be hydrated, otherwise from_loader is more suitable.
141
143
  self._validate_is_hydrated()
142
- obj = _Object.__new__(type(self))
144
+ obj = type(self).__new__(type(self))
143
145
  obj._initialize_from_other(self)
144
146
  return obj
145
147
 
modal/partial_function.py CHANGED
@@ -49,7 +49,7 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
49
49
  raw_f: Callable[P, ReturnType]
50
50
  flags: _PartialFunctionFlags
51
51
  webhook_config: Optional[api_pb2.WebhookConfig]
52
- is_generator: Optional[bool]
52
+ is_generator: bool
53
53
  keep_warm: Optional[int]
54
54
  batch_max_size: Optional[int]
55
55
  batch_wait_ms: Optional[int]
@@ -73,7 +73,13 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
73
73
  self.raw_f = raw_f
74
74
  self.flags = flags
75
75
  self.webhook_config = webhook_config
76
- self.is_generator = is_generator
76
+ if is_generator is None:
77
+ # auto detect - doesn't work if the function *returns* a generator
78
+ final_is_generator = inspect.isgeneratorfunction(raw_f) or inspect.isasyncgenfunction(raw_f)
79
+ else:
80
+ final_is_generator = is_generator
81
+
82
+ self.is_generator = final_is_generator
77
83
  self.keep_warm = keep_warm
78
84
  self.wrapped = False # Make sure that this was converted into a FunctionHandle
79
85
  self.batch_max_size = batch_max_size
@@ -101,7 +107,7 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
101
107
  # This happens mainly during serialization of the wrapped underlying class of a Cls
102
108
  # since we don't have the instance info here we just return the PartialFunction itself
103
109
  # to let it be bound to a variable and become a Function later on
104
- return self
110
+ return self # type: ignore # this returns a PartialFunction in a special internal case
105
111
 
106
112
  def __del__(self):
107
113
  if (self.flags & _PartialFunctionFlags.FUNCTION) and self.wrapped is False:
@@ -154,14 +160,14 @@ def _find_partial_methods_for_user_cls(user_cls: type[Any], flags: int) -> dict[
154
160
  )
155
161
  deprecation_error((2024, 2, 21), message)
156
162
 
157
- partial_functions: dict[str, PartialFunction] = {}
163
+ partial_functions: dict[str, _PartialFunction] = {}
158
164
  for parent_cls in reversed(user_cls.mro()):
159
165
  if parent_cls is not object:
160
166
  for k, v in parent_cls.__dict__.items():
161
- if isinstance(v, PartialFunction):
162
- partial_function = synchronizer._translate_in(v) # TODO: remove need for?
163
- if partial_function.flags & flags:
164
- partial_functions[k] = partial_function
167
+ if isinstance(v, PartialFunction): # type: ignore[reportArgumentType] # synchronicity wrapper types
168
+ _partial_function: _PartialFunction = typing.cast(_PartialFunction, synchronizer._translate_in(v))
169
+ if _partial_function.flags & flags:
170
+ partial_functions[k] = _partial_function
165
171
 
166
172
  return partial_functions
167
173
 
@@ -245,8 +251,6 @@ def _method(
245
251
  "Batched function on classes should not be wrapped by `@method`. "
246
252
  "Suggestion: remove the `@method` decorator."
247
253
  )
248
- if is_generator is None:
249
- is_generator = inspect.isgeneratorfunction(raw_f) or inspect.isasyncgenfunction(raw_f)
250
254
  return _PartialFunction(raw_f, _PartialFunctionFlags.FUNCTION, is_generator=is_generator, keep_warm=keep_warm)
251
255
 
252
256
  return wrapper
@@ -28,7 +28,7 @@ class _PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
28
28
  raw_f: typing.Callable[P, ReturnType]
29
29
  flags: _PartialFunctionFlags
30
30
  webhook_config: typing.Optional[modal_proto.api_pb2.WebhookConfig]
31
- is_generator: typing.Optional[bool]
31
+ is_generator: bool
32
32
  keep_warm: typing.Optional[int]
33
33
  batch_max_size: typing.Optional[int]
34
34
  batch_wait_ms: typing.Optional[int]
@@ -57,7 +57,7 @@ class PartialFunction(typing.Generic[P, ReturnType, OriginalReturnType]):
57
57
  raw_f: typing.Callable[P, ReturnType]
58
58
  flags: _PartialFunctionFlags
59
59
  webhook_config: typing.Optional[modal_proto.api_pb2.WebhookConfig]
60
- is_generator: typing.Optional[bool]
60
+ is_generator: bool
61
61
  keep_warm: typing.Optional[int]
62
62
  batch_max_size: typing.Optional[int]
63
63
  batch_wait_ms: typing.Optional[int]
modal/runner.py CHANGED
@@ -17,7 +17,7 @@ from modal_proto import api_pb2
17
17
  from ._pty import get_pty_info
18
18
  from ._resolver import Resolver
19
19
  from ._runtime.execution_context import is_local
20
- from ._traceback import traceback_contains_remote_call
20
+ from ._traceback import print_server_warnings, traceback_contains_remote_call
21
21
  from ._utils.async_utils import TaskContext, gather_cancel_on_exc, synchronize_api
22
22
  from ._utils.grpc_utils import retry_transient_errors
23
23
  from ._utils.name_utils import check_object_name, is_valid_tag
@@ -176,7 +176,7 @@ async def _publish_app(
176
176
  indexed_objects: dict[str, _Object],
177
177
  name: str = "", # Only relevant for deployments
178
178
  tag: str = "", # Only relevant for deployments
179
- ) -> tuple[str, list[str]]:
179
+ ) -> tuple[str, list[api_pb2.Warning]]:
180
180
  """Wrapper for AppPublish RPC."""
181
181
 
182
182
  # Could simplify this function some changing the internal representation to use
@@ -206,7 +206,8 @@ async def _publish_app(
206
206
  raise InvalidError(exc.message)
207
207
  raise
208
208
 
209
- return response.url, response.warnings
209
+ print_server_warnings(response.server_warnings)
210
+ return response.url, response.server_warnings
210
211
 
211
212
 
212
213
  async def _disconnect(
@@ -554,7 +555,7 @@ async def _deploy_app(
554
555
  app_id=running_app.app_id,
555
556
  app_page_url=running_app.app_page_url,
556
557
  app_logs_url=running_app.app_logs_url, # type: ignore
557
- warnings=warnings,
558
+ warnings=[warning.message for warning in warnings],
558
559
  )
559
560
 
560
561
 
modal/runner.pyi CHANGED
@@ -1,6 +1,7 @@
1
1
  import modal.client
2
2
  import modal.object
3
3
  import modal.running_app
4
+ import modal_proto.api_pb2
4
5
  import multiprocessing.synchronize
5
6
  import synchronicity.combined_types
6
7
  import typing
@@ -37,7 +38,7 @@ async def _publish_app(
37
38
  indexed_objects: dict[str, modal.object._Object],
38
39
  name: str = "",
39
40
  tag: str = "",
40
- ) -> tuple[str, list[str]]: ...
41
+ ) -> tuple[str, list[modal_proto.api_pb2.Warning]]: ...
41
42
  async def _disconnect(client: modal.client._Client, app_id: str, reason: int, exc_str: str = "") -> None: ...
42
43
  async def _status_based_disconnect(
43
44
  client: modal.client._Client, app_id: str, exc_info: typing.Optional[BaseException] = None
modal/sandbox.py CHANGED
@@ -4,6 +4,9 @@ import os
4
4
  from collections.abc import AsyncGenerator, Sequence
5
5
  from typing import TYPE_CHECKING, Literal, Optional, Union, overload
6
6
 
7
+ if TYPE_CHECKING:
8
+ import _typeshed
9
+
7
10
  from google.protobuf.message import Message
8
11
  from grpclib import GRPCError, Status
9
12
 
@@ -29,6 +32,7 @@ from .exception import (
29
32
  deprecation_error,
30
33
  deprecation_warning,
31
34
  )
35
+ from .file_io import _FileIO
32
36
  from .gpu import GPU_T
33
37
  from .image import _Image
34
38
  from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
@@ -527,6 +531,42 @@ class _Sandbox(_Object, type_prefix="sb"):
527
531
  by_line = bufsize == 1
528
532
  return _ContainerProcess(resp.exec_id, self._client, stdout=stdout, stderr=stderr, text=text, by_line=by_line)
529
533
 
534
+ @overload
535
+ async def open(
536
+ self,
537
+ path: str,
538
+ mode: "_typeshed.OpenTextMode",
539
+ ) -> _FileIO[str]:
540
+ ...
541
+
542
+ @overload
543
+ async def open(
544
+ self,
545
+ path: str,
546
+ mode: "_typeshed.OpenBinaryMode",
547
+ ) -> _FileIO[bytes]:
548
+ ...
549
+
550
+ async def open(
551
+ self,
552
+ path: str,
553
+ mode: Union["_typeshed.OpenTextMode", "_typeshed.OpenBinaryMode"] = "r",
554
+ ):
555
+ """Open a file in the Sandbox and return
556
+ a [`FileIO`](/docs/reference/modal.FileIO#modalfile_io) handle.
557
+
558
+ **Usage**
559
+
560
+ ```python notest
561
+ sb = modal.Sandbox.create(app=sb_app)
562
+ f = sb.open("/test.txt", "w")
563
+ f.write("hello")
564
+ f.close()
565
+ ```
566
+ """
567
+ task_id = await self._get_task_id()
568
+ return await _FileIO.create(path, mode, self._client, task_id)
569
+
530
570
  @property
531
571
  def stdout(self) -> _StreamReader[str]:
532
572
  """
modal/sandbox.pyi CHANGED
@@ -1,3 +1,4 @@
1
+ import _typeshed
1
2
  import collections.abc
2
3
  import google.protobuf.message
3
4
  import modal._tunnel
@@ -5,6 +6,7 @@ import modal.app
5
6
  import modal.client
6
7
  import modal.cloud_bucket_mount
7
8
  import modal.container_process
9
+ import modal.file_io
8
10
  import modal.gpu
9
11
  import modal.image
10
12
  import modal.io_streams
@@ -122,6 +124,10 @@ class _Sandbox(modal.object._Object):
122
124
  bufsize: typing.Literal[-1, 1] = -1,
123
125
  _pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
124
126
  ) -> modal.container_process._ContainerProcess[bytes]: ...
127
+ @typing.overload
128
+ async def open(self, path: str, mode: _typeshed.OpenTextMode) -> modal.file_io._FileIO[str]: ...
129
+ @typing.overload
130
+ async def open(self, path: str, mode: _typeshed.OpenBinaryMode) -> modal.file_io._FileIO[bytes]: ...
125
131
  @property
126
132
  def stdout(self) -> modal.io_streams._StreamReader[str]: ...
127
133
  @property
@@ -349,6 +355,18 @@ class Sandbox(modal.object.Object):
349
355
 
350
356
  exec: __exec_spec
351
357
 
358
+ class __open_spec(typing_extensions.Protocol):
359
+ @typing.overload
360
+ def __call__(self, path: str, mode: _typeshed.OpenTextMode) -> modal.file_io.FileIO[str]: ...
361
+ @typing.overload
362
+ def __call__(self, path: str, mode: _typeshed.OpenBinaryMode) -> modal.file_io.FileIO[bytes]: ...
363
+ @typing.overload
364
+ async def aio(self, path: str, mode: _typeshed.OpenTextMode) -> modal.file_io.FileIO[str]: ...
365
+ @typing.overload
366
+ async def aio(self, path: str, mode: _typeshed.OpenBinaryMode) -> modal.file_io.FileIO[bytes]: ...
367
+
368
+ open: __open_spec
369
+
352
370
  @property
353
371
  def stdout(self) -> modal.io_streams.StreamReader[str]: ...
354
372
  @property
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.67.43
3
+ Version: 0.68.11
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
@@ -21,7 +21,7 @@ Requires-Dist: fastapi
21
21
  Requires-Dist: grpclib (==0.4.7)
22
22
  Requires-Dist: protobuf (!=4.24.0,<6.0,>=3.19)
23
23
  Requires-Dist: rich (>=12.0.0)
24
- Requires-Dist: synchronicity (~=0.9.4)
24
+ Requires-Dist: synchronicity (~=0.9.6)
25
25
  Requires-Dist: toml
26
26
  Requires-Dist: typer (>=0.9)
27
27
  Requires-Dist: types-certifi
@@ -2,7 +2,7 @@ modal/__init__.py,sha256=Yn8zS7Jxl5uZjPM331Pc4FdSmp9Rt6VdE7TiE4ZKRc8,2151
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=Tae8hAbgN62HM9Q_UFuCyyswfdh1rOey2zzXkbG4Cns,28795
5
+ modal/_container_entrypoint.py,sha256=wk10vA5vRZZsVwQ0yINOLd0i-NwH7x6XbhTslumvGjo,28910
6
6
  modal/_ipython.py,sha256=HF_DYy0e0qM9WnGDmTY30s1RxzGya9GeORCauCEpRaE,450
7
7
  modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
8
8
  modal/_output.py,sha256=0fWX_KQwhER--U81ys16CL-pA5A-LN20C0EZjElKGJQ,25410
@@ -11,19 +11,19 @@ modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
11
11
  modal/_resolver.py,sha256=TtowKu2LdZ7NpiYkSXs058BZ4ivY8KVYdchqLfREkiA,6775
12
12
  modal/_resources.py,sha256=5qmcirXUI8dSH926nwkUaeX9H25mqYu9mXD_KuT79-o,1733
13
13
  modal/_serialization.py,sha256=qPLH6OUEBas1CT-a6i5pOP1hPGt5AfKr9q7RMUTFOMc,18722
14
- modal/_traceback.py,sha256=tueIGN5DbPaQlo23F-GrFMjl-HpDxBxfSAkqjU39zwg,4389
14
+ modal/_traceback.py,sha256=orZ7rsCk9ekV7ZoFjZTH_H00azCypwRKaLh0MZb1dR8,4898
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
18
  modal/app.py,sha256=EJ7FUN6rWnSwLJoYJh8nmKg_t-8hdN8_rt0OrkP7JvQ,46084
19
19
  modal/app.pyi,sha256=BE5SlR5tRECuc6-e2lUuOknDdov3zxgZ4N0AsLb5ZVQ,25270
20
20
  modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
21
- modal/client.py,sha256=cmylZhU35txmrx4nltNYuuqXRgeoMtm0ow1J9wJkEYQ,16400
22
- modal/client.pyi,sha256=4PTumnNQ0bz1iY7cJ9H9YbH76flPkTjCk-1pk-7WLAQ,7354
21
+ modal/client.py,sha256=nyPjfromWBeOyurexpFP2QLQNk822RPggMCLyX9j1jA,15247
22
+ modal/client.pyi,sha256=wnmsE-wrmK3qkFH1a5PoT45B11cFC5T3gLLO9KceJNU,7280
23
23
  modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
24
24
  modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
25
- modal/cls.py,sha256=OJqzj_V-n1g48BY_4Jg_BOTQdftEEl4kTWN0X4FOOdg,27378
26
- modal/cls.pyi,sha256=47jaIT06fz8PSUrs-MaNn6r03PHsAyUGsKuK5e9RMhQ,8140
25
+ modal/cls.py,sha256=ONnrfZ2vPcaY2JuKypPiBA9eTiyg8Qfg-Ull40nn9zs,30956
26
+ modal/cls.pyi,sha256=uoOEANXgCFT9Au3e-_bU98M6ZfAgQWF5ngj8f4c6qpY,8225
27
27
  modal/config.py,sha256=1KhNJkjYsJkX1V8RPPdRYPlM2HE-ZZs0JVSxbiXjmrw,11010
28
28
  modal/container_process.py,sha256=zDxCLk6KfJT1G9FfNtjom6gekBQ46op3TWepT7-Hkbg,6077
29
29
  modal/container_process.pyi,sha256=dqtqBmyRpXXpRrDooESL6WBVU_1Rh6OG-66P2Hk9E5U,2666
@@ -31,10 +31,12 @@ modal/dict.py,sha256=RmJlEwFJOdSfAYcVa50hbbFccV8e7BvC5tc5g1HXF-c,12622
31
31
  modal/dict.pyi,sha256=2cYgOqBxYZih4BYgMV0c3rNPuxYR6-cB1GBXzFkHA5c,7265
32
32
  modal/environments.py,sha256=5cgA-zbm6ngKLsRA19zSOgtgo9-BarJK3FJK0BiF2Lo,6505
33
33
  modal/environments.pyi,sha256=XalNpiPkAtHWAvOU2Cotq0ozmtl-Jv0FDsR8h9mr27Q,3521
34
- modal/exception.py,sha256=EBkdWVved2XEPsXaoPRu56xfxFFHL9iuqvUsdj42WDA,6392
34
+ modal/exception.py,sha256=dRK789TD1HaB63kHhu1yZuvS2vP_Vua3iLMBtA6dgqk,7128
35
35
  modal/experimental.py,sha256=jFuNbwrNHos47viMB9q-cHJSvf2RDxDdoEcss9plaZE,2302
36
- modal/functions.py,sha256=3GjjFbf40XciWAa4rTmh0erkZjPzRjKHqWxUu91mHOU,66685
37
- modal/functions.pyi,sha256=IyuM9TV79JfrtfTaJ4yq3EcWp3yHuxLavpxTOwSWEDw,24988
36
+ modal/file_io.py,sha256=q8s872qf6Ntdw7dPogDlpYbixxGkwCA0BlQn2UUoVhY,14637
37
+ modal/file_io.pyi,sha256=pfkmJiaBpMCZReE6-KCjYOzB1dVtyYDYokJoYX8ARK4,6932
38
+ modal/functions.py,sha256=IIdHw0FNOdoMksG1b2zvkn8f-xskhJu07ZvHMey9iq4,67667
39
+ modal/functions.pyi,sha256=EYH4w4VgQtdbEWLGarnU5QtYVfuM2_tnovKFEbYyg2c,25068
38
40
  modal/gpu.py,sha256=r4rL6uH3UJIQthzYvfWauXNyh01WqCPtKZCmmSX1fd4,6881
39
41
  modal/image.py,sha256=cQ6WP1xHXZT_nY8z3aEFiGwKzrTV0yxi3Ab8JzF91eo,79653
40
42
  modal/image.pyi,sha256=PIKH6JBA4L5TfdJrQu3pm2ykyIITmiP920TpP8cdyQA,24585
@@ -44,24 +46,24 @@ modal/mount.py,sha256=liaid5p42o0OKnzoocJJ_oCovDVderk3-JuCTa5pqtA,27656
44
46
  modal/mount.pyi,sha256=3e4nkXUeeVmUmOyK8Tiyk_EQlHeWruN3yGJVnmDUVrI,9761
45
47
  modal/network_file_system.py,sha256=NKZgh_p8MyJyyJgP92lhRgTmwA3kOPw7m8AbYlchhCE,14530
46
48
  modal/network_file_system.pyi,sha256=8mHKXuRkxHPazF6ljIW7g4M5aVqLSl6eKUPLgDCug5c,7901
47
- modal/object.py,sha256=KmtWRDd5ntHGSO9ASHe9MJcIgjNRqaDXGc3rWOXwrmA,9646
49
+ modal/object.py,sha256=HZs3N59C6JxlMuPQWJYvrWV1FEEkH9txUovVDorVUbs,9763
48
50
  modal/object.pyi,sha256=MO78H9yFSE5i1gExPEwyyQzLdlshkcGHN1aQ0ylyvq0,8802
49
51
  modal/output.py,sha256=N0xf4qeudEaYrslzdAl35VKV8rapstgIM2e9wO8_iy0,1967
50
52
  modal/parallel_map.py,sha256=4aoMXIrlG3wl5Ifk2YDNOQkXsGRsm6Xbfm6WtJ2t3WY,16002
51
53
  modal/parallel_map.pyi,sha256=pOhT0P3DDYlwLx0fR3PTsecA7DI8uOdXC1N8i-ZkyOY,2328
52
- modal/partial_function.py,sha256=938kcVJHcdGXKWsO7NE_FBxPldZ304a_GyhjxD79wHE,28215
53
- modal/partial_function.pyi,sha256=EafGOzZdEq-yE5bYRoMfnMqw-o8Hk_So8MRPDSB99_0,8982
54
+ modal/partial_function.py,sha256=rirVfihV6kp1SMTacrsfE5rNXV5JnTLpU_Zd4xukNg0,28529
55
+ modal/partial_function.pyi,sha256=mt9kUeeMSVTo5qJ6JF6qeQzr41zykYBi2Yt6R8dxtWk,8948
54
56
  modal/proxy.py,sha256=ZrOsuQP7dSZFq1OrIxalNnt0Zvsnp1h86Th679sSL40,1417
55
57
  modal/proxy.pyi,sha256=UvygdOYneLTuoDY6hVaMNCyZ947Tmx93IdLjErUqkvM,368
56
58
  modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
57
59
  modal/queue.py,sha256=fJYFfpdrlVj_doc3QxgvJvv7c8BGHjjja5q_9HCtSqs,18658
58
60
  modal/queue.pyi,sha256=di3ownBw4jc6d4X7ygXtbpjlUMOK69qyaD3lVsJbpoM,9900
59
61
  modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
60
- modal/runner.py,sha256=AiBGoc_BZxQenjA0T9yQ7hf515Va6G05ULYRGnTT5Y0,24453
61
- modal/runner.pyi,sha256=Fa6HjaqH---CJhsefLm6Ce6DRLKZdz_Bng_gn9arJdw,5126
62
+ modal/runner.py,sha256=Q02VdfLCO7YKpnOSqqh58XL3hR2XHaDeiJVYW3MKz_8,24580
63
+ modal/runner.pyi,sha256=BvMS1ZVzWSn8B8q0KnIZOJKPkN5L-i5b-USbV6SWWHQ,5177
62
64
  modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
63
- modal/sandbox.py,sha256=Yd__KipEINH2euDPOcm5MPBnagRv19Sa5z5tJCvGOQs,26360
64
- modal/sandbox.pyi,sha256=fRl32Pt5F6TbK7aYewjlcL4WQxxmp7m6Ybktmkd2VOk,18108
65
+ modal/sandbox.py,sha256=abmprnPtA-WVsHKu4J1deoltpAUvXtIHQHX-ZpYjYPE,27293
66
+ modal/sandbox.pyi,sha256=QPNuiTLNoKwYf8JK_fmfUBXpdGYlukyaksFV1DpCd2g,18987
65
67
  modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
66
68
  modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
67
69
  modal/secret.py,sha256=Y1WgybQIkfkxdzH9CQ1h-Wd1DJJpzipigMhyyvSxTww,10007
@@ -75,18 +77,18 @@ modal/volume.py,sha256=IISuMeXq9MoSkhXg8Q6JG0F-2n9NTkWk0xGuJB8l3d8,29159
75
77
  modal/volume.pyi,sha256=St0mDiaojfep6Bs4sBbkRJmeacYHF6lh6FKOWGmheHA,11182
76
78
  modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
77
79
  modal/_runtime/asgi.py,sha256=GvuxZqWnIHMIR-Bx5f7toCQlkERaJO8CHjTPNM9IFIw,21537
78
- modal/_runtime/container_io_manager.py,sha256=8NyX5uuwmHEJgxMwdoY9PpEO-IHA8LGdYdbdHLIafK8,44131
80
+ modal/_runtime/container_io_manager.py,sha256=ctgyNFiHjq1brCrabXmlurkAXjnrCeWPRvTVa735vRw,44215
79
81
  modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
80
82
  modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
81
- modal/_runtime/user_code_imports.py,sha256=q_3JOYqCPDcVFZWCHEjyEqj8yzdFsQ49HzeqYmFDLbk,14521
83
+ modal/_runtime/user_code_imports.py,sha256=4fI0F9OIaNOcO_S4Tx2JcnYwZwZq6JdhMAkUzYN6je4,14629
82
84
  modal/_utils/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
83
85
  modal/_utils/app_utils.py,sha256=88BT4TPLWfYAQwKTHcyzNQRHg8n9B-QE2UyJs96iV-0,108
84
86
  modal/_utils/async_utils.py,sha256=9ubwMkwiDB4gzOYG2jL9j7Fs-5dxHjcifZe3r7JRg-k,25091
85
87
  modal/_utils/blob_utils.py,sha256=0k_qUpO5GHnz538wjRhyRw4NdJ5O322N7QSilIu32jw,16601
86
- modal/_utils/function_utils.py,sha256=GV-mq6sSGXQIX5PcExYWJMaWY9YLjChjsiQjg-oPvm8,24902
87
- modal/_utils/grpc_testing.py,sha256=iqM9n5M0cWUUIIWNaEDer_pIfPnzXdZBO4L8FVbNepQ,8309
88
+ modal/_utils/function_utils.py,sha256=LgcveUUb4XU_dWxtqgK_3ujZBvS3cGVzcDOkljyFZ2w,25066
89
+ modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
88
90
  modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
89
- modal/_utils/hash_utils.py,sha256=xKwSI1eQobyWNdJwyLO59eB241LOXmQ6QvtzJsyIMcw,1784
91
+ modal/_utils/hash_utils.py,sha256=LOWJ9U5Eaye2ZIGQOdEk8RN8ExPFovGQisyuGv1PXU0,2236
90
92
  modal/_utils/http_utils.py,sha256=VKXYNPJtrSwZ1ttcXVGQUWmn8cLAXiOTv05g2ac3GbU,2179
91
93
  modal/_utils/logger.py,sha256=ePzdudrtx9jJCjuO6-bcL_kwUJfi4AwloUmIiNtqkY0,1330
92
94
  modal/_utils/mount_utils.py,sha256=J-FRZbPQv1i__Tob-FIpbB1oXWpFLAwZiB4OCiJpFG0,3206
@@ -101,7 +103,7 @@ modal/_vendor/cloudpickle.py,sha256=Loq12qo7PBNbE4LFVEW6BdMMwY10MG94EOW1SCpcnQ0,
101
103
  modal/_vendor/tblib.py,sha256=g1O7QUDd3sDoLd8YPFltkXkih7r_fyZOjgmGuligv3s,9722
102
104
  modal/cli/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
103
105
  modal/cli/_download.py,sha256=t6BXZwjTd9MgznDvbsV8rp0FZWggdzC-lUAGZU4xx1g,3984
104
- modal/cli/_traceback.py,sha256=Tm0g4V_fr4XAlmuh_4MNgZKtjJly9wsWtnKKvOJFM7Q,7130
106
+ modal/cli/_traceback.py,sha256=QlLa_iw3fAOA-mqCqjS8qAxvNT48J3YY3errtVVc2cw,7316
105
107
  modal/cli/app.py,sha256=KOU3tKdcw50612rmN2LmO-N8cT1M1-UgLs7tw68Kgds,7717
106
108
  modal/cli/config.py,sha256=pXPLmX0bIoV57rQNqIPK7V-yllj-GPRY4jiBO_EklGg,1667
107
109
  modal/cli/container.py,sha256=nCySVD10VJPzmX3ghTsGmpxdYeVYYMW6ofjsyt2gQcM,3667
@@ -113,7 +115,7 @@ modal/cli/launch.py,sha256=uyI-ouGvYRjHLGxGQ2lYBZq32BiRT1i0L8ksz5iy7K8,2935
113
115
  modal/cli/network_file_system.py,sha256=3QbAxKEoRc6RCMsYE3OS-GcuiI4GMkz_wAKsIBbN1qg,8186
114
116
  modal/cli/profile.py,sha256=rLXfjJObfPNjaZvNfHGIKqs7y9bGYyGe-K7V0w-Ni0M,3110
115
117
  modal/cli/queues.py,sha256=MIh2OsliNE2QeL1erubfsRsNuG4fxqcqWA2vgIfQ4Mg,4494
116
- modal/cli/run.py,sha256=MitoSFA_QaqkIVjBRi91w1ekz6UlCwL3htE3_RI3yjA,17353
118
+ modal/cli/run.py,sha256=rv2t7WURME6fCUYo4aA48azVIXLZqo4NjYjTg2I8vzk,17040
117
119
  modal/cli/secret.py,sha256=uQpwYrMY98iMCWeZOQTcktOYhPTZ8IHnyealDc2CZqo,4206
118
120
  modal/cli/token.py,sha256=mxSgOWakXG6N71hQb1ko61XAR9ZGkTMZD-Txn7gmTac,1924
119
121
  modal/cli/utils.py,sha256=hZmjyzcPjDnQSkLvycZD2LhGdcsfdZshs_rOU78EpvI,3717
@@ -131,7 +133,7 @@ modal/requirements/README.md,sha256=9tK76KP0Uph7O0M5oUgsSwEZDj5y-dcUPsnpR0Sc-Ik,
131
133
  modal/requirements/base-images.json,sha256=kLNo5Sqmnhp9H6Hr9IcaGJFrRaRg1yfuepUWkm-y8iQ,571
132
134
  modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
133
135
  modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
134
- modal_docs/gen_reference_docs.py,sha256=AI8h-JKfwn7Tohm3P3D5G0SivSpdGgN6gnw-fED-S0s,6613
136
+ modal_docs/gen_reference_docs.py,sha256=aDcUSSDtAAZ4eeFWyroeIg2TOzyRoYcic-d9Zh9TdLY,6656
135
137
  modal_docs/mdmd/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
136
138
  modal_docs/mdmd/mdmd.py,sha256=F6EXKkjwrTbOiG6I7wKtNGVVmmeWLAJ5pnE7DUkDpvM,6231
137
139
  modal_docs/mdmd/signatures.py,sha256=XJaZrK7Mdepk5fdX51A8uENiLFNil85Ud0d4MH8H5f0,3218
@@ -142,10 +144,10 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
142
144
  modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
143
145
  modal_global_objects/mounts/python_standalone.py,sha256=SL_riIxpd8mP4i4CLDCWiFFNj0Ltknm9c_UIGfX5d60,1836
144
146
  modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
145
- modal_proto/api.proto,sha256=zd8V-GFVMtUP8YwxnlVvaJIuocpWKchRCeUZSlMMk74,78818
147
+ modal_proto/api.proto,sha256=41iACETQzxnecGOJgoeyKPQOJVZcw8iHJNtiB6SMuWg,79317
146
148
  modal_proto/api_grpc.py,sha256=DveC4ejFYEhCLiWbQShnmY31_FWGYU675Bmr7nHhsgs,101342
147
- modal_proto/api_pb2.py,sha256=l88JT2IcEuSqCnk7WRTQrBoHtJyAQD4hHAoWmiCQr0A,287100
148
- modal_proto/api_pb2.pyi,sha256=a303c1L3sRnSk9wZXa7DuQWwBZm8u6EShoJImMYxt98,384236
149
+ modal_proto/api_pb2.py,sha256=316-2KJCwcoJm-oFQ7tG42LZjlA3lNhEUYsbbzoikUs,290107
150
+ modal_proto/api_pb2.pyi,sha256=kuvlkVay68o4OQTW8UGwH10Xvxejr-uQjcb2tT_Neso,388133
149
151
  modal_proto/api_pb2_grpc.py,sha256=2PEP6JPOoTw2rDC5qYjLNuumP68ZwAouRhCoayisAhY,219162
150
152
  modal_proto/api_pb2_grpc.pyi,sha256=uWtCxVEd0cFpOZ1oOGfZNO7Dv45OP4kp09jMnNyx9D4,51098
151
153
  modal_proto/modal_api_grpc.py,sha256=-8mLby_om5MYo6yu1zA_hqhz0yLsQW7k2YWBVZW1iVs,13546
@@ -157,12 +159,12 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
157
159
  modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
158
160
  modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
159
161
  modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
160
- modal_version/__init__.py,sha256=3IY-AWLH55r35_mQXIaut0jrJvoPuf1NZJBQQfSbPuo,470
162
+ modal_version/__init__.py,sha256=RT6zPoOdFO99u5Wcxxaoir4ZCuPTbQ22cvzFAXl3vUY,470
161
163
  modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
162
- modal_version/_version_generated.py,sha256=tPxVZVhTZ80YH1CvSZDHAkJ_azeUcv00GgLvebLfni8,149
163
- modal-0.67.43.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
164
- modal-0.67.43.dist-info/METADATA,sha256=tTXXCu0njTf-8EjJlrBL7TjvMP0e90efMYpHA5y1VRw,2329
165
- modal-0.67.43.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
166
- modal-0.67.43.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
167
- modal-0.67.43.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
168
- modal-0.67.43.dist-info/RECORD,,
164
+ modal_version/_version_generated.py,sha256=iMmZstd6JhPFScB-dfN5XinMS8GWtT-kQD4yTA3FQr4,149
165
+ modal-0.68.11.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
166
+ modal-0.68.11.dist-info/METADATA,sha256=xrxk7D7aRQurLJimfndYZrKyYvfhEFqBVT_o7q7Mxgk,2329
167
+ modal-0.68.11.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
168
+ modal-0.68.11.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
169
+ modal-0.68.11.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
170
+ modal-0.68.11.dist-info/RECORD,,
@@ -86,6 +86,7 @@ def run(output_dir: str = None):
86
86
  ("modal.Sandbox", "modal.sandbox"),
87
87
  ("modal.ContainerProcess", "modal.container_process"),
88
88
  ("modal.io_streams", "modal.io_streams"),
89
+ ("modal.FileIO", "modal.file_io"),
89
90
  ]
90
91
  # These aren't defined in `modal`, but should still be documented as top-level entries.
91
92
  forced_members = {"web_endpoint", "asgi_app", "method", "wsgi_app", "forward"}
modal_proto/api.proto CHANGED
@@ -400,7 +400,6 @@ message AppPublishRequest {
400
400
 
401
401
  message AppPublishResponse {
402
402
  string url = 1;
403
- repeated string warnings = 2; // Deprecated soon in favor of server_warnings
404
403
  repeated Warning server_warnings = 3;
405
404
  }
406
405
 
@@ -679,6 +678,7 @@ message ClassParameterValue {
679
678
  message ClientHelloResponse {
680
679
  string warning = 1;
681
680
  string image_builder_version = 2; // Deprecated, no longer used in client
681
+ repeated Warning server_warnings = 4;
682
682
  }
683
683
 
684
684
  message CloudBucketMount {
@@ -772,6 +772,15 @@ message ContainerFileFlushRequest {
772
772
  string file_descriptor = 1;
773
773
  }
774
774
 
775
+ message ContainerFileLsRequest {
776
+ string path = 1;
777
+ }
778
+
779
+ message ContainerFileMkdirRequest {
780
+ string path = 1;
781
+ bool make_parents = 2;
782
+ }
783
+
775
784
  message ContainerFileOpenRequest {
776
785
  // file descriptor is hydrated when sent from server -> worker
777
786
  optional string file_descriptor = 1;
@@ -788,12 +797,23 @@ message ContainerFileReadRequest {
788
797
  optional uint32 n = 2;
789
798
  }
790
799
 
800
+ message ContainerFileRmRequest {
801
+ string path = 1;
802
+ bool recursive = 2;
803
+ }
804
+
791
805
  message ContainerFileSeekRequest {
792
806
  string file_descriptor = 1;
793
807
  int32 offset = 2;
794
808
  SeekWhence whence = 3;
795
809
  }
796
810
 
811
+ message ContainerFileWatchRequest {
812
+ string path = 1;
813
+ bool recursive = 2;
814
+ optional uint64 timeout_secs = 3;
815
+ }
816
+
797
817
  message ContainerFileWriteReplaceBytesRequest {
798
818
  string file_descriptor = 1;
799
819
  bytes data = 2;
@@ -822,6 +842,10 @@ message ContainerFilesystemExecRequest {
822
842
  ContainerFileDeleteBytesRequest file_delete_bytes_request = 7;
823
843
  ContainerFileWriteReplaceBytesRequest file_write_replace_bytes_request = 8;
824
844
  ContainerFileCloseRequest file_close_request = 9;
845
+ ContainerFileLsRequest file_ls_request = 11;
846
+ ContainerFileMkdirRequest file_mkdir_request = 12;
847
+ ContainerFileRmRequest file_rm_request = 13;
848
+ ContainerFileWatchRequest file_watch_request = 14;
825
849
  }
826
850
  string task_id = 10;
827
851
  }