modal 0.62.115__py3-none-any.whl → 0.72.13__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 +13 -9
  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 +402 -398
  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 -60
  11. modal/_resources.py +26 -7
  12. modal/_runtime/__init__.py +1 -0
  13. modal/_runtime/asgi.py +519 -0
  14. modal/_runtime/container_io_manager.py +1025 -0
  15. modal/{execution_context.py → _runtime/execution_context.py} +11 -2
  16. modal/_runtime/telemetry.py +169 -0
  17. modal/_runtime/user_code_imports.py +356 -0
  18. modal/_serialization.py +123 -6
  19. modal/_traceback.py +47 -187
  20. modal/_tunnel.py +50 -14
  21. modal/_tunnel.pyi +19 -36
  22. modal/_utils/app_utils.py +3 -17
  23. modal/_utils/async_utils.py +386 -104
  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 +299 -98
  29. modal/_utils/grpc_testing.py +47 -34
  30. modal/_utils/grpc_utils.py +54 -21
  31. modal/_utils/hash_utils.py +51 -10
  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 +3 -3
  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 +12 -10
  43. modal/app.py +561 -323
  44. modal/app.pyi +474 -262
  45. modal/call_graph.py +7 -6
  46. modal/cli/_download.py +22 -6
  47. modal/cli/_traceback.py +200 -0
  48. modal/cli/app.py +203 -42
  49. modal/cli/config.py +12 -5
  50. modal/cli/container.py +61 -13
  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 +21 -48
  55. modal/cli/launch.py +28 -14
  56. modal/cli/network_file_system.py +57 -21
  57. modal/cli/profile.py +1 -1
  58. modal/cli/programs/run_jupyter.py +34 -9
  59. modal/cli/programs/vscode.py +58 -8
  60. modal/cli/queues.py +131 -0
  61. modal/cli/run.py +199 -96
  62. modal/cli/secret.py +5 -4
  63. modal/cli/token.py +7 -2
  64. modal/cli/utils.py +74 -8
  65. modal/cli/volume.py +97 -56
  66. modal/client.py +248 -144
  67. modal/client.pyi +156 -124
  68. modal/cloud_bucket_mount.py +43 -30
  69. modal/cloud_bucket_mount.pyi +32 -25
  70. modal/cls.py +528 -141
  71. modal/cls.pyi +189 -145
  72. modal/config.py +32 -15
  73. modal/container_process.py +177 -0
  74. modal/container_process.pyi +82 -0
  75. modal/dict.py +50 -54
  76. modal/dict.pyi +120 -164
  77. modal/environments.py +106 -5
  78. modal/environments.pyi +77 -25
  79. modal/exception.py +30 -43
  80. modal/experimental.py +62 -2
  81. modal/file_io.py +537 -0
  82. modal/file_io.pyi +235 -0
  83. modal/file_pattern_matcher.py +196 -0
  84. modal/functions.py +846 -428
  85. modal/functions.pyi +446 -387
  86. modal/gpu.py +57 -44
  87. modal/image.py +943 -417
  88. modal/image.pyi +584 -245
  89. modal/io_streams.py +434 -0
  90. modal/io_streams.pyi +122 -0
  91. modal/mount.py +223 -90
  92. modal/mount.pyi +241 -243
  93. modal/network_file_system.py +85 -86
  94. modal/network_file_system.pyi +151 -110
  95. modal/object.py +66 -36
  96. modal/object.pyi +166 -143
  97. modal/output.py +63 -0
  98. modal/parallel_map.py +73 -47
  99. modal/parallel_map.pyi +51 -63
  100. modal/partial_function.py +272 -107
  101. modal/partial_function.pyi +219 -120
  102. modal/proxy.py +15 -12
  103. modal/proxy.pyi +3 -8
  104. modal/queue.py +96 -72
  105. modal/queue.pyi +210 -135
  106. modal/requirements/2024.04.txt +2 -1
  107. modal/requirements/2024.10.txt +16 -0
  108. modal/requirements/README.md +21 -0
  109. modal/requirements/base-images.json +22 -0
  110. modal/retries.py +45 -4
  111. modal/runner.py +325 -203
  112. modal/runner.pyi +124 -110
  113. modal/running_app.py +27 -4
  114. modal/sandbox.py +509 -231
  115. modal/sandbox.pyi +396 -169
  116. modal/schedule.py +2 -2
  117. modal/scheduler_placement.py +20 -3
  118. modal/secret.py +41 -25
  119. modal/secret.pyi +62 -42
  120. modal/serving.py +39 -49
  121. modal/serving.pyi +37 -43
  122. modal/stream_type.py +15 -0
  123. modal/token_flow.py +5 -3
  124. modal/token_flow.pyi +37 -32
  125. modal/volume.py +123 -137
  126. modal/volume.pyi +228 -221
  127. {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/METADATA +5 -5
  128. modal-0.72.13.dist-info/RECORD +174 -0
  129. {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/top_level.txt +0 -1
  130. modal_docs/gen_reference_docs.py +3 -1
  131. modal_docs/mdmd/mdmd.py +0 -1
  132. modal_docs/mdmd/signatures.py +1 -2
  133. modal_global_objects/images/base_images.py +28 -0
  134. modal_global_objects/mounts/python_standalone.py +2 -2
  135. modal_proto/__init__.py +1 -1
  136. modal_proto/api.proto +1231 -531
  137. modal_proto/api_grpc.py +750 -430
  138. modal_proto/api_pb2.py +2102 -1176
  139. modal_proto/api_pb2.pyi +8859 -0
  140. modal_proto/api_pb2_grpc.py +1329 -675
  141. modal_proto/api_pb2_grpc.pyi +1416 -0
  142. modal_proto/modal_api_grpc.py +149 -0
  143. modal_proto/modal_options_grpc.py +3 -0
  144. modal_proto/options_pb2.pyi +20 -0
  145. modal_proto/options_pb2_grpc.pyi +7 -0
  146. modal_proto/py.typed +0 -0
  147. modal_version/__init__.py +1 -1
  148. modal_version/_version_generated.py +2 -2
  149. modal/_asgi.py +0 -370
  150. modal/_container_exec.py +0 -128
  151. modal/_container_io_manager.py +0 -646
  152. modal/_container_io_manager.pyi +0 -412
  153. modal/_sandbox_shell.py +0 -49
  154. modal/app_utils.py +0 -20
  155. modal/app_utils.pyi +0 -17
  156. modal/execution_context.pyi +0 -37
  157. modal/shared_volume.py +0 -23
  158. modal/shared_volume.pyi +0 -24
  159. modal-0.62.115.dist-info/RECORD +0 -207
  160. modal_global_objects/images/conda.py +0 -15
  161. modal_global_objects/images/debian_slim.py +0 -15
  162. modal_global_objects/images/micromamba.py +0 -15
  163. test/__init__.py +0 -1
  164. test/aio_test.py +0 -12
  165. test/async_utils_test.py +0 -279
  166. test/blob_test.py +0 -67
  167. test/cli_imports_test.py +0 -149
  168. test/cli_test.py +0 -674
  169. test/client_test.py +0 -203
  170. test/cloud_bucket_mount_test.py +0 -22
  171. test/cls_test.py +0 -636
  172. test/config_test.py +0 -149
  173. test/conftest.py +0 -1485
  174. test/container_app_test.py +0 -50
  175. test/container_test.py +0 -1405
  176. test/cpu_test.py +0 -23
  177. test/decorator_test.py +0 -85
  178. test/deprecation_test.py +0 -34
  179. test/dict_test.py +0 -51
  180. test/e2e_test.py +0 -68
  181. test/error_test.py +0 -7
  182. test/function_serialization_test.py +0 -32
  183. test/function_test.py +0 -791
  184. test/function_utils_test.py +0 -101
  185. test/gpu_test.py +0 -159
  186. test/grpc_utils_test.py +0 -82
  187. test/helpers.py +0 -47
  188. test/image_test.py +0 -814
  189. test/live_reload_test.py +0 -80
  190. test/lookup_test.py +0 -70
  191. test/mdmd_test.py +0 -329
  192. test/mount_test.py +0 -162
  193. test/mounted_files_test.py +0 -327
  194. test/network_file_system_test.py +0 -188
  195. test/notebook_test.py +0 -66
  196. test/object_test.py +0 -41
  197. test/package_utils_test.py +0 -25
  198. test/queue_test.py +0 -115
  199. test/resolver_test.py +0 -59
  200. test/retries_test.py +0 -67
  201. test/runner_test.py +0 -85
  202. test/sandbox_test.py +0 -191
  203. test/schedule_test.py +0 -15
  204. test/scheduler_placement_test.py +0 -57
  205. test/secret_test.py +0 -89
  206. test/serialization_test.py +0 -50
  207. test/stub_composition_test.py +0 -10
  208. test/stub_test.py +0 -361
  209. test/test_asgi_wrapper.py +0 -234
  210. test/token_flow_test.py +0 -18
  211. test/traceback_test.py +0 -135
  212. test/tunnel_test.py +0 -29
  213. test/utils_test.py +0 -88
  214. test/version_test.py +0 -14
  215. test/volume_test.py +0 -397
  216. test/watcher_test.py +0 -58
  217. test/webhook_test.py +0 -145
  218. {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/LICENSE +0 -0
  219. {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/WHEEL +0 -0
  220. {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/entry_points.txt +0 -0
modal/volume.pyi CHANGED
@@ -1,4 +1,5 @@
1
1
  import asyncio.locks
2
+ import collections.abc
2
3
  import enum
3
4
  import modal._utils.blob_utils
4
5
  import modal.client
@@ -17,7 +18,6 @@ class FileEntryType(enum.IntEnum):
17
18
  DIRECTORY = 2
18
19
  SYMLINK = 3
19
20
 
20
-
21
21
  class FileEntry:
22
22
  path: str
23
23
  type: FileEntryType
@@ -25,311 +25,318 @@ class FileEntry:
25
25
  size: int
26
26
 
27
27
  @classmethod
28
- def _from_proto(cls, proto: modal_proto.api_pb2.FileEntry) -> FileEntry:
29
- ...
30
-
31
- def __getattr__(self, name: str):
32
- ...
33
-
34
- def __init__(self, path: str, type: FileEntryType, mtime: int, size: int) -> None:
35
- ...
36
-
37
- def __repr__(self):
38
- ...
39
-
40
- def __eq__(self, other):
41
- ...
42
-
43
- def __setattr__(self, name, value):
44
- ...
45
-
46
- def __delattr__(self, name):
47
- ...
48
-
49
- def __hash__(self):
50
- ...
51
-
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): ...
52
35
 
53
36
  class _Volume(modal.object._Object):
54
- _lock: asyncio.locks.Lock
55
-
56
- def _initialize_from_empty(self):
57
- ...
58
-
59
- @staticmethod
60
- def new() -> _Volume:
61
- ...
37
+ _lock: typing.Optional[asyncio.locks.Lock]
62
38
 
39
+ async def _get_lock(self): ...
63
40
  @staticmethod
64
- def from_name(label: str, namespace=1, environment_name: typing.Union[str, None] = None, create_if_missing: bool = False) -> _Volume:
65
- ...
66
-
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: ...
67
48
  @classmethod
68
- 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]:
69
- ...
70
-
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]: ...
71
56
  @staticmethod
72
- def persisted(label: str, namespace=1, environment_name: typing.Union[str, None] = None, cloud: typing.Union[str, None] = None) -> _Volume:
73
- ...
74
-
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: ...
75
65
  @staticmethod
76
- 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:
77
- ...
78
-
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): ...
79
84
  @staticmethod
80
- 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:
81
- ...
82
-
83
- async def _do_reload(self, lock=True):
84
- ...
85
-
86
- async def commit(self):
87
- ...
88
-
89
- async def reload(self):
90
- ...
91
-
92
- def iterdir(self, path: str, *, recursive: bool = True) -> typing.AsyncIterator[FileEntry]:
93
- ...
94
-
95
- async def listdir(self, path: str, *, recursive: bool = False) -> typing.List[FileEntry]:
96
- ...
97
-
98
- def read_file(self, path: typing.Union[str, bytes]) -> typing.AsyncIterator[bytes]:
99
- ...
100
-
101
- async def read_file_into_fileobj(self, path: typing.Union[str, bytes], fileobj: typing.IO[bytes]) -> int:
102
- ...
103
-
104
- async def remove_file(self, path: typing.Union[str, bytes], recursive: bool = False) -> None:
105
- ...
106
-
107
- async def copy_files(self, src_paths: typing.Sequence[typing.Union[str, bytes]], dst_path: typing.Union[str, bytes]) -> None:
108
- ...
109
-
110
- async def batch_upload(self, force: bool = False) -> _VolumeUploadContextManager:
111
- ...
112
-
113
- async def _instance_delete(self):
114
- ...
115
-
116
- async def delete(*args, label: str = '', client: typing.Union[modal.client._Client, None] = None, environment_name: typing.Union[str, None] = None):
117
- ...
118
-
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
+ ): ...
119
96
 
