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/runner.pyi CHANGED
@@ -1,89 +1,153 @@
1
- import modal._output
2
1
  import modal.client
2
+ import modal.cls
3
+ import modal.functions
4
+ import modal.running_app
5
+ import modal_proto.api_pb2
3
6
  import multiprocessing.synchronize
4
7
  import synchronicity.combined_types
5
8
  import typing
6
9
  import typing_extensions
7
10
 
8
- _Stub = typing.TypeVar("_Stub")
9
-
10
- async def _heartbeat(client, app_id):
11
- ...
12
-
13
-
14
- def _run_stub(stub: _Stub, client: typing.Union[modal.client._Client, None] = None, stdout=None, show_progress: bool = True, detach: bool = False, output_mgr: typing.Union[modal._output.OutputManager, None] = None, environment_name: typing.Union[str, None] = None, shell=False, interactive=False) -> typing.AsyncContextManager[_Stub]:
15
- ...
16
-
17
-
18
- async def _serve_update(stub, existing_app_id: str, is_ready: multiprocessing.synchronize.Event, environment_name: str) -> None:
19
- ...
20
-
11
+ _App = typing.TypeVar("_App")
12
+
13
+ V = typing.TypeVar("V")
14
+
15
+ async def _heartbeat(client: modal.client._Client, app_id: str) -> None: ...
16
+ async def _init_local_app_existing(
17
+ client: modal.client._Client, existing_app_id: str, environment_name: str
18
+ ) -> modal.running_app.RunningApp: ...
19
+ async def _init_local_app_new(
20
+ client: modal.client._Client,
21
+ description: str,
22
+ app_state: int,
23
+ environment_name: str = "",
24
+ interactive: bool = False,
25
+ ) -> modal.running_app.RunningApp: ...
26
+ async def _init_local_app_from_name(
27
+ client: modal.client._Client, name: str, namespace: typing.Any, environment_name: str = ""
28
+ ) -> modal.running_app.RunningApp: ...
29
+ async def _create_all_objects(
30
+ client: modal.client._Client,
31
+ running_app: modal.running_app.RunningApp,
32
+ functions: dict[str, modal.functions._Function],
33
+ classes: dict[str, modal.cls._Cls],
34
+ environment_name: str,
35
+ ) -> None: ...
36
+ async def _publish_app(
37
+ client: modal.client._Client,
38
+ running_app: modal.running_app.RunningApp,
39
+ app_state: int,
40
+ functions: dict[str, modal.functions._Function],
41
+ classes: dict[str, modal.cls._Cls],
42
+ name: str = "",
43
+ tag: str = "",
44
+ ) -> tuple[str, list[modal_proto.api_pb2.Warning]]: ...
45
+ async def _disconnect(client: modal.client._Client, app_id: str, reason: int, exc_str: str = "") -> None: ...
46
+ async def _status_based_disconnect(
47
+ client: modal.client._Client, app_id: str, exc_info: typing.Optional[BaseException] = None
48
+ ): ...
49
+ def _run_app(
50
+ app: _App,
51
+ *,
52
+ client: typing.Optional[modal.client._Client] = None,
53
+ detach: bool = False,
54
+ environment_name: typing.Optional[str] = None,
55
+ interactive: bool = False,
56
+ ) -> typing.AsyncContextManager[_App]: ...
57
+ async def _serve_update(
58
+ app: _App, existing_app_id: str, is_ready: multiprocessing.synchronize.Event, environment_name: str
59
+ ) -> None: ...
21
60
 
22
61
  class DeployResult:
23
62
  app_id: str
