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.
- modal/__init__.py +17 -13
- modal/__main__.py +41 -3
- modal/_clustered_functions.py +80 -0
- modal/_clustered_functions.pyi +22 -0
- modal/_container_entrypoint.py +420 -937
- modal/_ipython.py +3 -13
- modal/_location.py +17 -10
- modal/_output.py +243 -99
- modal/_pty.py +2 -2
- modal/_resolver.py +55 -59
- modal/_resources.py +51 -0
- modal/_runtime/__init__.py +1 -0
- modal/_runtime/asgi.py +519 -0
- modal/_runtime/container_io_manager.py +1036 -0
- modal/_runtime/execution_context.py +89 -0
- modal/_runtime/telemetry.py +169 -0
- modal/_runtime/user_code_imports.py +356 -0
- modal/_serialization.py +134 -9
- modal/_traceback.py +47 -187
- modal/_tunnel.py +52 -16
- modal/_tunnel.pyi +19 -36
- modal/_utils/app_utils.py +3 -17
- modal/_utils/async_utils.py +479 -100
- modal/_utils/blob_utils.py +157 -186
- modal/_utils/bytes_io_segment_payload.py +97 -0
- modal/_utils/deprecation.py +89 -0
- modal/_utils/docker_utils.py +98 -0
- modal/_utils/function_utils.py +460 -171
- modal/_utils/grpc_testing.py +47 -31
- modal/_utils/grpc_utils.py +62 -109
- modal/_utils/hash_utils.py +61 -19
- modal/_utils/http_utils.py +39 -9
- modal/_utils/logger.py +2 -1
- modal/_utils/mount_utils.py +34 -16
- modal/_utils/name_utils.py +58 -0
- modal/_utils/package_utils.py +14 -1
- modal/_utils/pattern_utils.py +205 -0
- modal/_utils/rand_pb_testing.py +5 -7
- modal/_utils/shell_utils.py +15 -49
- modal/_vendor/a2wsgi_wsgi.py +62 -72
- modal/_vendor/cloudpickle.py +1 -1
- modal/_watcher.py +14 -12
- modal/app.py +1003 -314
- modal/app.pyi +540 -264
- modal/call_graph.py +7 -6
- modal/cli/_download.py +63 -53
- modal/cli/_traceback.py +200 -0
- modal/cli/app.py +205 -45
- modal/cli/config.py +12 -5
- modal/cli/container.py +62 -14
- modal/cli/dict.py +128 -0
- modal/cli/entry_point.py +26 -13
- modal/cli/environment.py +40 -9
- modal/cli/import_refs.py +64 -58
- modal/cli/launch.py +32 -18
- modal/cli/network_file_system.py +64 -83
- modal/cli/profile.py +1 -1
- modal/cli/programs/run_jupyter.py +35 -10
- modal/cli/programs/vscode.py +60 -10
- modal/cli/queues.py +131 -0
- modal/cli/run.py +234 -131
- modal/cli/secret.py +8 -7
- modal/cli/token.py +7 -2
- modal/cli/utils.py +79 -10
- modal/cli/volume.py +110 -109
- modal/client.py +250 -144
- modal/client.pyi +157 -118
- modal/cloud_bucket_mount.py +108 -34
- modal/cloud_bucket_mount.pyi +32 -38
- modal/cls.py +535 -148
- modal/cls.pyi +190 -146
- modal/config.py +41 -19
- modal/container_process.py +177 -0
- modal/container_process.pyi +82 -0
- modal/dict.py +111 -65
- modal/dict.pyi +136 -131
- modal/environments.py +106 -5
- modal/environments.pyi +77 -25
- modal/exception.py +34 -43
- modal/experimental.py +61 -2
- modal/extensions/ipython.py +5 -5
- modal/file_io.py +537 -0
- modal/file_io.pyi +235 -0
- modal/file_pattern_matcher.py +197 -0
- modal/functions.py +906 -911
- modal/functions.pyi +466 -430
- modal/gpu.py +57 -44
- modal/image.py +1089 -479
- modal/image.pyi +584 -228
- modal/io_streams.py +434 -0
- modal/io_streams.pyi +122 -0
- modal/mount.py +314 -101
- modal/mount.pyi +241 -235
- modal/network_file_system.py +92 -92
- modal/network_file_system.pyi +152 -110
- modal/object.py +67 -36
- modal/object.pyi +166 -143
- modal/output.py +63 -0
- modal/parallel_map.py +434 -0
- modal/parallel_map.pyi +75 -0
- modal/partial_function.py +282 -117
- modal/partial_function.pyi +222 -129
- modal/proxy.py +15 -12
- modal/proxy.pyi +3 -8
- modal/queue.py +182 -65
- modal/queue.pyi +218 -118
- modal/requirements/2024.04.txt +29 -0
- modal/requirements/2024.10.txt +16 -0
- modal/requirements/README.md +21 -0
- modal/requirements/base-images.json +22 -0
- modal/retries.py +48 -7
- modal/runner.py +459 -156
- modal/runner.pyi +135 -71
- modal/running_app.py +38 -0
- modal/sandbox.py +514 -236
- modal/sandbox.pyi +397 -169
- modal/schedule.py +4 -4
- modal/scheduler_placement.py +20 -3
- modal/secret.py +56 -31
- modal/secret.pyi +62 -42
- modal/serving.py +51 -56
- modal/serving.pyi +44 -36
- modal/stream_type.py +15 -0
- modal/token_flow.py +5 -3
- modal/token_flow.pyi +37 -32
- modal/volume.py +285 -157
- modal/volume.pyi +249 -184
- {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/METADATA +7 -7
- modal-0.72.11.dist-info/RECORD +174 -0
- {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/top_level.txt +0 -1
- modal_docs/gen_reference_docs.py +3 -1
- modal_docs/mdmd/mdmd.py +0 -1
- modal_docs/mdmd/signatures.py +5 -2
- modal_global_objects/images/base_images.py +28 -0
- modal_global_objects/mounts/python_standalone.py +2 -2
- modal_proto/__init__.py +1 -1
- modal_proto/api.proto +1288 -533
- modal_proto/api_grpc.py +856 -456
- modal_proto/api_pb2.py +2165 -1157
- modal_proto/api_pb2.pyi +8859 -0
- modal_proto/api_pb2_grpc.py +1674 -855
- modal_proto/api_pb2_grpc.pyi +1416 -0
- modal_proto/modal_api_grpc.py +149 -0
- modal_proto/modal_options_grpc.py +3 -0
- modal_proto/options_pb2.pyi +20 -0
- modal_proto/options_pb2_grpc.pyi +7 -0
- modal_proto/py.typed +0 -0
- modal_version/__init__.py +1 -1
- modal_version/_version_generated.py +2 -2
- modal/_asgi.py +0 -370
- modal/_container_entrypoint.pyi +0 -378
- modal/_container_exec.py +0 -128
- modal/_sandbox_shell.py +0 -49
- modal/shared_volume.py +0 -23
- modal/shared_volume.pyi +0 -24
- modal/stub.py +0 -783
- modal/stub.pyi +0 -332
- modal-0.62.16.dist-info/RECORD +0 -198
- modal_global_objects/images/conda.py +0 -15
- modal_global_objects/images/debian_slim.py +0 -15
- modal_global_objects/images/micromamba.py +0 -15
- test/__init__.py +0 -1
- test/aio_test.py +0 -12
- test/async_utils_test.py +0 -262
- test/blob_test.py +0 -67
- test/cli_imports_test.py +0 -149
- test/cli_test.py +0 -659
- test/client_test.py +0 -194
- test/cls_test.py +0 -630
- test/config_test.py +0 -137
- test/conftest.py +0 -1420
- test/container_app_test.py +0 -32
- test/container_test.py +0 -1389
- test/cpu_test.py +0 -23
- test/decorator_test.py +0 -85
- test/deprecation_test.py +0 -34
- test/dict_test.py +0 -33
- test/e2e_test.py +0 -68
- test/error_test.py +0 -7
- test/function_serialization_test.py +0 -32
- test/function_test.py +0 -653
- test/function_utils_test.py +0 -101
- test/gpu_test.py +0 -159
- test/grpc_utils_test.py +0 -141
- test/helpers.py +0 -42
- test/image_test.py +0 -669
- test/live_reload_test.py +0 -80
- test/lookup_test.py +0 -70
- test/mdmd_test.py +0 -329
- test/mount_test.py +0 -162
- test/mounted_files_test.py +0 -329
- test/network_file_system_test.py +0 -181
- test/notebook_test.py +0 -66
- test/object_test.py +0 -41
- test/package_utils_test.py +0 -25
- test/queue_test.py +0 -97
- test/resolver_test.py +0 -58
- test/retries_test.py +0 -67
- test/runner_test.py +0 -85
- test/sandbox_test.py +0 -191
- test/schedule_test.py +0 -15
- test/scheduler_placement_test.py +0 -29
- test/secret_test.py +0 -78
- test/serialization_test.py +0 -42
- test/stub_composition_test.py +0 -10
- test/stub_test.py +0 -360
- test/test_asgi_wrapper.py +0 -234
- test/token_flow_test.py +0 -18
- test/traceback_test.py +0 -135
- test/tunnel_test.py +0 -29
- test/utils_test.py +0 -88
- test/version_test.py +0 -14
- test/volume_test.py +0 -341
- test/watcher_test.py +0 -30
- test/webhook_test.py +0 -146
- /modal/{requirements.312.txt → requirements/2023.12.312.txt} +0 -0
- /modal/{requirements.txt → requirements/2023.12.txt} +0 -0
- {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/LICENSE +0 -0
- {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/WHEEL +0 -0
- {modal-0.62.16.dist-info → modal-0.72.11.dist-info}/entry_points.txt +0 -0
modal/object.pyi
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import collections.abc
|
1
2
|
import google.protobuf.message
|
2
3
|
import modal._resolver
|
3
4
|
import modal.client
|
@@ -8,189 +9,211 @@ O = typing.TypeVar("O", bound="_Object")
|
|
8
9
|
|
9
10
|
_BLOCKING_O = typing.TypeVar("_BLOCKING_O", bound="Object")
|
10
11
|
|
11
|
-
def _get_environment_name(
|
12
|
-
|
13
|
-
|
12
|
+
def _get_environment_name(
|
13
|
+
environment_name: typing.Optional[str] = None, resolver: typing.Optional[modal._resolver.Resolver] = None
|
14
|
+
) -> typing.Optional[str]: ...
|
14
15
|
|
15
16
|
class _Object:
|
16
|
-
_type_prefix: typing.ClassVar[typing.
|
17
|
-
_prefix_to_type: typing.ClassVar[
|
18
|
-
_load: typing.
|
19
|
-
|
17
|
+
_type_prefix: typing.ClassVar[typing.Optional[str]]
|
18
|
+
_prefix_to_type: typing.ClassVar[dict[str, type]]
|
19
|
+
_load: typing.Optional[
|
20
|
+
typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
21
|
+
]
|
22
|
+
_preload: typing.Optional[
|
23
|
+
typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
24
|
+
]
|
20
25
|
_rep: str
|
21
26
|
_is_another_app: bool
|
22
27
|
_hydrate_lazily: bool
|
23
|
-
_deps: typing.
|
24
|
-
_deduplication_key: typing.
|
28
|
+
_deps: typing.Optional[typing.Callable[..., list[_Object]]]
|
29
|
+
_deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]]
|
25
30
|
_object_id: str
|
26
31
|
_client: modal.client._Client
|
27
32
|
_is_hydrated: bool
|
33
|
+
_is_rehydrated: bool
|
28
34
|
|
29
35
|
@classmethod
|
30
|
-
def __init_subclass__(cls, type_prefix: typing.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
def
|
52
|
-
|
53
|
-
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
def
|
58
|
-
...
|
59
|
-
|
60
|
-
def clone(self: O) -> O:
|
61
|
-
...
|
62
|
-
|
36
|
+
def __init_subclass__(cls, type_prefix: typing.Optional[str] = None): ...
|
37
|
+
def __init__(self, *args, **kwargs): ...
|
38
|
+
def _init(
|
39
|
+
self,
|
40
|
+
rep: str,
|
41
|
+
load: typing.Optional[
|
42
|
+
typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
43
|
+
] = None,
|
44
|
+
is_another_app: bool = False,
|
45
|
+
preload: typing.Optional[
|
46
|
+
typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
47
|
+
] = None,
|
48
|
+
hydrate_lazily: bool = False,
|
49
|
+
deps: typing.Optional[typing.Callable[..., list[_Object]]] = None,
|
50
|
+
deduplication_key: typing.Optional[
|
51
|
+
typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
52
|
+
] = None,
|
53
|
+
): ...
|
54
|
+
def _unhydrate(self): ...
|
55
|
+
def _initialize_from_empty(self): ...
|
56
|
+
def _initialize_from_other(self, other): ...
|
57
|
+
def _hydrate(
|
58
|
+
self, object_id: str, client: modal.client._Client, metadata: typing.Optional[google.protobuf.message.Message]
|
59
|
+
): ...
|
60
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
61
|
+
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
62
|
+
def _validate_is_hydrated(self: O): ...
|
63
|
+
def clone(self: O) -> O: ...
|
63
64
|
@classmethod
|
64
|
-
def _from_loader(
|
65
|
-
|
66
|
-
|
65
|
+
def _from_loader(
|
66
|
+
cls,
|
67
|
+
load: typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]],
|
68
|
+
rep: str,
|
69
|
+
is_another_app: bool = False,
|
70
|
+
preload: typing.Optional[
|
71
|
+
typing.Callable[[O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
72
|
+
] = None,
|
73
|
+
hydrate_lazily: bool = False,
|
74
|
+
deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[_Object]]] = None,
|
75
|
+
deduplication_key: typing.Optional[
|
76
|
+
typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
77
|
+
] = None,
|
78
|
+
): ...
|
67
79
|
@classmethod
|
68
|
-
def
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
def _get_type_from_id(cls: type[O], object_id: str) -> type[O]: ...
|
81
|
+
@classmethod
|
82
|
+
def _is_id_type(cls: type[O], object_id) -> bool: ...
|
83
|
+
@classmethod
|
84
|
+
def _new_hydrated(
|
85
|
+
cls: type[O],
|
86
|
+
object_id: str,
|
87
|
+
client: modal.client._Client,
|
88
|
+
handle_metadata: typing.Optional[google.protobuf.message.Message],
|
89
|
+
is_another_app: bool = False,
|
90
|
+
) -> O: ...
|
91
|
+
def _hydrate_from_other(self, other: O): ...
|
92
|
+
def __repr__(self): ...
|
77
93
|
@property
|
78
|
-
def local_uuid(self):
|
79
|
-
...
|
80
|
-
|
94
|
+
def local_uuid(self): ...
|
81
95
|
@property
|
82
|
-
def object_id(self):
|
83
|
-
...
|
84
|
-
|
96
|
+
def object_id(self) -> str: ...
|
85
97
|
@property
|
86
|
-
def is_hydrated(self) -> bool:
|
87
|
-
...
|
88
|
-
|
98
|
+
def is_hydrated(self) -> bool: ...
|
89
99
|
@property
|
90
|
-
def deps(self) -> typing.Callable[...,
|
91
|
-
|
92
|
-
|
93
|
-
async def resolve(self):
|
94
|
-
...
|
95
|
-
|
100
|
+
def deps(self) -> typing.Callable[..., list[_Object]]: ...
|
101
|
+
async def resolve(self, client: typing.Optional[modal.client._Client] = None): ...
|
96
102
|
|
97
103
|
class Object:
|
98
|
-
_type_prefix: typing.ClassVar[typing.
|
99
|
-
_prefix_to_type: typing.ClassVar[
|
100
|
-
_load: typing.
|
101
|
-
|
104
|
+
_type_prefix: typing.ClassVar[typing.Optional[str]]
|
105
|
+
_prefix_to_type: typing.ClassVar[dict[str, type]]
|
106
|
+
_load: typing.Optional[
|
107
|
+
typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
108
|
+
]
|
109
|
+
_preload: typing.Optional[
|
110
|
+
typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]]
|
111
|
+
]
|
102
112
|
_rep: str
|
103
113
|
_is_another_app: bool
|
104
114
|
_hydrate_lazily: bool
|
105
|
-
_deps: typing.
|
106
|
-
_deduplication_key: typing.
|
115
|
+
_deps: typing.Optional[typing.Callable[..., list[Object]]]
|
116
|
+
_deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]]
|
107
117
|
_object_id: str
|
108
118
|
_client: modal.client.Client
|
109
119
|
_is_hydrated: bool
|
120
|
+
_is_rehydrated: bool
|
110
121
|
|
111
|
-
def __init__(self, *args, **kwargs):
|
112
|
-
...
|
113
|
-
|
122
|
+
def __init__(self, *args, **kwargs): ...
|
114
123
|
@classmethod
|
115
|
-
def __init_subclass__(cls, type_prefix: typing.
|
116
|
-
...
|
124
|
+
def __init_subclass__(cls, type_prefix: typing.Optional[str] = None): ...
|
117
125
|
|
118
126
|
class ___init_spec(typing_extensions.Protocol):
|
119
|
-
def __call__(
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
127
|
+
def __call__(
|
128
|
+
self,
|
129
|
+
rep: str,
|
130
|
+
load: typing.Optional[
|
131
|
+
typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
|
132
|
+
] = None,
|
133
|
+
is_another_app: bool = False,
|
134
|
+
preload: typing.Optional[
|
135
|
+
typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
|
136
|
+
] = None,
|
137
|
+
hydrate_lazily: bool = False,
|
138
|
+
deps: typing.Optional[typing.Callable[..., list[Object]]] = None,
|
139
|
+
deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Hashable]] = None,
|
140
|
+
): ...
|
141
|
+
def aio(
|
142
|
+
self,
|
143
|
+
rep: str,
|
144
|
+
load: typing.Optional[
|
145
|
+
typing.Callable[
|
146
|
+
[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
|
147
|
+
]
|
148
|
+
] = None,
|
149
|
+
is_another_app: bool = False,
|
150
|
+
preload: typing.Optional[
|
151
|
+
typing.Callable[
|
152
|
+
[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], collections.abc.Awaitable[None]
|
153
|
+
]
|
154
|
+
] = None,
|
155
|
+
hydrate_lazily: bool = False,
|
156
|
+
deps: typing.Optional[typing.Callable[..., list[Object]]] = None,
|
157
|
+
deduplication_key: typing.Optional[
|
158
|
+
typing.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
159
|
+
] = None,
|
160
|
+
): ...
|
124
161
|
|
125
162
|
_init: ___init_spec
|
126
163
|
|
127
|
-
def _unhydrate(self):
|
128
|
-
|
129
|
-
|
130
|
-
def
|
131
|
-
|
132
|
-
|
133
|
-
def
|
134
|
-
|
135
|
-
|
136
|
-
def
|
137
|
-
...
|
138
|
-
|
139
|
-
def _hydrate_metadata(self, metadata: typing.Union[google.protobuf.message.Message, None]):
|
140
|
-
...
|
141
|
-
|
142
|
-
def _get_metadata(self) -> typing.Union[google.protobuf.message.Message, None]:
|
143
|
-
...
|
144
|
-
|
145
|
-
def _init_from_other(self, other: _BLOCKING_O):
|
146
|
-
...
|
147
|
-
|
148
|
-
def clone(self: _BLOCKING_O) -> _BLOCKING_O:
|
149
|
-
...
|
150
|
-
|
164
|
+
def _unhydrate(self): ...
|
165
|
+
def _initialize_from_empty(self): ...
|
166
|
+
def _initialize_from_other(self, other): ...
|
167
|
+
def _hydrate(
|
168
|
+
self, object_id: str, client: modal.client.Client, metadata: typing.Optional[google.protobuf.message.Message]
|
169
|
+
): ...
|
170
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
171
|
+
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
172
|
+
def _validate_is_hydrated(self: _BLOCKING_O): ...
|
173
|
+
def clone(self: _BLOCKING_O) -> _BLOCKING_O: ...
|
151
174
|
@classmethod
|
152
|
-
def _from_loader(
|
153
|
-
|
154
|
-
|
175
|
+
def _from_loader(
|
176
|
+
cls,
|
177
|
+
load: typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None],
|
178
|
+
rep: str,
|
179
|
+
is_another_app: bool = False,
|
180
|
+
preload: typing.Optional[
|
181
|
+
typing.Callable[[_BLOCKING_O, modal._resolver.Resolver, typing.Optional[str]], None]
|
182
|
+
] = None,
|
183
|
+
hydrate_lazily: bool = False,
|
184
|
+
deps: typing.Optional[typing.Callable[..., collections.abc.Sequence[Object]]] = None,
|
185
|
+
deduplication_key: typing.Optional[typing.Callable[[], collections.abc.Hashable]] = None,
|
186
|
+
): ...
|
155
187
|
@classmethod
|
156
|
-
def
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
188
|
+
def _get_type_from_id(cls: type[_BLOCKING_O], object_id: str) -> type[_BLOCKING_O]: ...
|
189
|
+
@classmethod
|
190
|
+
def _is_id_type(cls: type[_BLOCKING_O], object_id) -> bool: ...
|
191
|
+
@classmethod
|
192
|
+
def _new_hydrated(
|
193
|
+
cls: type[_BLOCKING_O],
|
194
|
+
object_id: str,
|
195
|
+
client: modal.client.Client,
|
196
|
+
handle_metadata: typing.Optional[google.protobuf.message.Message],
|
197
|
+
is_another_app: bool = False,
|
198
|
+
) -> _BLOCKING_O: ...
|
199
|
+
def _hydrate_from_other(self, other: _BLOCKING_O): ...
|
200
|
+
def __repr__(self): ...
|
165
201
|
@property
|
166
|
-
def local_uuid(self):
|
167
|
-
...
|
168
|
-
|
202
|
+
def local_uuid(self): ...
|
169
203
|
@property
|
170
|
-
def object_id(self):
|
171
|
-
...
|
172
|
-
|
204
|
+
def object_id(self) -> str: ...
|
173
205
|
@property
|
174
|
-
def is_hydrated(self) -> bool:
|
175
|
-
...
|
176
|
-
|
206
|
+
def is_hydrated(self) -> bool: ...
|
177
207
|
@property
|
178
|
-
def deps(self) -> typing.Callable[...,
|
179
|
-
...
|
208
|
+
def deps(self) -> typing.Callable[..., list[Object]]: ...
|
180
209
|
|
181
210
|
class __resolve_spec(typing_extensions.Protocol):
|
182
|
-
def __call__(self):
|
183
|
-
|
184
|
-
|
185
|
-
async def aio(self, *args, **kwargs):
|
186
|
-
...
|
211
|
+
def __call__(self, client: typing.Optional[modal.client.Client] = None): ...
|
212
|
+
async def aio(self, client: typing.Optional[modal.client.Client] = None): ...
|
187
213
|
|
188
214
|
resolve: __resolve_spec
|
189
215
|
|
216
|
+
def live_method(method): ...
|
217
|
+
def live_method_gen(method): ...
|
190
218
|
|
191
|
-
|
192
|
-
...
|
193
|
-
|
194
|
-
|
195
|
-
def live_method_gen(method):
|
196
|
-
...
|
219
|
+
EPHEMERAL_OBJECT_HEARTBEAT_SLEEP: int
|
modal/output.py
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright Modal Labs 2024
|
2
|
+
"""Interface to Modal's OutputManager functionality.
|
3
|
+
|
4
|
+
These functions live here so that Modal library code can import them without
|
5
|
+
transitively importing Rich, as we do in global scope in _output.py. This allows
|
6
|
+
us to avoid importing Rich for client code that runs in the container environment.
|
7
|
+
|
8
|
+
"""
|
9
|
+
import contextlib
|
10
|
+
from collections.abc import Generator
|
11
|
+
from typing import TYPE_CHECKING, Optional
|
12
|
+
|
13
|
+
if TYPE_CHECKING:
|
14
|
+
from ._output import OutputManager
|
15
|
+
|
16
|
+
|
17
|
+
OUTPUT_ENABLED = False
|
18
|
+
|
19
|
+
|
20
|
+
@contextlib.contextmanager
|
21
|
+
def enable_output(show_progress: bool = True) -> Generator[None, None, None]:
|
22
|
+
"""Context manager that enable output when using the Python SDK.
|
23
|
+
|
24
|
+
This will print to stdout and stderr things such as
|
25
|
+
1. Logs from running functions
|
26
|
+
2. Status of creating objects
|
27
|
+
3. Map progress
|
28
|
+
|
29
|
+
Example:
|
30
|
+
```python
|
31
|
+
app = modal.App()
|
32
|
+
with modal.enable_output():
|
33
|
+
with app.run():
|
34
|
+
...
|
35
|
+
```
|
36
|
+
"""
|
37
|
+
from ._output import OutputManager
|
38
|
+
|
39
|
+
# Toggle the output flag from within this function so that we can
|
40
|
+
# call _get_output_manager from within the library and only import
|
41
|
+
# the _output module if output is explicitly enabled. That prevents
|
42
|
+
# us from trying to import rich inside a container environment where
|
43
|
+
# it might not be installed. This is sort of hacky and I would prefer
|
44
|
+
# a more thorough refactor where the OutputManager is fully useable
|
45
|
+
# without rich installed, but that's a larger project.
|
46
|
+
global OUTPUT_ENABLED
|
47
|
+
|
48
|
+
try:
|
49
|
+
with OutputManager.enable_output(show_progress):
|
50
|
+
OUTPUT_ENABLED = True
|
51
|
+
yield
|
52
|
+
finally:
|
53
|
+
OUTPUT_ENABLED = False
|
54
|
+
|
55
|
+
|
56
|
+
def _get_output_manager() -> Optional["OutputManager"]:
|
57
|
+
"""Interface to the OutputManager that returns None when output is not enabled."""
|
58
|
+
if OUTPUT_ENABLED:
|
59
|
+
from ._output import OutputManager
|
60
|
+
|
61
|
+
return OutputManager.get()
|
62
|
+
else:
|
63
|
+
return None
|