modal 0.62.115__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 +13 -9
- modal/__main__.py +41 -3
- modal/_clustered_functions.py +80 -0
- modal/_clustered_functions.pyi +22 -0
- modal/_container_entrypoint.py +407 -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 +1036 -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 +197 -0
- modal/functions.py +846 -428
- modal/functions.pyi +446 -387
- modal/gpu.py +57 -44
- modal/image.py +946 -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.11.dist-info}/METADATA +5 -5
- modal-0.72.11.dist-info/RECORD +174 -0
- {modal-0.62.115.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 +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.11.dist-info}/LICENSE +0 -0
- {modal-0.62.115.dist-info → modal-0.72.11.dist-info}/WHEEL +0 -0
- {modal-0.62.115.dist-info → modal-0.72.11.dist-info}/entry_points.txt +0 -0
modal/_container_exec.py
DELETED
@@ -1,128 +0,0 @@
|
|
1
|
-
# Copyright Modal Labs 2024
|
2
|
-
import asyncio
|
3
|
-
import platform
|
4
|
-
from typing import List, Optional
|
5
|
-
|
6
|
-
import rich
|
7
|
-
import rich.status
|
8
|
-
from grpclib import Status
|
9
|
-
from grpclib.exceptions import GRPCError, StreamTerminatedError
|
10
|
-
from rich.console import Console
|
11
|
-
|
12
|
-
from modal_proto import api_pb2
|
13
|
-
|
14
|
-
from ._pty import get_pty_info
|
15
|
-
from ._utils.grpc_utils import RETRYABLE_GRPC_STATUS_CODES, retry_transient_errors, unary_stream
|
16
|
-
from ._utils.shell_utils import connect_to_terminal, write_to_fd
|
17
|
-
from .client import _Client
|
18
|
-
from .config import config
|
19
|
-
from .exception import NotFoundError
|
20
|
-
|
21
|
-
|
22
|
-
async def container_exec(task_id: str, command: List[str], *, pty: bool, client: _Client):
|
23
|
-
"""Execute a command inside an active container"""
|
24
|
-
if platform.system() == "Windows":
|
25
|
-
print("container exec is not currently supported on Windows.")
|
26
|
-
return
|
27
|
-
|
28
|
-
client = await _Client.from_env()
|
29
|
-
|
30
|
-
console = Console()
|
31
|
-
connecting_status = console.status("Connecting...")
|
32
|
-
connecting_status.start()
|
33
|
-
|
34
|
-
try:
|
35
|
-
res: api_pb2.ContainerExecResponse = await client.stub.ContainerExec(
|
36
|
-
api_pb2.ContainerExecRequest(
|
37
|
-
task_id=task_id,
|
38
|
-
command=command,
|
39
|
-
pty_info=get_pty_info(shell=True) if pty else None,
|
40
|
-
runtime_debug=config.get("function_runtime_debug"),
|
41
|
-
)
|
42
|
-
)
|
43
|
-
except GRPCError as err:
|
44
|
-
connecting_status.stop()
|
45
|
-
if err.status == Status.NOT_FOUND:
|
46
|
-
raise NotFoundError(f"Container ID {task_id} not found")
|
47
|
-
raise
|
48
|
-
|
49
|
-
await connect_to_exec(res.exec_id, pty, connecting_status)
|
50
|
-
|
51
|
-
|
52
|
-
async def connect_to_exec(exec_id: str, pty: bool = False, connecting_status: Optional[rich.status.Status] = None):
|
53
|
-
"""
|
54
|
-
Connects the current terminal to the given exec id.
|
55
|
-
|
56
|
-
If connecting_status is given, this function will stop the status spinner upon connection or error.
|
57
|
-
"""
|
58
|
-
|
59
|
-
client = await _Client.from_env()
|
60
|
-
|
61
|
-
async def _stream_to_stdout(on_connect: asyncio.Event) -> int:
|
62
|
-
return await _handle_exec_output(client, exec_id, on_connect)
|
63
|
-
|
64
|
-
async def _handle_input(data: bytes, message_index: int):
|
65
|
-
await retry_transient_errors(
|
66
|
-
client.stub.ContainerExecPutInput,
|
67
|
-
api_pb2.ContainerExecPutInputRequest(
|
68
|
-
exec_id=exec_id, input=api_pb2.RuntimeInputMessage(message=data, message_index=message_index)
|
69
|
-
),
|
70
|
-
total_timeout=10,
|
71
|
-
)
|
72
|
-
|
73
|
-
await connect_to_terminal(_handle_input, _stream_to_stdout, pty, connecting_status)
|
74
|
-
|
75
|
-
|
76
|
-
async def _handle_exec_output(client: _Client, exec_id: str, on_connect: Optional[asyncio.Event] = None) -> int:
|
77
|
-
"""
|
78
|
-
Streams exec output to current terminal's stdout.
|
79
|
-
|
80
|
-
The on_connect event will be set when the client connects to the running process,
|
81
|
-
and the event loop will be released.
|
82
|
-
|
83
|
-
Returns the status code of the process.
|
84
|
-
"""
|
85
|
-
|
86
|
-
last_batch_index = 0
|
87
|
-
exit_status = None
|
88
|
-
|
89
|
-
# we are connected if we received at least one message from the server
|
90
|
-
# (the server will send an empty message when the process spawns)
|
91
|
-
connected = False
|
92
|
-
|
93
|
-
async def _get_output():
|
94
|
-
nonlocal last_batch_index, exit_status, connected
|
95
|
-
req = api_pb2.ContainerExecGetOutputRequest(
|
96
|
-
exec_id=exec_id,
|
97
|
-
timeout=55,
|
98
|
-
last_batch_index=last_batch_index,
|
99
|
-
)
|
100
|
-
async for batch in unary_stream(client.stub.ContainerExecGetOutput, req):
|
101
|
-
for message in batch.items:
|
102
|
-
assert message.file_descriptor in [1, 2]
|
103
|
-
|
104
|
-
await write_to_fd(message.file_descriptor, str.encode(message.message))
|
105
|
-
|
106
|
-
if not connected:
|
107
|
-
connected = True
|
108
|
-
on_connect.set()
|
109
|
-
# give up the event loop
|
110
|
-
await asyncio.sleep(0)
|
111
|
-
|
112
|
-
if batch.HasField("exit_code"):
|
113
|
-
exit_status = batch.exit_code
|
114
|
-
break
|
115
|
-
last_batch_index = batch.batch_index
|
116
|
-
|
117
|
-
while exit_status is None:
|
118
|
-
try:
|
119
|
-
await _get_output()
|
120
|
-
except (GRPCError, StreamTerminatedError) as exc:
|
121
|
-
if isinstance(exc, GRPCError):
|
122
|
-
if exc.status in RETRYABLE_GRPC_STATUS_CODES:
|
123
|
-
continue
|
124
|
-
elif isinstance(exc, StreamTerminatedError):
|
125
|
-
continue
|
126
|
-
raise
|
127
|
-
|
128
|
-
return exit_status
|