120
97
  class _VolumeUploadContextManager:
121
98
  _volume_id: str
122
99
  _client: modal.client._Client
123
100
  _force: bool
124
- _upload_generators: typing.List[typing.Generator[typing.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]]
125
-
126
- def __init__(self, volume_id: str, client: modal.client._Client, force: bool = False):
127
- ...
128
-
129
- async def __aenter__(self):
130
- ...
131
-
132
- async def __aexit__(self, exc_type, exc_val, exc_tb):
133
- ...
134
-
135
- 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):
136
- ...
137
-
138
- def put_directory(self, local_path: typing.Union[pathlib.Path, str], remote_path: typing.Union[pathlib.PurePosixPath, str], recursive: bool = True):
139
- ...
140
-
141
- async def _upload_file(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile:
142
- ...
143
-
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: ...
144
130
 
145
131
  class Volume(modal.object.Object):
146
- _lock: asyncio.locks.Lock
132
+ _lock: typing.Optional[asyncio.locks.Lock]
147
133
 
148
- def __init__(self, *args, **kwargs):
149
- ...
134
+ def __init__(self, *args, **kwargs): ...
150
135
 
151
- def _initialize_from_empty(self):
152
- ...
136
+ class ___get_lock_spec(typing_extensions.Protocol):
137
+ def __call__(self): ...
138
+ async def aio(self): ...
153
139
 
154
- @staticmethod
155
- def new() -> Volume:
156
- ...
140
+ _get_lock: ___get_lock_spec
157
141
 
158
142
  @staticmethod
159
- def from_name(label: str, namespace=1, environment_name: typing.Union[str, None] = None, create_if_missing: bool = False) -> Volume:
160
- ...
161
-
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: ...
162
150
  @classmethod
163
- 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]:
164
- ...
165
-
166
- @staticmethod
167
- def persisted(label: str, namespace=1, environment_name: typing.Union[str, None] = None, cloud: typing.Union[str, None] = None) -> Volume:
168
- ...
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]: ...
169
158
 