24
-
25
- def __init__(self, app_id: str) -> None:
26
- ...
27
-
28
- def __repr__(self):
29
- ...
30
-
31
- def __eq__(self, other):
32
- ...
33
-
34
- def __setattr__(self, name, value):
35
- ...
36
-
37
- def __delattr__(self, name):
38
- ...
39
-
40
- def __hash__(self):
41
- ...
42
-
43
-
44
- async def _deploy_stub(stub: _Stub, name: str = None, namespace=1, client=None, stdout=None, show_progress=True, environment_name: typing.Union[str, None] = None, public: bool = False) -> DeployResult:
45
- ...
46
-
47
-
48
- async def _interactive_shell(_stub: _Stub, cmd: typing.List[str], environment_name: str = '', **kwargs):
49
- ...
50
-
51
-
52
- class __run_stub_spec(typing_extensions.Protocol):
53
- def __call__(self, stub: _Stub, client: typing.Union[modal.client.Client, None] = None, stdout=None, show_progress: bool = True, detach: bool = False, output_mgr: typing.Union[modal._output.OutputManager, None] = None, environment_name: typing.Union[str, None] = None, shell=False, interactive=False) -> synchronicity.combined_types.AsyncAndBlockingContextManager[_Stub]:
54
- ...
55
-
56
- def aio(self, stub: _Stub, client: typing.Union[modal.client.Client, None] = None, stdout=None, show_progress: bool = True, detach: bool = False, output_mgr: typing.Union[modal._output.OutputManager, None] = None, environment_name: typing.Union[str, None] = None, shell=False, interactive=False) -> typing.AsyncContextManager[_Stub]:
57
- ...
58
-
59
- run_stub: __run_stub_spec
60
-
63
+ app_page_url: str
64
+ app_logs_url: str
65
+ warnings: list[str]
66
+
67
+ def __init__(self, app_id: str, app_page_url: str, app_logs_url: str, warnings: list[str]) -> None: ...
68
+ def __repr__(self): ...
69
+ def __eq__(self, other): ...
70
+ def __setattr__(self, name, value): ...
71
+ def __delattr__(self, name): ...
72
+ def __hash__(self): ...
73
+
74
+ async def _deploy_app(
75
+ app: _App,
76
+ name: typing.Optional[str] = None,
77
+ namespace: typing.Any = 1,
78
+ client: typing.Optional[modal.client._Client] = None,
79
+ environment_name: typing.Optional[str] = None,
80
+ tag: str = "",
81
+ ) -> DeployResult: ...
82
+ async def _interactive_shell(
83
+ _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: typing.Any
84
+ ) -> None: ...
85
+ def _run_stub(*args: typing.Any, **kwargs: typing.Any): ...
86
+ def _deploy_stub(*args: typing.Any, **kwargs: typing.Any): ...
87
+
88
+ class __run_app_spec(typing_extensions.Protocol):
89
+ def __call__(
90
+ self,
91
+ app: _App,
92
+ *,
93
+ client: typing.Optional[modal.client.Client] = None,
94
+ detach: bool = False,
95
+ environment_name: typing.Optional[str] = None,
96
+ interactive: bool = False,
97
+ ) -> synchronicity.combined_types.AsyncAndBlockingContextManager[_App]: ...
98
+ def aio(
99
+ self,
100
+ app: _App,
101
+ *,
102
+ client: typing.Optional[modal.client.Client] = None,
103
+ detach: bool = False,
104
+ environment_name: typing.Optional[str] = None,
105
+ interactive: bool = False,
106
+ ) -> typing.AsyncContextManager[_App]: ...
107
+
108
+ run_app: __run_app_spec
61
109
 
62
110
  class __serve_update_spec(typing_extensions.Protocol):
63
- def __call__(self, stub, existing_app_id: str, is_ready: multiprocessing.synchronize.Event, environment_name: str) -> None:
64
- ...
65
-
66
- async def aio(self, *args, **kwargs) -> None:
67
- ...
111
+ def __call__(
112
+ self, app: _App, existing_app_id: str, is_ready: multiprocessing.synchronize.Event, environment_name: str
113
+ ) -> None: ...
114
+ async def aio(
115
+ self, app: _App, existing_app_id: str, is_ready: multiprocessing.synchronize.Event, environment_name: str
116
+ ) -> None: ...
68
117
 
