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/cls.pyi
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
+
import collections.abc
|
1
2
|
import google.protobuf.message
|
2
|
-
import
|
3
|
+
import inspect
|
4
|
+
import modal.app
|
3
5
|
import modal.client
|
4
6
|
import modal.functions
|
5
7
|
import modal.gpu
|
@@ -7,7 +9,6 @@ import modal.object
|
|
7
9
|
import modal.partial_function
|
8
10
|
import modal.retries
|
9
11
|
import modal.secret
|
10
|
-
import modal.stub
|
11
12
|
import modal.volume
|
12
13
|
import modal_proto.api_pb2
|
13
14
|
import os
|
@@ -16,167 +17,210 @@ import typing_extensions
|
|
16
17
|
|
17
18
|
T = typing.TypeVar("T")
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
_local_obj_constr: typing.Union[typing.Callable[[], typing.Any], None]
|
25
|
-
|
26
|
-
def __init__(self, user_cls: type, output_mgr: typing.Union[modal._output.OutputManager, None], base_functions: typing.Dict[str, modal.functions._Function], from_other_workspace: bool, options: typing.Union[modal_proto.api_pb2.FunctionOptions, None], args, kwargs):
|
27
|
-
...
|
28
|
-
|
29
|
-
def get_obj(self):
|
30
|
-
...
|
31
|
-
|
32
|
-
def get_local_obj(self):
|
33
|
-
...
|
34
|
-
|
35
|
-
def enter(self):
|
36
|
-
...
|
20
|
+
def _use_annotation_parameters(user_cls: type) -> bool: ...
|
21
|
+
def _get_class_constructor_signature(user_cls: type) -> inspect.Signature: ...
|
22
|
+
def _bind_instance_method(
|
23
|
+
service_function: modal.functions._Function, class_bound_method: modal.functions._Function
|
24
|
+
): ...
|
37
25
|
|
26
|
+
class _Obj:
|
27
|
+
_cls: _Cls
|
28
|
+
_functions: dict[str, modal.functions._Function]
|
29
|
+
_has_entered: bool
|
30
|
+
_user_cls_instance: typing.Optional[typing.Any]
|
31
|
+
_args: tuple[typing.Any, ...]
|
32
|
+
_kwargs: dict[str, typing.Any]
|
33
|
+
_instance_service_function: typing.Optional[modal.functions._Function]
|
34
|
+
|
35
|
+
def _uses_common_service_function(self): ...
|
36
|
+
def __init__(
|
37
|
+
self,
|
38
|
+
cls: _Cls,
|
39
|
+
user_cls: typing.Optional[type],
|
40
|
+
options: typing.Optional[modal_proto.api_pb2.FunctionOptions],
|
41
|
+
args,
|
42
|
+
kwargs,
|
43
|
+
): ...
|
44
|
+
def _cached_service_function(self) -> modal.functions._Function: ...
|
45
|
+
def _get_parameter_values(self) -> dict[str, typing.Any]: ...
|
46
|
+
def _new_user_cls_instance(self): ...
|
47
|
+
async def keep_warm(self, warm_pool_size: int) -> None: ...
|
48
|
+
def _cached_user_cls_instance(self): ...
|
49
|
+
def _enter(self): ...
|
38
50
|
@property
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def
|
44
|
-
...
|
45
|
-
|
46
|
-
async def aenter(self):
|
47
|
-
...
|
48
|
-
|
49
|
-
def __getattr__(self, k):
|
50
|
-
...
|
51
|
-
|
51
|
+
def _entered(self) -> bool: ...
|
52
|
+
@_entered.setter
|
53
|
+
def _entered(self, val: bool): ...
|
54
|
+
async def _aenter(self): ...
|
55
|
+
def __getattr__(self, k): ...
|
52
56
|
|
53
57
|
class Obj:
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
58
|
+
_cls: Cls
|
59
|
+
_functions: dict[str, modal.functions.Function]
|
60
|
+
_has_entered: bool
|
61
|
+
_user_cls_instance: typing.Optional[typing.Any]
|
62
|
+
_args: tuple[typing.Any, ...]
|
63
|
+
_kwargs: dict[str, typing.Any]
|
64
|
+
_instance_service_function: typing.Optional[modal.functions.Function]
|
65
|
+
|
66
|
+
def __init__(
|
67
|
+
self,
|
68
|
+
cls: Cls,
|
69
|
+
user_cls: typing.Optional[type],
|
70
|
+
options: typing.Optional[modal_proto.api_pb2.FunctionOptions],
|
71
|
+
args,
|
72
|
+
kwargs,
|
73
|
+
): ...
|
74
|
+
def _uses_common_service_function(self): ...
|
75
|
+
def _cached_service_function(self) -> modal.functions.Function: ...
|
76
|
+
def _get_parameter_values(self) -> dict[str, typing.Any]: ...
|
77
|
+
def _new_user_cls_instance(self): ...
|
78
|
+
|
79
|
+
class __keep_warm_spec(typing_extensions.Protocol):
|
80
|
+
def __call__(self, warm_pool_size: int) -> None: ...
|
81
|
+
async def aio(self, warm_pool_size: int) -> None: ...
|
82
|
+
|
83
|
+
keep_warm: __keep_warm_spec
|
84
|
+
|
85
|
+
def _cached_user_cls_instance(self): ...
|
86
|
+
def _enter(self): ...
|
72
87
|
@property
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
def
|
78
|
-
...
|
79
|
-
|
80
|
-
async def aenter(self):
|
81
|
-
...
|
82
|
-
|
83
|
-
def __getattr__(self, k):
|
84
|
-
...
|
85
|
-
|
88
|
+
def _entered(self) -> bool: ...
|
89
|
+
@_entered.setter
|
90
|
+
def _entered(self, val: bool): ...
|
91
|
+
async def _aenter(self): ...
|
92
|
+
def __getattr__(self, k): ...
|
86
93
|
|
87
94
|
class _Cls(modal.object._Object):
|
88
|
-
_user_cls: typing.
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
def
|
99
|
-
|
100
|
-
|
101
|
-
def _set_output_mgr(self, output_mgr: modal._output.OutputManager):
|
102
|
-
...
|
103
|
-
|
104
|
-
def _hydrate_metadata(self, metadata: google.protobuf.message.Message):
|
105
|
-
...
|
106
|
-
|
107
|
-
def _get_metadata(self) -> modal_proto.api_pb2.ClassHandleMetadata:
|
108
|
-
...
|
109
|
-
|
95
|
+
_user_cls: typing.Optional[type]
|
96
|
+
_class_service_function: typing.Optional[modal.functions._Function]
|
97
|
+
_method_functions: typing.Optional[dict[str, modal.functions._Function]]
|
98
|
+
_options: typing.Optional[modal_proto.api_pb2.FunctionOptions]
|
99
|
+
_callables: dict[str, typing.Callable[..., typing.Any]]
|
100
|
+
_app: typing.Optional[modal.app._App]
|
101
|
+
_name: typing.Optional[str]
|
102
|
+
|
103
|
+
def _initialize_from_empty(self): ...
|
104
|
+
def _initialize_from_other(self, other: _Cls): ...
|
105
|
+
def _get_partial_functions(self) -> dict[str, modal.partial_function._PartialFunction]: ...
|
106
|
+
def _hydrate_metadata(self, metadata: google.protobuf.message.Message): ...
|
110
107
|
@staticmethod
|
111
|
-
def
|
112
|
-
|
113
|
-
|
108
|
+
def validate_construction_mechanism(user_cls): ...
|
109
|
+
@staticmethod
|
110
|
+
def from_local(user_cls, app: modal.app._App, class_service_function: modal.functions._Function) -> _Cls: ...
|
111
|
+
def _uses_common_service_function(self): ...
|
114
112
|
@classmethod
|
115
|
-
def from_name(
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
113
|
+
def from_name(
|
114
|
+
cls: type[_Cls],
|
115
|
+
app_name: str,
|
116
|
+
name: str,
|
117
|
+
namespace=1,
|
118
|
+
environment_name: typing.Optional[str] = None,
|
119
|
+
workspace: typing.Optional[str] = None,
|
120
|
+
) -> _Cls: ...
|
121
|
+
def with_options(
|
122
|
+
self: _Cls,
|
123
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
124
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
125
|
+
gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
|
126
|
+
secrets: collections.abc.Collection[modal.secret._Secret] = (),
|
127
|
+
volumes: dict[typing.Union[str, os.PathLike], modal.volume._Volume] = {},
|
128
|
+
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
129
|
+
timeout: typing.Optional[int] = None,
|
130
|
+
concurrency_limit: typing.Optional[int] = None,
|
131
|
+
allow_concurrent_inputs: typing.Optional[int] = None,
|
132
|
+
container_idle_timeout: typing.Optional[int] = None,
|
133
|
+
) -> _Cls: ...
|
121
134
|
@staticmethod
|
122
|
-
async def lookup(
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
135
|
+
async def lookup(
|
136
|
+
app_name: str,
|
137
|
+
name: str,
|
138
|
+
namespace=1,
|
139
|
+
client: typing.Optional[modal.client._Client] = None,
|
140
|
+
environment_name: typing.Optional[str] = None,
|
141
|
+
workspace: typing.Optional[str] = None,
|
142
|
+
) -> _Cls: ...
|
143
|
+
def __call__(self, *args, **kwargs) -> _Obj: ...
|
144
|
+
def __getattr__(self, k): ...
|
131
145
|
|
132
146
|
class Cls(modal.object.Object):
|
133
|
-
_user_cls: typing.
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
def
|
144
|
-
|
145
|
-
|
146
|
-
def _initialize_from_other(self, other: Cls):
|
147
|
-
...
|
148
|
-
|
149
|
-
def _set_output_mgr(self, output_mgr: modal._output.OutputManager):
|
150
|
-
...
|
151
|
-
|
152
|
-
def _hydrate_metadata(self, metadata: google.protobuf.message.Message):
|
153
|
-
...
|
154
|
-
|
155
|
-
def _get_metadata(self) -> modal_proto.api_pb2.ClassHandleMetadata:
|
156
|
-
...
|
157
|
-
|
147
|
+
_user_cls: typing.Optional[type]
|
148
|
+
_class_service_function: typing.Optional[modal.functions.Function]
|
149
|
+
_method_functions: typing.Optional[dict[str, modal.functions.Function]]
|
150
|
+
_options: typing.Optional[modal_proto.api_pb2.FunctionOptions]
|
151
|
+
_callables: dict[str, typing.Callable[..., typing.Any]]
|
152
|
+
_app: typing.Optional[modal.app.App]
|
153
|
+
_name: typing.Optional[str]
|
154
|
+
|
155
|
+
def __init__(self, *args, **kwargs): ...
|
156
|
+
def _initialize_from_empty(self): ...
|
157
|
+
def _initialize_from_other(self, other: Cls): ...
|
158
|
+
def _get_partial_functions(self) -> dict[str, modal.partial_function.PartialFunction]: ...
|
159
|
+
def _hydrate_metadata(self, metadata: google.protobuf.message.Message): ...
|
158
160
|
@staticmethod
|
159
|
-
def
|
160
|
-
|
161
|
-
|
161
|
+
def validate_construction_mechanism(user_cls): ...
|
162
|
+
@staticmethod
|
163
|
+
def from_local(user_cls, app: modal.app.App, class_service_function: modal.functions.Function) -> Cls: ...
|
164
|
+
def _uses_common_service_function(self): ...
|
162
165
|
@classmethod
|
163
|
-
def from_name(
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
166
|
+
def from_name(
|
167
|
+
cls: type[Cls],
|
168
|
+
app_name: str,
|
169
|
+
name: str,
|
170
|
+
namespace=1,
|
171
|
+
environment_name: typing.Optional[str] = None,
|
172
|
+
workspace: typing.Optional[str] = None,
|
173
|
+
) -> Cls: ...
|
174
|
+
def with_options(
|
175
|
+
self: Cls,
|
176
|
+
cpu: typing.Union[float, tuple[float, float], None] = None,
|
177
|
+
memory: typing.Union[int, tuple[int, int], None] = None,
|
178
|
+
gpu: typing.Union[None, bool, str, modal.gpu._GPUConfig] = None,
|
179
|
+
secrets: collections.abc.Collection[modal.secret.Secret] = (),
|
180
|
+
volumes: dict[typing.Union[str, os.PathLike], modal.volume.Volume] = {},
|
181
|
+
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
182
|
+
timeout: typing.Optional[int] = None,
|
183
|
+
concurrency_limit: typing.Optional[int] = None,
|
184
|
+
allow_concurrent_inputs: typing.Optional[int] = None,
|
185
|
+
container_idle_timeout: typing.Optional[int] = None,
|
186
|
+
) -> Cls: ...
|
168
187
|
|
169
188
|
class __lookup_spec(typing_extensions.Protocol):
|
170
|
-
def __call__(
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
189
|
+
def __call__(
|
190
|
+
self,
|
191
|
+
app_name: str,
|
192
|
+
name: str,
|
193
|
+
namespace=1,
|
194
|
+
client: typing.Optional[modal.client.Client] = None,
|
195
|
+
environment_name: typing.Optional[str] = None,
|
196
|
+
workspace: typing.Optional[str] = None,
|
197
|
+
) -> Cls: ...
|
198
|
+
async def aio(
|
199
|
+
self,
|
200
|
+
app_name: str,
|
201
|
+
name: str,
|
202
|
+
namespace=1,
|
203
|
+
client: typing.Optional[modal.client.Client] = None,
|
204
|
+
environment_name: typing.Optional[str] = None,
|
205
|
+
workspace: typing.Optional[str] = None,
|
206
|
+
) -> Cls: ...
|
175
207
|
|
176
208
|
lookup: __lookup_spec
|
177
209
|
|
178
|
-
def __call__(self, *args, **kwargs) -> Obj:
|
179
|
-
|
210
|
+
def __call__(self, *args, **kwargs) -> Obj: ...
|
211
|
+
def __getattr__(self, k): ...
|
212
|
+
|
213
|
+
class _NO_DEFAULT:
|
214
|
+
def __repr__(self): ...
|
215
|
+
|
216
|
+
_no_default: _NO_DEFAULT
|
217
|
+
|
218
|
+
class _Parameter:
|
219
|
+
default: typing.Any
|
220
|
+
init: bool
|
221
|
+
|
222
|
+
def __init__(self, default: typing.Any, init: bool): ...
|
223
|
+
def __get__(self, obj, obj_type=None) -> typing.Any: ...
|
180
224
|
|
181
|
-
|
182
|
-
|
225
|
+
def is_parameter(p: typing.Any) -> bool: ...
|
226
|
+
def parameter(*, default: typing.Any = modal.cls._NO_DEFAULT(), init: bool = True) -> typing.Any: ...
|
modal/config.py
CHANGED
@@ -29,7 +29,7 @@ Setting tokens using the CLI
|
|
29
29
|
|
30
30
|
You can set a token by running the command::
|
31
31
|
|
32
|
-
```
|
32
|
+
```
|
33
33
|
modal token set \
|
34
34
|
--token-id <token id> \
|
35
35
|
--token-secret <token secret>
|
@@ -55,6 +55,11 @@ Other possible configuration options are:
|
|
55
55
|
Defaults to True.
|
56
56
|
By default, Modal automatically mounts modules imported in the current scope, that
|
57
57
|
are deemed to be "local". This can be turned off by setting this to False.
|
58
|
+
* `force_build` (in the .toml file) / `MODAL_FORCE_BUILD` (as an env var).
|
59
|
+
Defaults to False.
|
60
|
+
When set, ignores the Image cache and builds all Image layers. Note that this
|
61
|
+
will break the cache for all images based on the rebuilt layers, so other images
|
62
|
+
may rebuild on subsequent runs / deploys even if the config is reverted.
|
58
63
|
* `traceback` (in the .toml file) / `MODAL_TRACEBACK` (as an env var).
|
59
64
|
Defaults to False. Enables printing full tracebacks on unexpected CLI
|
60
65
|
errors, which can be useful for debugging client issues.
|
@@ -75,14 +80,15 @@ import os
|
|
75
80
|
import typing
|
76
81
|
import warnings
|
77
82
|
from textwrap import dedent
|
78
|
-
from typing import Any,
|
83
|
+
from typing import Any, Optional
|
79
84
|
|
80
85
|
from google.protobuf.empty_pb2 import Empty
|
81
86
|
|
82
87
|
from modal_proto import api_pb2
|
83
88
|
|
89
|
+
from ._utils.deprecation import deprecation_error
|
84
90
|
from ._utils.logger import configure_logger
|
85
|
-
from .exception import InvalidError
|
91
|
+
from .exception import InvalidError
|
86
92
|
|
87
93
|
# Locate config file and read it
|
88
94
|
|
@@ -98,14 +104,25 @@ def _is_remote() -> bool:
|
|
98
104
|
|
99
105
|
|
100
106
|
def _read_user_config():
|
107
|
+
config_data = {}
|
101
108
|
if not _is_remote() and os.path.exists(user_config_path):
|
102
109
|
# Defer toml import so we don't need it in the container runtime environment
|
103
110
|
import toml
|
104
111
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
112
|
+
try:
|
113
|
+
with open(user_config_path) as f:
|
114
|
+
config_data = toml.load(f)
|
115
|
+
except Exception as exc:
|
116
|
+
config_problem = str(exc)
|
117
|
+
else:
|
118
|
+
if not all(isinstance(e, dict) for e in config_data.values()):
|
119
|
+
config_problem = "TOML file must contain table sections for each profile."
|
120
|
+
else:
|
121
|
+
config_problem = ""
|
122
|
+
if config_problem:
|
123
|
+
message = f"\nError when reading the modal configuration from `{user_config_path}`.\n\n{config_problem}"
|
124
|
+
raise InvalidError(message)
|
125
|
+
return config_data
|
109
126
|
|
110
127
|
|
111
128
|
_user_config = _read_user_config()
|
@@ -161,11 +178,9 @@ def _check_config() -> None:
|
|
161
178
|
Support for using an implicit 'default' profile is deprecated.
|
162
179
|
Please use `modal profile activate` to activate one of your profiles.
|
163
180
|
(Use `modal profile list` to see the options.)
|
164
|
-
|
165
|
-
This will become an error in a future update.
|
166
181
|
"""
|
167
182
|
)
|
168
|
-
|
183
|
+
deprecation_error((2024, 2, 6), message)
|
169
184
|
|
170
185
|
|
171
186
|
_profile = os.environ.get("MODAL_PROFILE") or _config_active_profile()
|
@@ -173,6 +188,10 @@ _profile = os.environ.get("MODAL_PROFILE") or _config_active_profile()
|
|
173
188
|
# Define settings
|
174
189
|
|
175
190
|
|
191
|
+
def _to_boolean(x: object) -> bool:
|
192
|
+
return str(x).lower() not in {"", "0", "false"}
|
193
|
+
|
194
|
+
|
176
195
|
class _Setting(typing.NamedTuple):
|
177
196
|
default: typing.Any = None
|
178
197
|
transform: typing.Callable[[str], typing.Any] = lambda x: x # noqa: E731
|
@@ -185,22 +204,25 @@ _SETTINGS = {
|
|
185
204
|
"token_id": _Setting(),
|
186
205
|
"token_secret": _Setting(),
|
187
206
|
"task_id": _Setting(),
|
188
|
-
"task_secret": _Setting(),
|
189
207
|
"serve_timeout": _Setting(transform=float),
|
190
208
|
"sync_entrypoint": _Setting(),
|
191
209
|
"logs_timeout": _Setting(10, float),
|
192
210
|
"image_id": _Setting(),
|
193
|
-
"automount": _Setting(True, transform=
|
194
|
-
"profiling_enabled": _Setting(False, transform=lambda x: x not in ("", "0")),
|
211
|
+
"automount": _Setting(True, transform=_to_boolean),
|
195
212
|
"heartbeat_interval": _Setting(15, float),
|
196
213
|
"function_runtime": _Setting(),
|
197
|
-
"function_runtime_debug": _Setting(False, transform=
|
214
|
+
"function_runtime_debug": _Setting(False, transform=_to_boolean), # For internal debugging use.
|
215
|
+
"runtime_perf_record": _Setting(False, transform=_to_boolean), # For internal debugging use.
|
198
216
|
"environment": _Setting(),
|
199
217
|
"default_cloud": _Setting(None, transform=lambda x: x if x else None),
|
200
218
|
"worker_id": _Setting(), # For internal debugging use.
|
201
219
|
"restore_state_path": _Setting("/__modal/restore-state.json"),
|
202
|
-
"force_build": _Setting(False, transform=
|
203
|
-
"traceback": _Setting(False, transform=
|
220
|
+
"force_build": _Setting(False, transform=_to_boolean),
|
221
|
+
"traceback": _Setting(False, transform=_to_boolean),
|
222
|
+
"image_builder_version": _Setting(),
|
223
|
+
"strict_parameters": _Setting(False, transform=_to_boolean), # For internal/experimental use
|
224
|
+
"snapshot_debug": _Setting(False, transform=_to_boolean),
|
225
|
+
"client_retries": _Setting(False, transform=_to_boolean), # For internal testing.
|
204
226
|
}
|
205
227
|
|
206
228
|
|
@@ -238,7 +260,7 @@ class Config:
|
|
238
260
|
os.environ["MODAL_" + key.upper()] = value
|
239
261
|
except KeyError:
|
240
262
|
# Override env vars not available in config, e.g. NVIDIA_VISIBLE_DEVICES.
|
241
|
-
# This is used for restoring env vars from a
|
263
|
+
# This is used for restoring env vars from a memory snapshot.
|
242
264
|
os.environ[key.upper()] = value
|
243
265
|
|
244
266
|
def __getitem__(self, key):
|
@@ -248,7 +270,7 @@ class Config:
|
|
248
270
|
return repr(self.to_dict())
|
249
271
|
|
250
272
|
def to_dict(self):
|
251
|
-
return {key: self.get(key) for key in _SETTINGS
|
273
|
+
return {key: self.get(key) for key in sorted(_SETTINGS)}
|
252
274
|
|
253
275
|
|
254
276
|
config = Config()
|
@@ -262,7 +284,7 @@ configure_logger(logger, config["loglevel"], config["log_format"])
|
|
262
284
|
|
263
285
|
|
264
286
|
def _store_user_config(
|
265
|
-
new_settings:
|
287
|
+
new_settings: dict[str, Any], profile: Optional[str] = None, active_profile: Optional[str] = None
|
266
288
|
):
|
267
289
|
"""Internal method, used by the CLI to set tokens."""
|
268
290
|
if profile is None:
|