170
159
  class __lookup_spec(typing_extensions.Protocol):
171
- 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:
172
- ...
173
-
174
- async def aio(self, *args, **kwargs) -> Volume:
175
- ...
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: ...
176
178
 
177
179
  lookup: __lookup_spec
178
180
 
179
181
  class __create_deployed_spec(typing_extensions.Protocol):
180
- def __call__(self, deployment_name: str, namespace=1, client: typing.Union[modal.client.Client, None] = None, environment_name: typing.Union[str, None] = None) -> str:
181
- ...
182
-
183
- async def aio(self, *args, **kwargs) -> str:
184
- ...
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: ...
185
198
 
186
199
  create_deployed: __create_deployed_spec
187
200
 
188
201
  class ___do_reload_spec(typing_extensions.Protocol):
189
- def __call__(self, lock=True):
190
- ...
191
-
192
- async def aio(self, *args, **kwargs):
193
- ...
202
+ def __call__(self, lock=True): ...
203
+ async def aio(self, lock=True): ...
194
204
 
195
205
  _do_reload: ___do_reload_spec
196
206
 
197
207
  class __commit_spec(typing_extensions.Protocol):
198
- def __call__(self):
199
- ...
200
-
201
- async def aio(self, *args, **kwargs):
202
- ...
208
+ def __call__(self): ...
209
+ async def aio(self): ...
203
210
 
