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.
- modal/__init__.py +13 -9
- modal/__main__.py +41 -3
- modal/_clustered_functions.py +80 -0
- modal/_clustered_functions.pyi +22 -0
- modal/_container_entrypoint.py +402 -398
- modal/_ipython.py +3 -13
- modal/_location.py +17 -10
- modal/_output.py +243 -99
- modal/_pty.py +2 -2
- modal/_resolver.py +55 -60
- modal/_resources.py +26 -7
- modal/_runtime/__init__.py +1 -0
- modal/_runtime/asgi.py +519 -0
- modal/_runtime/container_io_manager.py +1025 -0
- modal/{execution_context.py → _runtime/execution_context.py} +11 -2
- modal/_runtime/telemetry.py +169 -0
- modal/_runtime/user_code_imports.py +356 -0
- modal/_serialization.py +123 -6
- modal/_traceback.py +47 -187
- modal/_tunnel.py +50 -14
- modal/_tunnel.pyi +19 -36
- modal/_utils/app_utils.py +3 -17
- modal/_utils/async_utils.py +386 -104
- 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 +299 -98
- modal/_utils/grpc_testing.py +47 -34
- modal/_utils/grpc_utils.py +54 -21
- modal/_utils/hash_utils.py +51 -10
- 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 +3 -3
- modal/_utils/shell_utils.py +15 -49
- modal/_vendor/a2wsgi_wsgi.py +62 -72
- modal/_vendor/cloudpickle.py +1 -1
- modal/_watcher.py +12 -10
- modal/app.py +561 -323
- modal/app.pyi +474 -262
- modal/call_graph.py +7 -6
- modal/cli/_download.py +22 -6
- modal/cli/_traceback.py +200 -0
- modal/cli/app.py +203 -42
- modal/cli/config.py +12 -5
- modal/cli/container.py +61 -13
- modal/cli/dict.py +128 -0
- modal/cli/entry_point.py +26 -13
- modal/cli/environment.py +40 -9
- modal/cli/import_refs.py +21 -48
- modal/cli/launch.py +28 -14
- modal/cli/network_file_system.py +57 -21
- modal/cli/profile.py +1 -1
- modal/cli/programs/run_jupyter.py +34 -9
- modal/cli/programs/vscode.py +58 -8
- modal/cli/queues.py +131 -0
- modal/cli/run.py +199 -96
- modal/cli/secret.py +5 -4
- modal/cli/token.py +7 -2
- modal/cli/utils.py +74 -8
- modal/cli/volume.py +97 -56
- modal/client.py +248 -144
- modal/client.pyi +156 -124
- modal/cloud_bucket_mount.py +43 -30
- modal/cloud_bucket_mount.pyi +32 -25
- modal/cls.py +528 -141
- modal/cls.pyi +189 -145
- modal/config.py +32 -15
- modal/container_process.py +177 -0
- modal/container_process.pyi +82 -0
- modal/dict.py +50 -54
- modal/dict.pyi +120 -164
- modal/environments.py +106 -5
- modal/environments.pyi +77 -25
- modal/exception.py +30 -43
- modal/experimental.py +62 -2
- modal/file_io.py +537 -0
- modal/file_io.pyi +235 -0
- modal/file_pattern_matcher.py +196 -0
- modal/functions.py +846 -428
- modal/functions.pyi +446 -387
- modal/gpu.py +57 -44
- modal/image.py +943 -417
- modal/image.pyi +584 -245
- modal/io_streams.py +434 -0
- modal/io_streams.pyi +122 -0
- modal/mount.py +223 -90
- modal/mount.pyi +241 -243
- modal/network_file_system.py +85 -86
- modal/network_file_system.pyi +151 -110
- modal/object.py +66 -36
- modal/object.pyi +166 -143
- modal/output.py +63 -0
- modal/parallel_map.py +73 -47
- modal/parallel_map.pyi +51 -63
- modal/partial_function.py +272 -107
- modal/partial_function.pyi +219 -120
- modal/proxy.py +15 -12
- modal/proxy.pyi +3 -8
- modal/queue.py +96 -72
- modal/queue.pyi +210 -135
- modal/requirements/2024.04.txt +2 -1
- modal/requirements/2024.10.txt +16 -0
- modal/requirements/README.md +21 -0
- modal/requirements/base-images.json +22 -0
- modal/retries.py +45 -4
- modal/runner.py +325 -203
- modal/runner.pyi +124 -110
- modal/running_app.py +27 -4
- modal/sandbox.py +509 -231
- modal/sandbox.pyi +396 -169
- modal/schedule.py +2 -2
- modal/scheduler_placement.py +20 -3
- modal/secret.py +41 -25
- modal/secret.pyi +62 -42
- modal/serving.py +39 -49
- modal/serving.pyi +37 -43
- modal/stream_type.py +15 -0
- modal/token_flow.py +5 -3
- modal/token_flow.pyi +37 -32
- modal/volume.py +123 -137
- modal/volume.pyi +228 -221
- {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/METADATA +5 -5
- modal-0.72.13.dist-info/RECORD +174 -0
- {modal-0.62.115.dist-info → modal-0.72.13.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 +1 -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 +1231 -531
- modal_proto/api_grpc.py +750 -430
- modal_proto/api_pb2.py +2102 -1176
- modal_proto/api_pb2.pyi +8859 -0
- modal_proto/api_pb2_grpc.py +1329 -675
- 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_exec.py +0 -128
- modal/_container_io_manager.py +0 -646
- modal/_container_io_manager.pyi +0 -412
- modal/_sandbox_shell.py +0 -49
- modal/app_utils.py +0 -20
- modal/app_utils.pyi +0 -17
- modal/execution_context.pyi +0 -37
- modal/shared_volume.py +0 -23
- modal/shared_volume.pyi +0 -24
- modal-0.62.115.dist-info/RECORD +0 -207
- 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 -279
- test/blob_test.py +0 -67
- test/cli_imports_test.py +0 -149
- test/cli_test.py +0 -674
- test/client_test.py +0 -203
- test/cloud_bucket_mount_test.py +0 -22
- test/cls_test.py +0 -636
- test/config_test.py +0 -149
- test/conftest.py +0 -1485
- test/container_app_test.py +0 -50
- test/container_test.py +0 -1405
- test/cpu_test.py +0 -23
- test/decorator_test.py +0 -85
- test/deprecation_test.py +0 -34
- test/dict_test.py +0 -51
- test/e2e_test.py +0 -68
- test/error_test.py +0 -7
- test/function_serialization_test.py +0 -32
- test/function_test.py +0 -791
- test/function_utils_test.py +0 -101
- test/gpu_test.py +0 -159
- test/grpc_utils_test.py +0 -82
- test/helpers.py +0 -47
- test/image_test.py +0 -814
- 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 -327
- test/network_file_system_test.py +0 -188
- test/notebook_test.py +0 -66
- test/object_test.py +0 -41
- test/package_utils_test.py +0 -25
- test/queue_test.py +0 -115
- test/resolver_test.py +0 -59
- 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 -57
- test/secret_test.py +0 -89
- test/serialization_test.py +0 -50
- test/stub_composition_test.py +0 -10
- test/stub_test.py +0 -361
- 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 -397
- test/watcher_test.py +0 -58
- test/webhook_test.py +0 -145
- {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/LICENSE +0 -0
- {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/WHEEL +0 -0
- {modal-0.62.115.dist-info → modal-0.72.13.dist-info}/entry_points.txt +0 -0
test/config_test.py
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
# Copyright Modal Labs 2022
|
2
|
-
import os
|
3
|
-
import pathlib
|
4
|
-
import pytest
|
5
|
-
import subprocess
|
6
|
-
import sys
|
7
|
-
|
8
|
-
import toml
|
9
|
-
|
10
|
-
import modal
|
11
|
-
from modal.config import Config, _lookup_workspace, config
|
12
|
-
|
13
|
-
|
14
|
-
def _cli(args, env={}):
|
15
|
-
lib_dir = pathlib.Path(modal.__file__).parent.parent
|
16
|
-
args = [sys.executable, "-m", "modal.cli.entry_point"] + args
|
17
|
-
env = {
|
18
|
-
**os.environ,
|
19
|
-
**env,
|
20
|
-
# For windows
|
21
|
-
"PYTHONUTF8": "1",
|
22
|
-
}
|
23
|
-
ret = subprocess.run(args, cwd=lib_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
24
|
-
stdout = ret.stdout.decode()
|
25
|
-
stderr = ret.stderr.decode()
|
26
|
-
if ret.returncode != 0:
|
27
|
-
raise Exception(f"Failed with {ret.returncode} stdout: {stdout} stderr: {stderr}")
|
28
|
-
return stdout
|
29
|
-
|
30
|
-
|
31
|
-
def _get_config(env={}):
|
32
|
-
stdout = _cli(["config", "show"], env=env)
|
33
|
-
return eval(stdout)
|
34
|
-
|
35
|
-
|
36
|
-
def test_config():
|
37
|
-
config = _get_config()
|
38
|
-
assert config["server_url"]
|
39
|
-
|
40
|
-
|
41
|
-
def test_config_env_override():
|
42
|
-
config = _get_config(env={"MODAL_SERVER_URL": "xyz.corp"})
|
43
|
-
assert config["server_url"] == "xyz.corp"
|
44
|
-
|
45
|
-
|
46
|
-
def test_config_store_user(servicer, modal_config):
|
47
|
-
with modal_config(show_on_error=True) as config_file_path:
|
48
|
-
env = {"MODAL_SERVER_URL": servicer.remote_addr}
|
49
|
-
|
50
|
-
# No token by default
|
51
|
-
config = _get_config(env=env)
|
52
|
-
assert config["token_id"] is None
|
53
|
-
|
54
|
-
# Set creds to abc / xyz
|
55
|
-
_cli(["token", "set", "--token-id", "abc", "--token-secret", "xyz"], env=env)
|
56
|
-
|
57
|
-
# Set creds to foo / bar1 for the prof_1 profile
|
58
|
-
_cli(
|
59
|
-
["token", "set", "--token-id", "foo", "--token-secret", "bar1", "--profile", "prof_1", "--no-activate"],
|
60
|
-
env=env,
|
61
|
-
)
|
62
|
-
|
63
|
-
# Set creds to foo / bar2 for the prof_2 profile (given as an env var)
|
64
|
-
_cli(
|
65
|
-
["token", "set", "--token-id", "foo", "--token-secret", "bar2", "--no-activate"],
|
66
|
-
env={"MODAL_PROFILE": "prof_2", **env},
|
67
|
-
)
|
68
|
-
|
69
|
-
# Now these should be stored in the user's home directory
|
70
|
-
config = _get_config(env=env)
|
71
|
-
assert config["token_id"] == "abc"
|
72
|
-
assert config["token_secret"] == "xyz"
|
73
|
-
|
74
|
-
# Make sure it can be overridden too
|
75
|
-
config = _get_config(env={"MODAL_TOKEN_ID": "foo", **env})
|
76
|
-
assert config["token_id"] == "foo"
|
77
|
-
assert config["token_secret"] == "xyz"
|
78
|
-
|
79
|
-
# Check that the profile is named after the workspace username by default
|
80
|
-
config = _get_config(env={"MODAL_PROFILE": "test-username", **env})
|
81
|
-
assert config["token_id"] == "abc"
|
82
|
-
assert config["token_secret"] == "xyz"
|
83
|
-
|
84
|
-
# Check that we can get the prof_1 env creds too
|
85
|
-
config = _get_config(env={"MODAL_PROFILE": "prof_1", **env})
|
86
|
-
assert config["token_id"] == "foo"
|
87
|
-
assert config["token_secret"] == "bar1"
|
88
|
-
|
89
|
-
# Check that we can get the prof_2 env creds too
|
90
|
-
config = _get_config(env={"MODAL_PROFILE": "prof_2", **env})
|
91
|
-
assert config["token_id"] == "foo"
|
92
|
-
assert config["token_secret"] == "bar2"
|
93
|
-
|
94
|
-
# Check that an empty string falls back to the active profile
|
95
|
-
config = _get_config(env={"MODAL_PROFILE": "", **env})
|
96
|
-
assert config["token_secret"] == "xyz"
|
97
|
-
|
98
|
-
# Test that only the first profile was explicitly activated
|
99
|
-
for profile, profile_config in toml.load(config_file_path).items():
|
100
|
-
if profile == "test-username":
|
101
|
-
assert profile_config["active"] is True
|
102
|
-
else:
|
103
|
-
assert "active" not in profile_config
|
104
|
-
|
105
|
-
# Check that we can overwrite the default profile
|
106
|
-
_cli(["token", "set", "--token-id", "ABC", "--token-secret", "XYZ"], env=env)
|
107
|
-
assert toml.load(config_file_path)["test-username"]["token_id"] == "ABC"
|
108
|
-
|
109
|
-
# Check that we activate a profile by default while setting a token
|
110
|
-
_cli(
|
111
|
-
["token", "set", "--token-id", "foo", "--token-secret", "bar3", "--profile", "prof_3"],
|
112
|
-
env=env,
|
113
|
-
)
|
114
|
-
for profile, profile_config in toml.load(config_file_path).items():
|
115
|
-
if profile == "prof_3":
|
116
|
-
assert profile_config["active"] is True
|
117
|
-
else:
|
118
|
-
assert "active" not in profile_config
|
119
|
-
|
120
|
-
|
121
|
-
def test_config_env_override_arbitrary_env():
|
122
|
-
"""config.override_locally() replaces existing env var if not part of config."""
|
123
|
-
key = "NVIDIA_VISIBLE_DEVICES"
|
124
|
-
value = "0,1"
|
125
|
-
|
126
|
-
# Place old value in memory.
|
127
|
-
os.environ[key] = "none"
|
128
|
-
|
129
|
-
# Expect value to be overwritten.
|
130
|
-
config.override_locally(key, value)
|
131
|
-
assert os.getenv(key) == value
|
132
|
-
|
133
|
-
|
134
|
-
@pytest.mark.asyncio
|
135
|
-
async def test_workspace_lookup(servicer, server_url_env):
|
136
|
-
resp = await _lookup_workspace(servicer.remote_addr, "ak-abc", "as-xyz")
|
137
|
-
assert resp.username == "test-username"
|
138
|
-
|
139
|
-
|
140
|
-
@pytest.mark.parametrize("automount", ["false", "'false'", "'False'", "'0'", 0, "''"])
|
141
|
-
def test_config_boolean(modal_config, automount):
|
142
|
-
modal_toml = f"""
|
143
|
-
[prof-1]
|
144
|
-
token_id = 'ak-abc'
|
145
|
-
token_secret = 'as_xyz'
|
146
|
-
automount = {automount}
|
147
|
-
"""
|
148
|
-
with modal_config(modal_toml):
|
149
|
-
assert not Config().get("automount", "prof-1")
|