modal 0.62.16__py3-none-any.whl → 0.72.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.
Files changed (220) hide show
  1. modal/__init__.py +17 -13
  2. modal/__main__.py +41 -3
  3. modal/_clustered_functions.py +80 -0
  4. modal/_clustered_functions.pyi +22 -0
  5. modal/_container_entrypoint.py +420 -937
  6. modal/_ipython.py +3 -13
  7. modal/_location.py +17 -10
  8. modal/_output.py +243 -99
  9. modal/_pty.py +2 -2
  10. modal/_resolver.py +55 -59
  11. modal/_resources.py +51 -0
  12. modal/_runtime/__init__.py +1 -0
  13. modal/_runtime/asgi.py +519 -0
  14. modal/_runtime/container_io_manager.py +1036 -0
  15. modal/_runtime/execution_context.py +89 -0
  16. modal/_runtime/telemetry.py +169 -0
  17. modal/_runtime/user_code_imports.py +356 -0
  18. modal/_serialization.py +134 -9
  19. modal/_traceback.py +47 -187
  20. modal/_tunnel.py +52 -16
  21. modal/_tunnel.pyi +19 -36
  22. modal/_utils/app_utils.py +3 -17
  23. modal/_utils/async_utils.py +479 -100
  24. modal/_utils/blob_utils.py +157 -186
  25. modal/_utils/bytes_io_segment_payload.py +97 -0
  26. modal/_utils/deprecation.py +89 -0
  27. modal/_utils/docker_utils.py +98 -0
  28. modal/_utils/function_utils.py +460 -171
  29. modal/_utils/grpc_testing.py +47 -31
  30. modal/_utils/grpc_utils.py +62 -109
  31. modal/_utils/hash_utils.py +61 -19
  32. modal/_utils/http_utils.py +39 -9
  33. modal/_utils/logger.py +2 -1
  34. modal/_utils/mount_utils.py +34 -16
  35. modal/_utils/name_utils.py +58 -0
  36. modal/_utils/package_utils.py +14 -1
  37. modal/_utils/pattern_utils.py +205 -0
  38. modal/_utils/rand_pb_testing.py +5 -7
  39. modal/_utils/shell_utils.py +15 -49
  40. modal/_vendor/a2wsgi_wsgi.py +62 -72
  41. modal/_vendor/cloudpickle.py +1 -1
  42. modal/_watcher.py +14 -12
  43. modal/app.py +1003 -314
  44. modal/app.pyi +540 -264
  45. modal/call_graph.py +7 -6
  46. modal/cli/_download.py +63 -53
  47. modal/cli/_traceback.py +200 -0
  48. modal/cli/app.py +205 -45
  49. modal/cli/config.py +12 -5
  50. modal/cli/container.py +62 -14
  51. modal/cli/dict.py +128 -0
  52. modal/cli/entry_point.py +26 -13
  53. modal/cli/environment.py +40 -9
  54. modal/cli/import_refs.py +64 -58
  55. modal/cli/launch.py +32 -18
  56. modal/cli/network_file_system.py +64 -83
  57. modal/cli/profile.py +1 -1
  58. modal/cli/programs/run_jupyter.py +35 -10
  59. modal/cli/programs/vscode.py +60 -10
  60. modal/cli/queues.py +131 -0
  61. modal/cli/run.py +234 -131
  62. modal/cli/secret.py +8 -7
  63. modal/cli/token.py +7 -2
  64. modal/cli/utils.py +79 -10
  65. modal/cli/volume.py +110 -109
  66. modal/client.py +250 -144
  67. modal/client.pyi +157 -118
  68. modal/cloud_bucket_mount.py +108 -34
  69. modal/cloud_bucket_mount.pyi +32 -38
  70. modal/cls.py +535 -148
  71. modal/cls.pyi +190 -146
  72. modal/config.py +41 -19
  73. modal/container_process.py +177 -0
  74. modal/container_process.pyi +82 -0
  75. modal/dict.py +111 -65
  76. modal/dict.pyi +136 -131
  77. modal/environments.py +106 -5
  78. modal/environments.pyi +77 -25
  79. modal/exception.py +34 -43
  80. modal/experimental.py +61 -2
  81. modal/extensions/ipython.py +5 -5
  82. modal/file_io.py +537 -0
  83. modal/file_io.pyi +235 -0
  84. modal/file_pattern_matcher.py +197 -0
  85. modal/functions.py +906 -911
  86. modal/functions.pyi +466 -430
  87. modal/gpu.py +57 -44
  88. modal/image.py +1089 -479
  89. modal/image.pyi +584 -228
  90. modal/io_streams.py +434 -0
  91. modal/io_streams.pyi +122 -0
  92. modal/mount.py +314 -101
  93. modal/mount.pyi +241 -235
  94. modal/network_file_system.py +92 -92
  95. modal/network_file_system.pyi +152 -110
  96. modal/object.py +67 -36
  97. modal/object.pyi +166 -143
  98. modal/output.py +63 -0
  99. modal/parallel_map.py +434 -0
  100. modal/parallel_map.pyi +75 -0
  101. modal/partial_function.py +282 -117
  102. modal/partial_function.pyi +222 -129
  103. modal/proxy.py +15 -12
  104. modal/proxy.pyi +3 -8
  105. modal/queue.py +182 -65
  106. modal/queue.pyi +218 -118
  107. modal/requirements/2024.04.txt +29 -0
  108. modal/requirements/2024.10.txt +16 -0
  109. modal/requirements/README.md +21 -0
  110. modal/requirements/base-images.json +22 -0
  111. modal/retries.py +48 -7
  112. modal/runner.py +459 -156
  113. modal/runner.pyi +135 -71
  114. modal/running_app.py +38 -0
  115. modal/sandbox.py +514 -236
  116. modal/sandbox.pyi +397 -169
  117. modal/schedule.py +4 -4
  118. modal/scheduler_placement.py +20 -3
  119. modal/secret.py +56 -31
  120. modal/secret.pyi +62 -42
  121. modal/serving.py +51 -56
  122. modal/serving.pyi +44 -36
  123. modal/stream_type.py +15 -0
  124. modal/token_flow.py +5 -3
  125. modal/token_flow.pyi +37 -32
  126. modal/volume.py +285 -157
  127. modal/volume.pyi +249 -184
  128. {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/METADATA +7 -7
  129. modal-0.72.11.dist-info/RECORD +174 -0
  130. {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/top_level.txt +0 -1
  131. modal_docs/gen_reference_docs.py +3 -1
  132. modal_docs/mdmd/mdmd.py +0 -1
  133. modal_docs/mdmd/signatures.py +5 -2
  134. modal_global_objects/images/base_images.py +28 -0
  135. modal_global_objects/mounts/python_standalone.py +2 -2
  136. modal_proto/__init__.py +1 -1
  137. modal_proto/api.proto +1288 -533
  138. modal_proto/api_grpc.py +856 -456
  139. modal_proto/api_pb2.py +2165 -1157
  140. modal_proto/api_pb2.pyi +8859 -0
  141. modal_proto/api_pb2_grpc.py +1674 -855
  142. modal_proto/api_pb2_grpc.pyi +1416 -0
  143. modal_proto/modal_api_grpc.py +149 -0
  144. modal_proto/modal_options_grpc.py +3 -0
  145. modal_proto/options_pb2.pyi +20 -0
  146. modal_proto/options_pb2_grpc.pyi +7 -0
  147. modal_proto/py.typed +0 -0
  148. modal_version/__init__.py +1 -1
  149. modal_version/_version_generated.py +2 -2
  150. modal/_asgi.py +0 -370
  151. modal/_container_entrypoint.pyi +0 -378
  152. modal/_container_exec.py +0 -128
  153. modal/_sandbox_shell.py +0 -49
  154. modal/shared_volume.py +0 -23
  155. modal/shared_volume.pyi +0 -24
  156. modal/stub.py +0 -783
  157. modal/stub.pyi +0 -332
  158. modal-0.62.16.dist-info/RECORD +0 -198
  159. modal_global_objects/images/conda.py +0 -15
  160. modal_global_objects/images/debian_slim.py +0 -15
  161. modal_global_objects/images/micromamba.py +0 -15
  162. test/__init__.py +0 -1
  163. test/aio_test.py +0 -12
  164. test/async_utils_test.py +0 -262
  165. test/blob_test.py +0 -67
  166. test/cli_imports_test.py +0 -149
  167. test/cli_test.py +0 -659
  168. test/client_test.py +0 -194
  169. test/cls_test.py +0 -630
  170. test/config_test.py +0 -137
  171. test/conftest.py +0 -1420
  172. test/container_app_test.py +0 -32
  173. test/container_test.py +0 -1389
  174. test/cpu_test.py +0 -23
  175. test/decorator_test.py +0 -85
  176. test/deprecation_test.py +0 -34
  177. test/dict_test.py +0 -33
  178. test/e2e_test.py +0 -68
  179. test/error_test.py +0 -7
  180. test/function_serialization_test.py +0 -32
  181. test/function_test.py +0 -653
  182. test/function_utils_test.py +0 -101
  183. test/gpu_test.py +0 -159
  184. test/grpc_utils_test.py +0 -141
  185. test/helpers.py +0 -42
  186. test/image_test.py +0 -669
  187. test/live_reload_test.py +0 -80
  188. test/lookup_test.py +0 -70
  189. test/mdmd_test.py +0 -329
  190. test/mount_test.py +0 -162
  191. test/mounted_files_test.py +0 -329
  192. test/network_file_system_test.py +0 -181
  193. test/notebook_test.py +0 -66
  194. test/object_test.py +0 -41
  195. test/package_utils_test.py +0 -25
  196. test/queue_test.py +0 -97
  197. test/resolver_test.py +0 -58
  198. test/retries_test.py +0 -67
  199. test/runner_test.py +0 -85
  200. test/sandbox_test.py +0 -191
  201. test/schedule_test.py +0 -15
  202. test/scheduler_placement_test.py +0 -29
  203. test/secret_test.py +0 -78
  204. test/serialization_test.py +0 -42
  205. test/stub_composition_test.py +0 -10
  206. test/stub_test.py +0 -360
  207. test/test_asgi_wrapper.py +0 -234
  208. test/token_flow_test.py +0 -18
  209. test/traceback_test.py +0 -135
  210. test/tunnel_test.py +0 -29
  211. test/utils_test.py +0 -88
  212. test/version_test.py +0 -14
  213. test/volume_test.py +0 -341
  214. test/watcher_test.py +0 -30
  215. test/webhook_test.py +0 -146
  216. /modal/{requirements.312.txt → requirements/2023.12.312.txt} +0 -0
  217. /modal/{requirements.txt → requirements/2023.12.txt} +0 -0
  218. {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/LICENSE +0 -0
  219. {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/WHEEL +0 -0
  220. {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/entry_points.txt +0 -0
modal/volume.pyi CHANGED
@@ -1,4 +1,6 @@
1
1
  import asyncio.locks
2
+ import collections.abc
3
+ import enum
2
4
  import modal._utils.blob_utils
3
5
  import modal.client
4
6
  import modal.object
@@ -8,270 +10,333 @@ import synchronicity.combined_types
8
10
  import typing
9
11
  import typing_extensions
10
12
 
11
- class _Volume(modal.object._Object):
12
- _lock: asyncio.locks.Lock
13
-
14
- def _initialize_from_empty(self):
15
- ...
13
+ class FileEntryType(enum.IntEnum):
14
+ """Type of a file entry listed from a Modal volume."""
16
15
 
17
- @staticmethod
18
- def new() -> _Volume:
19
- ...
16
+ UNSPECIFIED = 0
17
+ FILE = 1
18
+ DIRECTORY = 2
19
+ SYMLINK = 3
20
20
 
21
- @staticmethod
22
- def from_name(label: str, namespace=1, environment_name: typing.Union[str, None] = None, create_if_missing: bool = False) -> _Volume:
23
- ...
21
+ class FileEntry:
22
+ path: str
23
+ type: FileEntryType
24
+ mtime: int
25
+ size: int
24
26
 
25
27
  @classmethod
26
- def ephemeral(cls: typing.Type[_Volume], client: typing.Union[modal.client._Client, None] = None, environment_name: typing.Union[str, None] = None, _heartbeat_sleep: float = 300) -> typing.AsyncContextManager[_Volume]:
27
- ...
28
+ def _from_proto(cls, proto: modal_proto.api_pb2.FileEntry) -> FileEntry: ...
29
+ def __init__(self, path: str, type: FileEntryType, mtime: int, size: int) -> None: ...
30
+ def __repr__(self): ...
31
+ def __eq__(self, other): ...
32
+ def __setattr__(self, name, value): ...
33
+ def __delattr__(self, name): ...
34
+ def __hash__(self): ...
28
35
 
29
- @staticmethod
30
- def persisted(label: str, namespace=1, environment_name: typing.Union[str, None] = None, cloud: typing.Union[str, None] = None) -> _Volume:
31
- ...
36
+ class _Volume(modal.object._Object):
37
+ _lock: typing.Optional[asyncio.locks.Lock]
32
38
 
39
+ async def _get_lock(self): ...
33
40
  @staticmethod
34
- async def lookup(label: str, namespace=1, client: typing.Union[modal.client._Client, None] = None, environment_name: typing.Union[str, None] = None, create_if_missing: bool = False) -> _Volume:
35
- ...
36
-
41
+ def from_name(
42
+ name: str,
43
+ namespace=1,
44
+ environment_name: typing.Optional[str] = None,
45
+ create_if_missing: bool = False,
46
+ version: typing.Optional[int] = None,
47
+ ) -> _Volume: ...
48
+ @classmethod
49
+ def ephemeral(
50
+ cls: type[_Volume],
51
+ client: typing.Optional[modal.client._Client] = None,
52
+ environment_name: typing.Optional[str] = None,
53
+ version: typing.Optional[int] = None,
54
+ _heartbeat_sleep: float = 300,
55
+ ) -> typing.AsyncContextManager[_Volume]: ...
37
56
  @staticmethod
38
- async def create_deployed(deployment_name: str, namespace=1, client: typing.Union[modal.client._Client, None] = None, environment_name: typing.Union[str, None] = None) -> str:
39
- ...
40
-
41
- async def _do_reload(self, lock=True):
42
- ...
43
-
44
- async def commit(self):
45
- ...
46
-
47
- async def reload(self):
48
- ...
49
-
50
- def iterdir(self, path: str) -> typing.AsyncIterator[modal_proto.api_pb2.VolumeListFilesEntry]:
51
- ...
52
-
53
- async def listdir(self, path: str) -> typing.List[modal_proto.api_pb2.VolumeListFilesEntry]:
54
- ...
55
-
56
- def read_file(self, path: typing.Union[str, bytes]) -> typing.AsyncIterator[bytes]:
57
- ...
58
-
59
- async def read_file_into_fileobj(self, path: typing.Union[str, bytes], fileobj: typing.IO[bytes], progress: bool = False) -> int:
60
- ...
61
-
62
- async def remove_file(self, path: typing.Union[str, bytes], recursive: bool = False) -> None:
63
- ...
64
-
65
- async def copy_files(self, src_paths: typing.Sequence[typing.Union[str, bytes]], dst_path: typing.Union[str, bytes]) -> None:
66
- ...
67
-
68
- async def batch_upload(self, force: bool = False) -> _VolumeUploadContextManager:
69
- ...
70
-
71
- async def delete(self):
72
- ...
73
-
57
+ async def lookup(
58
+ name: str,
59
+ namespace=1,
60
+ client: typing.Optional[modal.client._Client] = None,
61
+ environment_name: typing.Optional[str] = None,
62
+ create_if_missing: bool = False,
63
+ version: typing.Optional[int] = None,
64
+ ) -> _Volume: ...
65
+ @staticmethod
66
+ async def create_deployed(
67
+ deployment_name: str,
68
+ namespace=1,
69
+ client: typing.Optional[modal.client._Client] = None,
70
+ environment_name: typing.Optional[str] = None,
71
+ version: typing.Optional[int] = None,
72
+ ) -> str: ...
73
+ async def _do_reload(self, lock=True): ...
74
+ async def commit(self): ...
75
+ async def reload(self): ...
76
+ def iterdir(self, path: str, *, recursive: bool = True) -> collections.abc.AsyncIterator[FileEntry]: ...
77
+ async def listdir(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
78
+ def read_file(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
79
+ async def read_file_into_fileobj(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
80
+ async def remove_file(self, path: str, recursive: bool = False) -> None: ...
81
+ async def copy_files(self, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
82
+ async def batch_upload(self, force: bool = False) -> _VolumeUploadContextManager: ...
83
+ async def _instance_delete(self): ...
84
+ @staticmethod
85
+ async def delete(
86
+ name: str, client: typing.Optional[modal.client._Client] = None, environment_name: typing.Optional[str] = None
87
+ ): ...
88
+ @staticmethod
89
+ async def rename(
90
+ old_name: str,
91
+ new_name: str,
92
+ *,
93
+ client: typing.Optional[modal.client._Client] = None,
94
+ environment_name: typing.Optional[str] = None,
95
+ ): ...
74
96
 
75
97
  class _VolumeUploadContextManager:
76
98
  _volume_id: str
77
99
  _client: modal.client._Client
78
100
  _force: bool
79
- _upload_generators: typing.List[typing.Generator[typing.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]]
80
-
81
- def __init__(self, volume_id: str, client: modal.client._Client, force: bool = False):
82
- ...
83
-
84
- async def __aenter__(self):
85
- ...
86
-
87
- async def __aexit__(self, exc_type, exc_val, exc_tb):
88
- ...
89
-
90
- def put_file(self, local_file: typing.Union[pathlib.Path, str, typing.BinaryIO], remote_path: typing.Union[pathlib.PurePosixPath, str], mode: typing.Union[int, None] = None):
91
- ...
92
-
93
- def put_directory(self, local_path: typing.Union[pathlib.Path, str], remote_path: typing.Union[pathlib.PurePosixPath, str], recursive: bool = True):
94
- ...
95
-
96
- async def _upload_file(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile:
97
- ...
98
-
101
+ progress_cb: typing.Callable[..., typing.Any]
102
+ _upload_generators: list[
103
+ collections.abc.Generator[typing.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]
104
+ ]
105
+
106
+ def __init__(
107
+ self,
108
+ volume_id: str,
109
+ client: modal.client._Client,
110
+ progress_cb: typing.Optional[typing.Callable[..., typing.Any]] = None,
111
+ force: bool = False,
112
+ ): ...
113
+ async def __aenter__(self): ...
114
+ async def __aexit__(self, exc_type, exc_val, exc_tb): ...
115
+ def put_file(
116
+ self,
117
+ local_file: typing.Union[pathlib.Path, str, typing.BinaryIO],
118
+ remote_path: typing.Union[pathlib.PurePosixPath, str],
119
+ mode: typing.Optional[int] = None,
120
+ ): ...
121
+ def put_directory(
122
+ self,
123
+ local_path: typing.Union[pathlib.Path, str],
124
+ remote_path: typing.Union[pathlib.PurePosixPath, str],
125
+ recursive: bool = True,
126
+ ): ...
127
+ async def _upload_file(
128
+ self, file_spec: modal._utils.blob_utils.FileUploadSpec
129
+ ) -> modal_proto.api_pb2.MountFile: ...
99
130
 
100
131
  class Volume(modal.object.Object):
101
- _lock: asyncio.locks.Lock
132
+ _lock: typing.Optional[asyncio.locks.Lock]
102
133
 
103
- def __init__(self, *args, **kwargs):
104
- ...
134
+ def __init__(self, *args, **kwargs): ...
105
135
 
106
- def _initialize_from_empty(self):
107
- ...
136
+ class ___get_lock_spec(typing_extensions.Protocol):
137
+ def __call__(self): ...
138
+ async def aio(self): ...
108
139
 
109
- @staticmethod
110
- def new() -> Volume:
111
- ...
140
+ _get_lock: ___get_lock_spec
112
141
 
113
142
  @staticmethod
114
- def from_name(label: str, namespace=1, environment_name: typing.Union[str, None] = None, create_if_missing: bool = False) -> Volume:
115
- ...
116
-
143
+ def from_name(
144
+ name: str,
145
+ namespace=1,
146
+ environment_name: typing.Optional[str] = None,
147
+ create_if_missing: bool = False,
148
+ version: typing.Optional[int] = None,
149
+ ) -> Volume: ...
117
150
  @classmethod
118
- def ephemeral(cls: typing.Type[Volume], client: typing.Union[modal.client.Client, None] = None, environment_name: typing.Union[str, None] = None, _heartbeat_sleep: float = 300) -> synchronicity.combined_types.AsyncAndBlockingContextManager[Volume]:
119
- ...
120
-
121
- @staticmethod
122
- def persisted(label: str, namespace=1, environment_name: typing.Union[str, None] = None, cloud: typing.Union[str, None] = None) -> Volume:
123
- ...
151
+ def ephemeral(
152
+ cls: type[Volume],
153
+ client: typing.Optional[modal.client.Client] = None,
154
+ environment_name: typing.Optional[str] = None,
155
+ version: typing.Optional[int] = None,
156
+ _heartbeat_sleep: float = 300,
157
+ ) -> synchronicity.combined_types.AsyncAndBlockingContextManager[Volume]: ...
124
158
 
125
159
  class __lookup_spec(typing_extensions.Protocol):
126
- def __call__(self, label: str, namespace=1, client: typing.Union[modal.client.Client, None] = None, environment_name: typing.Union[str, None] = None, create_if_missing: bool = False) -> Volume:
127
- ...
128
-
129
- async def aio(self, *args, **kwargs) -> Volume:
130
- ...
160
+ def __call__(
161
+ self,
162
+ name: str,
163
+ namespace=1,
164
+ client: typing.Optional[modal.client.Client] = None,
165
+ environment_name: typing.Optional[str] = None,
166
+ create_if_missing: bool = False,
167
+ version: typing.Optional[int] = None,
168
+ ) -> Volume: ...
169
+ async def aio(
170
+ self,
171
+ name: str,
172
+ namespace=1,
173
+ client: typing.Optional[modal.client.Client] = None,
174
+ environment_name: typing.Optional[str] = None,
175
+ create_if_missing: bool = False,
176
+ version: typing.Optional[int] = None,
177
+ ) -> Volume: ...
131
178
 
132
179
  lookup: __lookup_spec
133
180
 
134
181
  class __create_deployed_spec(typing_extensions.Protocol):
135
- def __call__(self, deployment_name: str, namespace=1, client: typing.Union[modal.client.Client, None] = None, environment_name: typing.Union[str, None] = None) -> str:
136
- ...
137
-
138
- async def aio(self, *args, **kwargs) -> str:
139
- ...
182
+ def __call__(
183
+ self,
184
+ deployment_name: str,
185
+ namespace=1,
186
+ client: typing.Optional[modal.client.Client] = None,
187
+ environment_name: typing.Optional[str] = None,
188
+ version: typing.Optional[int] = None,
189
+ ) -> str: ...
190
+ async def aio(
191
+ self,
192
+ deployment_name: str,
193
+ namespace=1,
194
+ client: typing.Optional[modal.client.Client] = None,
195
+ environment_name: typing.Optional[str] = None,
196
+ version: typing.Optional[int] = None,
197
+ ) -> str: ...
140
198
 
141
199
  create_deployed: __create_deployed_spec
142
200
 
143
201
  class ___do_reload_spec(typing_extensions.Protocol):
144
- def __call__(self, lock=True):
145
- ...
146
-
147
- async def aio(self, *args, **kwargs):
148
- ...
202
+ def __call__(self, lock=True): ...
203
+ async def aio(self, lock=True): ...
149
204
 
150
205
  _do_reload: ___do_reload_spec
151
206
 
152
207
  class __commit_spec(typing_extensions.Protocol):
153
- def __call__(self):
154
- ...
155
-
156
- async def aio(self, *args, **kwargs):
157
- ...
208
+ def __call__(self): ...
209
+ async def aio(self): ...
158
210
 
159
211
  commit: __commit_spec
160
212
 
161
213
  class __reload_spec(typing_extensions.Protocol):
162
- def __call__(self):
163
- ...
164
-
165
- async def aio(self, *args, **kwargs):
166
- ...
214
+ def __call__(self): ...
215
+ async def aio(self): ...
167
216
 
168
217
  reload: __reload_spec
169
218
 
170
219
  class __iterdir_spec(typing_extensions.Protocol):
171
- def __call__(self, path: str) -> typing.Iterator[modal_proto.api_pb2.VolumeListFilesEntry]:
172
- ...
173
-
174
- def aio(self, path: str) -> typing.AsyncIterator[modal_proto.api_pb2.VolumeListFilesEntry]:
175
- ...
220
+ def __call__(self, path: str, *, recursive: bool = True) -> typing.Iterator[FileEntry]: ...
221
+ def aio(self, path: str, *, recursive: bool = True) -> collections.abc.AsyncIterator[FileEntry]: ...
176
222
 
177
223
  iterdir: __iterdir_spec
178
224
 
179
225
  class __listdir_spec(typing_extensions.Protocol):
180
- def __call__(self, path: str) -> typing.List[modal_proto.api_pb2.VolumeListFilesEntry]:
181
- ...
182
-
183
- async def aio(self, *args, **kwargs) -> typing.List[modal_proto.api_pb2.VolumeListFilesEntry]:
184
- ...
226
+ def __call__(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
227
+ async def aio(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
185
228
 
186
229
  listdir: __listdir_spec
187
230
 
188
231
  class __read_file_spec(typing_extensions.Protocol):
189
- def __call__(self, path: typing.Union[str, bytes]) -> typing.Iterator[bytes]:
190
- ...
191
-
192
- def aio(self, path: typing.Union[str, bytes]) -> typing.AsyncIterator[bytes]:
193
- ...
232
+ def __call__(self, path: str) -> typing.Iterator[bytes]: ...
233
+ def aio(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
194
234
 
195
235
  read_file: __read_file_spec
196
236
 
197
237
  class __read_file_into_fileobj_spec(typing_extensions.Protocol):
198
- def __call__(self, path: typing.Union[str, bytes], fileobj: typing.IO[bytes], progress: bool = False) -> int:
199
- ...
200
-
201
- async def aio(self, *args, **kwargs) -> int:
202
- ...
238
+ def __call__(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
239
+ async def aio(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
203
240
 
204
241
  read_file_into_fileobj: __read_file_into_fileobj_spec
205
242
 
206
243
  class __remove_file_spec(typing_extensions.Protocol):
207
- def __call__(self, path: typing.Union[str, bytes], recursive: bool = False) -> None:
208
- ...
209
-
210
- async def aio(self, *args, **kwargs) -> None:
211
- ...
244
+ def __call__(self, path: str, recursive: bool = False) -> None: ...
245
+ async def aio(self, path: str, recursive: bool = False) -> None: ...
212
246
 
213
247
  remove_file: __remove_file_spec
214
248
 
215
249
  class __copy_files_spec(typing_extensions.Protocol):
216
- def __call__(self, src_paths: typing.Sequence[typing.Union[str, bytes]], dst_path: typing.Union[str, bytes]) -> None:
217
- ...
218
-
219
- async def aio(self, *args, **kwargs) -> None:
220
- ...
250
+ def __call__(self, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
251
+ async def aio(self, src_paths: collections.abc.Sequence[str], dst_path: str) -> None: ...
221
252
 
222
253
  copy_files: __copy_files_spec
223
254
 
224
255
  class __batch_upload_spec(typing_extensions.Protocol):
225
- def __call__(self, force: bool = False) -> VolumeUploadContextManager:
226
- ...
227
-
228
- async def aio(self, *args, **kwargs) -> VolumeUploadContextManager:
229
- ...
256
+ def __call__(self, force: bool = False) -> VolumeUploadContextManager: ...
257
+ async def aio(self, force: bool = False) -> VolumeUploadContextManager: ...
230
258
 
231
259
  batch_upload: __batch_upload_spec
232
260
 
233
- class __delete_spec(typing_extensions.Protocol):
234
- def __call__(self):
235
- ...
261
+ class ___instance_delete_spec(typing_extensions.Protocol):
262
+ def __call__(self): ...
263
+ async def aio(self): ...
236
264
 
237
- async def aio(self, *args, **kwargs):
238
- ...
265
+ _instance_delete: ___instance_delete_spec
266
+
267
+ class __delete_spec(typing_extensions.Protocol):
268
+ def __call__(
269
+ self,
270
+ name: str,
271
+ client: typing.Optional[modal.client.Client] = None,
272
+ environment_name: typing.Optional[str] = None,
273
+ ): ...
274
+ async def aio(
275
+ self,
276
+ name: str,
277
+ client: typing.Optional[modal.client.Client] = None,
278
+ environment_name: typing.Optional[str] = None,
279
+ ): ...
239
280
 
240
281
  delete: __delete_spec
241
282
 
283
+ class __rename_spec(typing_extensions.Protocol):
284
+ def __call__(
285
+ self,
286
+ old_name: str,
287
+ new_name: str,
288
+ *,
289
+ client: typing.Optional[modal.client.Client] = None,
290
+ environment_name: typing.Optional[str] = None,
291
+ ): ...
292
+ async def aio(
293
+ self,
294
+ old_name: str,
295
+ new_name: str,
296
+ *,
297
+ client: typing.Optional[modal.client.Client] = None,
298
+ environment_name: typing.Optional[str] = None,
299
+ ): ...
300
+
301
+ rename: __rename_spec
242
302
 
243
303
  class VolumeUploadContextManager:
244
304
  _volume_id: str
245
305
  _client: modal.client.Client
246
306
  _force: bool
247
- _upload_generators: typing.List[typing.Generator[typing.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]]
248
-
249
- def __init__(self, volume_id: str, client: modal.client.Client, force: bool = False):
250
- ...
251
-
252
- def __enter__(self):
253
- ...
254
-
255
- async def __aenter__(self, *args, **kwargs):
256
- ...
257
-
258
- def __exit__(self, exc_type, exc_val, exc_tb):
259
- ...
260
-
261
- async def __aexit__(self, *args, **kwargs):
262
- ...
263
-
264
- def put_file(self, local_file: typing.Union[pathlib.Path, str, typing.BinaryIO], remote_path: typing.Union[pathlib.PurePosixPath, str], mode: typing.Union[int, None] = None):
265
- ...
266
-
267
- def put_directory(self, local_path: typing.Union[pathlib.Path, str], remote_path: typing.Union[pathlib.PurePosixPath, str], recursive: bool = True):
268
- ...
307
+ progress_cb: typing.Callable[..., typing.Any]
308
+ _upload_generators: list[
309
+ collections.abc.Generator[typing.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]
310
+ ]
311
+
312
+ def __init__(
313
+ self,
314
+ volume_id: str,
315
+ client: modal.client.Client,
316
+ progress_cb: typing.Optional[typing.Callable[..., typing.Any]] = None,
317
+ force: bool = False,
318
+ ): ...
319
+ def __enter__(self): ...
320
+ async def __aenter__(self): ...
321
+ def __exit__(self, exc_type, exc_val, exc_tb): ...
322
+ async def __aexit__(self, exc_type, exc_val, exc_tb): ...
323
+ def put_file(
324
+ self,
325
+ local_file: typing.Union[pathlib.Path, str, typing.BinaryIO],
326
+ remote_path: typing.Union[pathlib.PurePosixPath, str],
327
+ mode: typing.Optional[int] = None,
328
+ ): ...
329
+ def put_directory(
330
+ self,
331
+ local_path: typing.Union[pathlib.Path, str],
332
+ remote_path: typing.Union[pathlib.PurePosixPath, str],
333
+ recursive: bool = True,
334
+ ): ...
269
335
 
270
336
  class ___upload_file_spec(typing_extensions.Protocol):
271
- def __call__(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile:
272
- ...
273
-
274
- async def aio(self, *args, **kwargs) -> modal_proto.api_pb2.MountFile:
275
- ...
337
+ def __call__(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile: ...
338
+ async def aio(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile: ...
276
339
 
277
340
  _upload_file: ___upload_file_spec
341
+
342
+ def _open_files_error_annotation(mount_path: str) -> typing.Optional[str]: ...
@@ -1,29 +1,29 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.62.16
3
+ Version: 0.72.11
4
4
  Summary: Python client library for Modal
5
5
  Author: Modal Labs
6
6
  Author-email: support@modal.com
7
7
  Project-URL: Homepage, https://modal.com
8
+ Project-URL: Source, https://github.com/modal-labs/modal-client
8
9
  Keywords: modal,client,cloud,serverless,infrastructure
9
10
  Classifier: Topic :: System :: Distributed Computing
10
11
  Classifier: Operating System :: OS Independent
11
12
  Classifier: License :: OSI Approved :: Apache Software License
12
13
  Classifier: Programming Language :: Python :: 3
13
- Requires-Python: >=3.8
14
+ Requires-Python: >=3.9
14
15
  Description-Content-Type: text/markdown
15
16
  License-File: LICENSE
16
17
  Requires-Dist: aiohttp
17
- Requires-Dist: aiostream (~=0.5.2)
18
18
  Requires-Dist: certifi
19
19
  Requires-Dist: click (>=8.1.0)
20
20
  Requires-Dist: fastapi
21
21
  Requires-Dist: grpclib (==0.4.7)
22
- Requires-Dist: protobuf (!=4.24.0,<5.0,>=3.19)
22
+ Requires-Dist: protobuf (!=4.24.0,<6.0,>=3.19)
23
23
  Requires-Dist: rich (>=12.0.0)
24
- Requires-Dist: synchronicity (~=0.6.3)
24
+ Requires-Dist: synchronicity (~=0.9.8)
25
25
  Requires-Dist: toml
26
- Requires-Dist: typer (~=0.9.0)
26
+ Requires-Dist: typer (>=0.9)
27
27
  Requires-Dist: types-certifi
28
28
  Requires-Dist: types-toml
29
29
  Requires-Dist: watchfiles
@@ -48,7 +48,7 @@ a [user guide](https://modal.com/docs/guide), and the detailed
48
48
 
49
49
  ## Installation
50
50
 
51
- **This library requires Python 3.8 – 3.12.**
51
+ **This library requires Python 3.9 – 3.13.**
52
52
 
53
53
  Install the package with `pip`:
54
54