204
211
  commit: __commit_spec
205
212
 
206
213
  class __reload_spec(typing_extensions.Protocol):
207
- def __call__(self):
208
- ...
209
-
210
- async def aio(self, *args, **kwargs):
211
- ...
214
+ def __call__(self): ...
215
+ async def aio(self): ...
212
216
 
213
217
  reload: __reload_spec
214
218
 
215
219
  class __iterdir_spec(typing_extensions.Protocol):
216
- def __call__(self, path: str, *, recursive: bool = True) -> typing.Iterator[FileEntry]:
217
- ...
218
-
219
- def aio(self, path: str, *, recursive: bool = True) -> typing.AsyncIterator[FileEntry]:
220
- ...
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]: ...
221
222
 
222
223
  iterdir: __iterdir_spec
223
224
 
224
225
  class __listdir_spec(typing_extensions.Protocol):
225
- def __call__(self, path: str, *, recursive: bool = False) -> typing.List[FileEntry]:
226
- ...
227
-
228
- async def aio(self, *args, **kwargs) -> typing.List[FileEntry]:
229
- ...
226
+ def __call__(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
227
+ async def aio(self, path: str, *, recursive: bool = False) -> list[FileEntry]: ...
230
228
 
231
229
  listdir: __listdir_spec
232
230
 
233
231
  class __read_file_spec(typing_extensions.Protocol):
234
- def __call__(self, path: typing.Union[str, bytes]) -> typing.Iterator[bytes]:
235
- ...
236
-
237
- def aio(self, path: typing.Union[str, bytes]) -> typing.AsyncIterator[bytes]:
238
- ...
232
+ def __call__(self, path: str) -> typing.Iterator[bytes]: ...
233
+ def aio(self, path: str) -> collections.abc.AsyncIterator[bytes]: ...
239
234
 
240
235
  read_file: __read_file_spec
241
236
 
242
237
  class __read_file_into_fileobj_spec(typing_extensions.Protocol):
243
- def __call__(self, path: typing.Union[str, bytes], fileobj: typing.IO[bytes]) -> int:
244
- ...
245
-
246
- async def aio(self, *args, **kwargs) -> int:
247
- ...
238
+ def __call__(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
239
+ async def aio(self, path: str, fileobj: typing.IO[bytes]) -> int: ...
248
240
 
249
241
  read_file_into_fileobj: __read_file_into_fileobj_spec
250
242
 
251
243
  class __remove_file_spec(typing_extensions.Protocol):
252
- def __call__(self, path: typing.Union[str, bytes], recursive: bool = False) -> None:
253
- ...
254
-
255
- async def aio(self, *args, **kwargs) -> None:
256
- ...
244
+ def __call__(self, path: str, recursive: bool = False) -> None: ...
245
+ async def aio(self, path: str, recursive: bool = False) -> None: ...
257
246
 
258
247
  remove_file: __remove_file_spec
259
248
 
260
249
  class __copy_files_spec(typing_extensions.Protocol):
261
- def __call__(self, src_paths: typing.Sequence[typing.Union[str, bytes]], dst_path: typing.Union[str, bytes]) -> None:
262
- ...
263
-
264
- async def aio(self, *args, **kwargs) -> None:
265
- ...
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: ...
266
252
 
267
253
  copy_files: __copy_files_spec
268
254
 
269
255
  class __batch_upload_spec(typing_extensions.Protocol):
270
- def __call__(self, force: bool = False) -> VolumeUploadContextManager:
271
- ...
272
-
273
- async def aio(self, *args, **kwargs) -> VolumeUploadContextManager:
274
- ...
256
+ def __call__(self, force: bool = False) -> VolumeUploadContextManager: ...
257
+ async def aio(self, force: bool = False) -> VolumeUploadContextManager: ...
275
258
 
276
259
  batch_upload: __batch_upload_spec
277
260
 
278
261
  class ___instance_delete_spec(typing_extensions.Protocol):
279
- def __call__(self):
280
- ...
281
-
282
- async def aio(self, *args, **kwargs):
283
- ...
262
+ def __call__(self): ...
263
+ async def aio(self): ...
284
264
 
285
265
  _instance_delete: ___instance_delete_spec
286
266
 
287
267
  class __delete_spec(typing_extensions.Protocol):
288
- def __call__(self, *args, label: str = '', client: typing.Union[modal.client.Client, None] = None, environment_name: typing.Union[str, None] = None):
289
- ...
290
-
291
- async def aio(self, *args, **kwargs):
292
- ...
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
+ ): ...
293
280
 
294
281
  delete: __delete_spec
295
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
296
302
 
297
303
  class VolumeUploadContextManager:
298
304
  _volume_id: str
299
305
  _client: modal.client.Client
300
306
  _force: bool
301
- _upload_generators: typing.List[typing.Generator[typing.Callable[[], modal._utils.blob_utils.FileUploadSpec], None, None]]
302
-
303
- def __init__(self, volume_id: str, client: modal.client.Client, force: bool = False):
304
- ...
305
-
306
- def __enter__(self):
307
- ...
308
-
309
- async def __aenter__(self, *args, **kwargs):
310
- ...
311
-
312
- def __exit__(self, exc_type, exc_val, exc_tb):
313
- ...
314
-
315
- async def __aexit__(self, *args, **kwargs):
316
- ...
317
-
318
- 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):
319
- ...
320
-
321
- def put_directory(self, local_path: typing.Union[pathlib.Path, str], remote_path: typing.Union[pathlib.PurePosixPath, str], recursive: bool = True):
322
- ...
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
+ ): ...
323
335
 
324
336
  class ___upload_file_spec(typing_extensions.Protocol):
325
- def __call__(self, file_spec: modal._utils.blob_utils.FileUploadSpec) -> modal_proto.api_pb2.MountFile:
326
- ...
327
-
328
- async def aio(self, *args, **kwargs) -> modal_proto.api_pb2.MountFile:
329
- ...
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: ...
330
339
 
331
340
  _upload_file: ___upload_file_spec
332
341
 
333
-
334
- def _open_files_error_annotation(mount_path: str) -> typing.Union[str, None]:
335
- ...
342
+ def _open_files_error_annotation(mount_path: str) -> typing.Optional[str]: ...
@@ -1,27 +1,27 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: modal
3
- Version: 0.62.115
3
+ Version: 0.72.13
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
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.6)
24
+ Requires-Dist: synchronicity (~=0.9.8)
25
25
  Requires-Dist: toml
26
26
  Requires-Dist: typer (>=0.9)
27
27
  Requires-Dist: types-certifi
@@ -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