69
118
  serve_update: __serve_update_spec
70
119
 
71
-
72
- class __deploy_stub_spec(typing_extensions.Protocol):
73
- def __call__(self, stub: _Stub, name: str = None, namespace=1, client=None, stdout=None, show_progress=True, environment_name: typing.Union[str, None] = None, public: bool = False) -> DeployResult:
74
- ...
75
-
76
- async def aio(self, *args, **kwargs) -> DeployResult:
77
- ...
78
-
79
- deploy_stub: __deploy_stub_spec
80
-
120
+ class __deploy_app_spec(typing_extensions.Protocol):
121
+ def __call__(
122
+ self,
123
+ app: _App,
124
+ name: typing.Optional[str] = None,
125
+ namespace: typing.Any = 1,
126
+ client: typing.Optional[modal.client.Client] = None,
127
+ environment_name: typing.Optional[str] = None,
128
+ tag: str = "",
129
+ ) -> DeployResult: ...
130
+ async def aio(
131
+ self,
132
+ app: _App,
133
+ name: typing.Optional[str] = None,
134
+ namespace: typing.Any = 1,
135
+ client: typing.Optional[modal.client.Client] = None,
136
+ environment_name: typing.Optional[str] = None,
137
+ tag: str = "",
138
+ ) -> DeployResult: ...
139
+
140
+ deploy_app: __deploy_app_spec
81
141
 
82
142
  class __interactive_shell_spec(typing_extensions.Protocol):
83
- def __call__(self, _stub: _Stub, cmd: typing.List[str], environment_name: str = '', **kwargs):
84
- ...
85
-
86
- async def aio(self, *args, **kwargs):
87
- ...
143
+ def __call__(
144
+ self, _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: typing.Any
145
+ ) -> None: ...
146
+ async def aio(
147
+ self, _app: _App, cmds: list[str], environment_name: str = "", pty: bool = True, **kwargs: typing.Any
148
+ ) -> None: ...
88
149
 
89
150
  interactive_shell: __interactive_shell_spec
151
+
152
+ def run_stub(*args: typing.Any, **kwargs: typing.Any): ...
153
+ def deploy_stub(*args: typing.Any, **kwargs: typing.Any): ...
modal/running_app.py ADDED
@@ -0,0 +1,38 @@
1
+ # Copyright Modal Labs 2024
2
+ from dataclasses import dataclass, field
3
+ from typing import Optional
4
+
5
+ from google.protobuf.message import Message
6
+
7
+ from modal._utils.grpc_utils import get_proto_oneof
8
+ from modal_proto import api_pb2
9
+
10
+
11
+ @dataclass
12
+ class RunningApp:
13
+ app_id: str
14
+ app_page_url: Optional[str] = None
15
+ app_logs_url: Optional[str] = None
16
+ function_ids: dict[str, str] = field(default_factory=dict)
17
+ class_ids: dict[str, str] = field(default_factory=dict)
18
+ object_handle_metadata: dict[str, Optional[Message]] = field(default_factory=dict)
19
+ interactive: bool = False
20
+
21
+
22
+ def running_app_from_layout(
23
+ app_id: str,
24
+ app_layout: api_pb2.AppLayout,
25
+ app_page_url: Optional[str] = None,
26
+ ) -> RunningApp:
27
+ object_handle_metadata = {}
28
+ for obj in app_layout.objects:
29
+ handle_metadata: Optional[Message] = get_proto_oneof(obj, "handle_metadata_oneof")
30
+ object_handle_metadata[obj.object_id] = handle_metadata
31
+
32
+ return RunningApp(
33
+ app_id,
34
+ function_ids=dict(app_layout.function_ids),
35
+ class_ids=dict(app_layout.class_ids),
36
+ object_handle_metadata=object_handle_metadata,
37
+ app_page_url=app_page_url,
38
+ )