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
test/cli_imports_test.py DELETED
@@ -1,149 +0,0 @@
1
- # Copyright Modal Labs 2023
2
- import pytest
3
-
4
- from modal._utils.async_utils import synchronizer
5
- from modal.app import _App, _LocalEntrypoint
6
- from modal.cli.import_refs import (
7
- DEFAULT_APP_NAME,
8
- get_by_object_path,
9
- import_file_or_module,
10
- parse_import_ref,
11
- )
12
-
13
- # Some helper vars for import_stub tests:
14
- local_entrypoint_src = """
15
- import modal
16
-
17
- app = modal.App()
18
- @app.local_entrypoint()
19
- def main():
20
- pass
21
- """
22
- python_module_src = """
23
- import modal
24
- app = modal.App("FOO")
25
- other_app = modal.App("BAR")
26
- @other_app.function()
27
- def func():
28
- pass
29
- @app.cls()
30
- class Parent:
31
- @modal.method()
32
- def meth(self):
33
- pass
34
-
35
- assert not __package__
36
- """
37
-
38
- python_package_src = """
39
- import modal
40
- app = modal.App("FOO")
41
- other_app = modal.App("BAR")
42
- @other_app.function()
43
- def func():
44
- pass
45
- assert __package__ == "pack"
46
- """
47
-
48
- python_subpackage_src = """
49
- import modal
50
- app = modal.App("FOO")
51
- other_app = modal.App("BAR")
52
- @other_app.function()
53
- def func():
54
- pass
55
- assert __package__ == "pack.sub"
56
- """
57
-
58
- python_file_src = """
59
- import modal
60
- app = modal.App("FOO")
61
- other_app = modal.App("BAR")
62
- @other_app.function()
63
- def func():
64
- pass
65
-
66
- assert __package__ == ""
67
- """
68
-
69
- empty_dir_with_python_file = {"mod.py": python_module_src}
70
-
71
-
72
- dir_containing_python_package = {
73
- "dir": {"sub": {"mod.py": python_module_src, "subfile.py": python_file_src}},
74
- "pack": {
75
- "file.py": python_file_src,
76
- "mod.py": python_package_src,
77
- "local.py": local_entrypoint_src,
78
- "__init__.py": "",
79
- "sub": {"mod.py": python_subpackage_src, "__init__.py": "", "subfile.py": python_file_src},
80
- },
81
- }
82
-
83
-
84
- @pytest.mark.parametrize(
85
- ["dir_structure", "ref", "expected_object_type"],
86
- [
87
- # # file syntax
88
- (empty_dir_with_python_file, "mod.py", _App),
89
- (empty_dir_with_python_file, "mod.py::app", _App),
90
- (empty_dir_with_python_file, "mod.py::other_app", _App),
91
- (dir_containing_python_package, "pack/file.py", _App),
92
- (dir_containing_python_package, "pack/sub/subfile.py", _App),
93
- (dir_containing_python_package, "dir/sub/subfile.py", _App),
94
- # # python module syntax
95
- (empty_dir_with_python_file, "mod", _App),
96
- (empty_dir_with_python_file, "mod::app", _App),
97
- (empty_dir_with_python_file, "mod::other_app", _App),
98
- (dir_containing_python_package, "pack.mod", _App),
99
- (dir_containing_python_package, "pack.mod::other_app", _App),
100
- (dir_containing_python_package, "pack/local.py::app.main", _LocalEntrypoint),
101
- ],
102
- )
103
- def test_import_object(dir_structure, ref, expected_object_type, mock_dir):
104
- with mock_dir(dir_structure):
105
- import_ref = parse_import_ref(ref)
106
- module = import_file_or_module(import_ref.file_or_module)
107
- imported_object = get_by_object_path(module, import_ref.object_path or DEFAULT_APP_NAME)
108
- _translated_obj = synchronizer._translate_in(imported_object)
109
- assert isinstance(_translated_obj, expected_object_type)
110
-
111
-
112
- def test_import_package_and_module_names(monkeypatch, supports_dir):
113
- # We try to reproduce the package/module naming standard that the `python` command line tool uses,
114
- # i.e. when loading using a module path (-m flag w/ python) you get a fully qualified package/module name
115
- # but when loading using a filename, some/mod.py it will not have a __package__
116
-
117
- # The biggest difference is that __name__ of the imported "entrypoint" script
118
- # is __main__ when using `python` but in the Modal runtime it's the name of the
119
- # file minus the ".py", since Modal has its own __main__
120
- monkeypatch.chdir(supports_dir)
121
- mod1 = import_file_or_module("assert_package")
122
- assert mod1.__package__ == ""
123
- assert mod1.__name__ == "assert_package"
124
-
125
- monkeypatch.chdir(supports_dir.parent)
126
- mod2 = import_file_or_module("test.supports.assert_package")
127
- assert mod2.__package__ == "test.supports"
128
- assert mod2.__name__ == "test.supports.assert_package"
129
-
130
- mod3 = import_file_or_module("supports/assert_package.py")
131
- assert mod3.__package__ == ""
132
- assert mod3.__name__ == "assert_package"
133
-
134
-
135
- def test_get_by_object_path():
136
- class NS(dict):
137
- def __getattr__(self, n):
138
- return dict.__getitem__(self, n)
139
-
140
- # simple
141
- assert get_by_object_path(NS(foo="bar"), "foo") == "bar"
142
- assert get_by_object_path(NS(foo="bar"), "bar") is None
143
-
144
- # nested simple
145
- assert get_by_object_path(NS(foo=NS(bar="baz")), "foo.bar") == "baz"
146
-
147
- # try to find item keys with periods in them (ugh).
148
- # this helps resolving lifecycled functions
149
- assert get_by_object_path(NS({"foo.bar": "baz"}), "foo.bar") == "baz"