modal 0.68.50__py3-none-any.whl → 0.71.5__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/_container_entrypoint.py +24 -16
- modal/_runtime/container_io_manager.py +11 -23
- modal/_utils/docker_utils.py +64 -0
- modal/_utils/function_utils.py +10 -1
- modal/app.py +25 -23
- modal/app.pyi +6 -2
- modal/cli/launch.py +2 -0
- modal/cli/programs/vscode.py +27 -2
- modal/cli/run.py +1 -1
- modal/client.pyi +2 -2
- modal/exception.py +6 -0
- modal/experimental.py +3 -0
- modal/file_io.py +102 -10
- modal/file_io.pyi +59 -0
- modal/file_pattern_matcher.py +11 -1
- modal/functions.py +20 -5
- modal/functions.pyi +2 -2
- modal/image.py +95 -39
- modal/image.pyi +11 -2
- modal/io_streams.py +15 -27
- modal/io_streams_helper.py +53 -0
- modal/mount.py +3 -5
- modal/mount.pyi +4 -4
- modal/partial_function.py +4 -4
- modal/runner.py +34 -37
- modal/runner.pyi +6 -3
- modal/running_app.py +23 -4
- modal/sandbox.py +19 -6
- modal/sandbox.pyi +25 -0
- {modal-0.68.50.dist-info → modal-0.71.5.dist-info}/METADATA +1 -1
- {modal-0.68.50.dist-info → modal-0.71.5.dist-info}/RECORD +44 -42
- modal_proto/api.proto +13 -0
- modal_proto/api_grpc.py +16 -0
- modal_proto/api_pb2.py +456 -436
- modal_proto/api_pb2.pyi +41 -1
- modal_proto/api_pb2_grpc.py +34 -1
- modal_proto/api_pb2_grpc.pyi +13 -3
- modal_proto/modal_api_grpc.py +1 -0
- modal_version/__init__.py +1 -1
- modal_version/_version_generated.py +2 -2
- {modal-0.68.50.dist-info → modal-0.71.5.dist-info}/LICENSE +0 -0
- {modal-0.68.50.dist-info → modal-0.71.5.dist-info}/WHEEL +0 -0
- {modal-0.68.50.dist-info → modal-0.71.5.dist-info}/entry_points.txt +0 -0
- {modal-0.68.50.dist-info → modal-0.71.5.dist-info}/top_level.txt +0 -0
modal/mount.py
CHANGED
@@ -16,6 +16,7 @@ from typing import Callable, Optional, Sequence, Union
|
|
16
16
|
from google.protobuf.message import Message
|
17
17
|
|
18
18
|
import modal.exception
|
19
|
+
import modal.file_pattern_matcher
|
19
20
|
from modal_proto import api_pb2
|
20
21
|
from modal_version import __version__
|
21
22
|
|
@@ -325,12 +326,9 @@ class _Mount(_Object, type_prefix="mo"):
|
|
325
326
|
@staticmethod
|
326
327
|
def _add_local_dir(
|
327
328
|
local_path: Path,
|
328
|
-
remote_path:
|
329
|
-
ignore:
|
329
|
+
remote_path: PurePosixPath,
|
330
|
+
ignore: Callable[[Path], bool] = modal.file_pattern_matcher._NOTHING,
|
330
331
|
):
|
331
|
-
if isinstance(ignore, list):
|
332
|
-
ignore = FilePatternMatcher(*ignore)
|
333
|
-
|
334
332
|
return _Mount._new()._extend(
|
335
333
|
_MountDir(
|
336
334
|
local_dir=local_path,
|
modal/mount.pyi
CHANGED
@@ -94,8 +94,8 @@ class _Mount(modal.object._Object):
|
|
94
94
|
@staticmethod
|
95
95
|
def _add_local_dir(
|
96
96
|
local_path: pathlib.Path,
|
97
|
-
remote_path: pathlib.
|
98
|
-
ignore: typing.
|
97
|
+
remote_path: pathlib.PurePosixPath,
|
98
|
+
ignore: typing.Callable[[pathlib.Path], bool] = modal.file_pattern_matcher._NOTHING,
|
99
99
|
): ...
|
100
100
|
def add_local_dir(
|
101
101
|
self,
|
@@ -176,8 +176,8 @@ class Mount(modal.object.Object):
|
|
176
176
|
@staticmethod
|
177
177
|
def _add_local_dir(
|
178
178
|
local_path: pathlib.Path,
|
179
|
-
remote_path: pathlib.
|
180
|
-
ignore: typing.
|
179
|
+
remote_path: pathlib.PurePosixPath,
|
180
|
+
ignore: typing.Callable[[pathlib.Path], bool] = modal.file_pattern_matcher._NOTHING,
|
181
181
|
): ...
|
182
182
|
def add_local_dir(
|
183
183
|
self,
|
modal/partial_function.py
CHANGED
@@ -253,7 +253,7 @@ def _web_endpoint(
|
|
253
253
|
custom_domains: Optional[
|
254
254
|
Iterable[str]
|
255
255
|
] = None, # Create an endpoint using a custom domain fully-qualified domain name (FQDN).
|
256
|
-
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
256
|
+
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
257
257
|
wait_for_response: bool = True, # DEPRECATED: this must always be True now
|
258
258
|
) -> Callable[[Callable[P, ReturnType]], _PartialFunction[P, ReturnType, ReturnType]]:
|
259
259
|
"""Register a basic web endpoint with this application.
|
@@ -316,7 +316,7 @@ def _asgi_app(
|
|
316
316
|
*,
|
317
317
|
label: Optional[str] = None, # Label for created endpoint. Final subdomain will be <workspace>--<label>.modal.run.
|
318
318
|
custom_domains: Optional[Iterable[str]] = None, # Deploy this endpoint on a custom domain.
|
319
|
-
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
319
|
+
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
320
320
|
wait_for_response: bool = True, # DEPRECATED: this must always be True now
|
321
321
|
) -> Callable[[Callable[..., Any]], _PartialFunction]:
|
322
322
|
"""Decorator for registering an ASGI app with a Modal function.
|
@@ -392,7 +392,7 @@ def _wsgi_app(
|
|
392
392
|
*,
|
393
393
|
label: Optional[str] = None, # Label for created endpoint. Final subdomain will be <workspace>--<label>.modal.run.
|
394
394
|
custom_domains: Optional[Iterable[str]] = None, # Deploy this endpoint on a custom domain.
|
395
|
-
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
395
|
+
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
396
396
|
wait_for_response: bool = True, # DEPRECATED: this must always be True now
|
397
397
|
) -> Callable[[Callable[..., Any]], _PartialFunction]:
|
398
398
|
"""Decorator for registering a WSGI app with a Modal function.
|
@@ -469,7 +469,7 @@ def _web_server(
|
|
469
469
|
startup_timeout: float = 5.0, # Maximum number of seconds to wait for the web server to start.
|
470
470
|
label: Optional[str] = None, # Label for created endpoint. Final subdomain will be <workspace>--<label>.modal.run.
|
471
471
|
custom_domains: Optional[Iterable[str]] = None, # Deploy this endpoint on a custom domain.
|
472
|
-
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
472
|
+
requires_proxy_auth: bool = False, # Require Proxy-Authorization HTTP Headers on requests
|
473
473
|
) -> Callable[[Callable[..., Any]], _PartialFunction]:
|
474
474
|
"""Decorator that registers an HTTP web server inside the container.
|
475
475
|
|
modal/runner.py
CHANGED
@@ -6,7 +6,7 @@ import time
|
|
6
6
|
import typing
|
7
7
|
from collections.abc import AsyncGenerator
|
8
8
|
from multiprocessing.synchronize import Event
|
9
|
-
from typing import TYPE_CHECKING, Any,
|
9
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar
|
10
10
|
|
11
11
|
from grpclib import GRPCError, Status
|
12
12
|
from synchronicity.async_wrap import asynccontextmanager
|
@@ -30,7 +30,7 @@ from .exception import InteractiveTimeoutError, InvalidError, RemoteError, _CliU
|
|
30
30
|
from .functions import _Function
|
31
31
|
from .object import _get_environment_name, _Object
|
32
32
|
from .output import _get_output_manager, enable_output
|
33
|
-
from .running_app import RunningApp
|
33
|
+
from .running_app import RunningApp, running_app_from_layout
|
34
34
|
from .sandbox import _Sandbox
|
35
35
|
from .secret import _Secret
|
36
36
|
from .stream_type import StreamType
|
@@ -54,15 +54,18 @@ async def _heartbeat(client: _Client, app_id: str) -> None:
|
|
54
54
|
|
55
55
|
async def _init_local_app_existing(client: _Client, existing_app_id: str, environment_name: str) -> RunningApp:
|
56
56
|
# Get all the objects first
|
57
|
-
obj_req = api_pb2.
|
57
|
+
obj_req = api_pb2.AppGetLayoutRequest(app_id=existing_app_id)
|
58
58
|
obj_resp, _ = await gather_cancel_on_exc(
|
59
|
-
retry_transient_errors(client.stub.
|
59
|
+
retry_transient_errors(client.stub.AppGetLayout, obj_req),
|
60
60
|
# Cache the environment associated with the app now as we will use it later
|
61
61
|
_get_environment_cached(environment_name, client),
|
62
62
|
)
|
63
63
|
app_page_url = f"https://modal.com/apps/{existing_app_id}" # TODO (elias): this should come from the backend
|
64
|
-
|
65
|
-
|
64
|
+
return running_app_from_layout(
|
65
|
+
existing_app_id,
|
66
|
+
obj_resp.app_layout,
|
67
|
+
app_page_url=app_page_url,
|
68
|
+
)
|
66
69
|
|
67
70
|
|
68
71
|
async def _init_local_app_new(
|
@@ -85,10 +88,8 @@ async def _init_local_app_new(
|
|
85
88
|
logger.debug(f"Created new app with id {app_resp.app_id}")
|
86
89
|
return RunningApp(
|
87
90
|
app_resp.app_id,
|
88
|
-
client=client,
|
89
91
|
app_page_url=app_resp.app_page_url,
|
90
92
|
app_logs_url=app_resp.app_logs_url,
|
91
|
-
environment_name=environment_name,
|
92
93
|
interactive=interactive,
|
93
94
|
)
|
94
95
|
|
@@ -120,10 +121,12 @@ async def _init_local_app_from_name(
|
|
120
121
|
async def _create_all_objects(
|
121
122
|
client: _Client,
|
122
123
|
running_app: RunningApp,
|
123
|
-
|
124
|
+
functions: dict[str, _Function],
|
125
|
+
classes: dict[str, _Cls],
|
124
126
|
environment_name: str,
|
125
127
|
) -> None:
|
126
128
|
"""Create objects that have been defined but not created on the server."""
|
129
|
+
indexed_objects: dict[str, _Object] = {**functions, **classes}
|
127
130
|
resolver = Resolver(
|
128
131
|
client,
|
129
132
|
environment_name=environment_name,
|
@@ -131,8 +134,9 @@ async def _create_all_objects(
|
|
131
134
|
)
|
132
135
|
with resolver.display():
|
133
136
|
# Get current objects, and reset all objects
|
134
|
-
tag_to_object_id = running_app.
|
135
|
-
running_app.
|
137
|
+
tag_to_object_id = {**running_app.function_ids, **running_app.class_ids}
|
138
|
+
running_app.function_ids = {}
|
139
|
+
running_app.class_ids = {}
|
136
140
|
|
137
141
|
# Assign all objects
|
138
142
|
for tag, obj in indexed_objects.items():
|
@@ -159,7 +163,12 @@ async def _create_all_objects(
|
|
159
163
|
async def _load(tag, obj):
|
160
164
|
existing_object_id = tag_to_object_id.get(tag)
|
161
165
|
await resolver.load(obj, existing_object_id)
|
162
|
-
|
166
|
+
if _Function._is_id_type(obj.object_id):
|
167
|
+
running_app.function_ids[tag] = obj.object_id
|
168
|
+
elif _Cls._is_id_type(obj.object_id):
|
169
|
+
running_app.class_ids[tag] = obj.object_id
|
170
|
+
else:
|
171
|
+
raise RuntimeError(f"Unexpected object {obj.object_id}")
|
163
172
|
|
164
173
|
await TaskContext.gather(*(_load(tag, obj) for tag, obj in indexed_objects.items()))
|
165
174
|
|
@@ -168,30 +177,22 @@ async def _publish_app(
|
|
168
177
|
client: _Client,
|
169
178
|
running_app: RunningApp,
|
170
179
|
app_state: int, # api_pb2.AppState.value
|
171
|
-
|
180
|
+
functions: dict[str, _Function],
|
181
|
+
classes: dict[str, _Cls],
|
172
182
|
name: str = "", # Only relevant for deployments
|
173
183
|
tag: str = "", # Only relevant for deployments
|
174
184
|
) -> tuple[str, list[api_pb2.Warning]]:
|
175
185
|
"""Wrapper for AppPublish RPC."""
|
176
186
|
|
177
|
-
|
178
|
-
# function_ids / class_ids rather than the current tag_to_object_id (i.e. "indexed_objects")
|
179
|
-
def filter_values(full_dict: dict[str, V], condition: Callable[[V], bool]) -> dict[str, V]:
|
180
|
-
return {k: v for k, v in full_dict.items() if condition(v)}
|
181
|
-
|
182
|
-
function_ids = filter_values(running_app.tag_to_object_id, _Function._is_id_type)
|
183
|
-
class_ids = filter_values(running_app.tag_to_object_id, _Cls._is_id_type)
|
184
|
-
|
185
|
-
function_objs = filter_values(indexed_objects, lambda v: v.object_id in function_ids.values())
|
186
|
-
definition_ids = {obj.object_id: obj._get_metadata().definition_id for obj in function_objs.values()} # type: ignore
|
187
|
+
definition_ids = {obj.object_id: obj._get_metadata().definition_id for obj in functions.values()} # type: ignore
|
187
188
|
|
188
189
|
request = api_pb2.AppPublishRequest(
|
189
190
|
app_id=running_app.app_id,
|
190
191
|
name=name,
|
191
192
|
deployment_tag=tag,
|
192
193
|
app_state=app_state, # type: ignore : should be a api_pb2.AppState.value
|
193
|
-
function_ids=function_ids,
|
194
|
-
class_ids=class_ids,
|
194
|
+
function_ids=running_app.function_ids,
|
195
|
+
class_ids=running_app.class_ids,
|
195
196
|
definition_ids=definition_ids,
|
196
197
|
)
|
197
198
|
try:
|
@@ -325,13 +326,11 @@ async def _run_app(
|
|
325
326
|
)
|
326
327
|
|
327
328
|
try:
|
328
|
-
indexed_objects = dict(**app._functions, **app._classes) # TODO(erikbern): remove
|
329
|
-
|
330
329
|
# Create all members
|
331
|
-
await _create_all_objects(client, running_app,
|
330
|
+
await _create_all_objects(client, running_app, app._functions, app._classes, environment_name)
|
332
331
|
|
333
332
|
# Publish the app
|
334
|
-
await _publish_app(client, running_app, app_state,
|
333
|
+
await _publish_app(client, running_app, app_state, app._functions, app._classes)
|
335
334
|
except asyncio.CancelledError as e:
|
336
335
|
# this typically happens on sigint/ctrl-C during setup (the KeyboardInterrupt happens in the main thread)
|
337
336
|
if output_mgr := _get_output_manager():
|
@@ -424,18 +423,17 @@ async def _serve_update(
|
|
424
423
|
try:
|
425
424
|
running_app: RunningApp = await _init_local_app_existing(client, existing_app_id, environment_name)
|
426
425
|
|
427
|
-
indexed_objects = dict(**app._functions, **app._classes) # TODO(erikbern): remove
|
428
|
-
|
429
426
|
# Create objects
|
430
427
|
await _create_all_objects(
|
431
428
|
client,
|
432
429
|
running_app,
|
433
|
-
|
430
|
+
app._functions,
|
431
|
+
app._classes,
|
434
432
|
environment_name,
|
435
433
|
)
|
436
434
|
|
437
435
|
# Publish the updated app
|
438
|
-
await _publish_app(client, running_app, api_pb2.APP_STATE_UNSPECIFIED,
|
436
|
+
await _publish_app(client, running_app, api_pb2.APP_STATE_UNSPECIFIED, app._functions, app._classes)
|
439
437
|
|
440
438
|
# Communicate to the parent process
|
441
439
|
is_ready.set()
|
@@ -523,19 +521,18 @@ async def _deploy_app(
|
|
523
521
|
|
524
522
|
tc.infinite_loop(heartbeat, sleep=HEARTBEAT_INTERVAL)
|
525
523
|
|
526
|
-
indexed_objects = dict(**app._functions, **app._classes) # TODO(erikbern): remove
|
527
|
-
|
528
524
|
try:
|
529
525
|
# Create all members
|
530
526
|
await _create_all_objects(
|
531
527
|
client,
|
532
528
|
running_app,
|
533
|
-
|
529
|
+
app._functions,
|
530
|
+
app._classes,
|
534
531
|
environment_name=environment_name,
|
535
532
|
)
|
536
533
|
|
537
534
|
app_url, warnings = await _publish_app(
|
538
|
-
client, running_app, api_pb2.APP_STATE_DEPLOYED,
|
535
|
+
client, running_app, api_pb2.APP_STATE_DEPLOYED, app._functions, app._classes, name, tag
|
539
536
|
)
|
540
537
|
except Exception as e:
|
541
538
|
# Note that AppClientDisconnect only stops the app if it's still initializing, and is a no-op otherwise.
|
modal/runner.pyi
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import modal.client
|
2
|
-
import modal.
|
2
|
+
import modal.cls
|
3
|
+
import modal.functions
|
3
4
|
import modal.running_app
|
4
5
|
import modal_proto.api_pb2
|
5
6
|
import multiprocessing.synchronize
|
@@ -28,14 +29,16 @@ async def _init_local_app_from_name(
|
|
28
29
|
async def _create_all_objects(
|
29
30
|
client: modal.client._Client,
|
30
31
|
running_app: modal.running_app.RunningApp,
|
31
|
-
|
32
|
+
functions: dict[str, modal.functions._Function],
|
33
|
+
classes: dict[str, modal.cls._Cls],
|
32
34
|
environment_name: str,
|
33
35
|
) -> None: ...
|
34
36
|
async def _publish_app(
|
35
37
|
client: modal.client._Client,
|
36
38
|
running_app: modal.running_app.RunningApp,
|
37
39
|
app_state: int,
|
38
|
-
|
40
|
+
functions: dict[str, modal.functions._Function],
|
41
|
+
classes: dict[str, modal.cls._Cls],
|
39
42
|
name: str = "",
|
40
43
|
tag: str = "",
|
41
44
|
) -> tuple[str, list[modal_proto.api_pb2.Warning]]: ...
|
modal/running_app.py
CHANGED
@@ -4,16 +4,35 @@ from typing import Optional
|
|
4
4
|
|
5
5
|
from google.protobuf.message import Message
|
6
6
|
|
7
|
-
from .
|
7
|
+
from modal._utils.grpc_utils import get_proto_oneof
|
8
|
+
from modal_proto import api_pb2
|
8
9
|
|
9
10
|
|
10
11
|
@dataclass
|
11
12
|
class RunningApp:
|
12
13
|
app_id: str
|
13
|
-
environment_name: Optional[str] = None
|
14
14
|
app_page_url: Optional[str] = None
|
15
15
|
app_logs_url: Optional[str] = None
|
16
|
-
|
16
|
+
function_ids: dict[str, str] = field(default_factory=dict)
|
17
|
+
class_ids: dict[str, str] = field(default_factory=dict)
|
17
18
|
object_handle_metadata: dict[str, Optional[Message]] = field(default_factory=dict)
|
18
19
|
interactive: bool = False
|
19
|
-
|
20
|
+
|
21
|
+
|
22
|
+
def running_app_from_layout(
|
23
|
+
app_id: str,
|
24
|
+
app_layout: api_pb2.AppLayout,
|
25
|
+
app_page_url: Optional[str] = None,
|
26
|
+
) -> RunningApp:
|
27
|
+
object_handle_metadata = {}
|
28
|
+
for obj in app_layout.objects:
|
29
|
+
handle_metadata: Optional[Message] = get_proto_oneof(obj, "handle_metadata_oneof")
|
30
|
+
object_handle_metadata[obj.object_id] = handle_metadata
|
31
|
+
|
32
|
+
return RunningApp(
|
33
|
+
app_id,
|
34
|
+
function_ids=dict(app_layout.function_ids),
|
35
|
+
class_ids=dict(app_layout.class_ids),
|
36
|
+
object_handle_metadata=object_handle_metadata,
|
37
|
+
app_page_url=app_page_url,
|
38
|
+
)
|
modal/sandbox.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
import asyncio
|
3
3
|
import os
|
4
4
|
from collections.abc import AsyncGenerator, Sequence
|
5
|
-
from typing import TYPE_CHECKING, Literal, Optional, Union, overload
|
5
|
+
from typing import TYPE_CHECKING, AsyncIterator, Literal, Optional, Union, overload
|
6
6
|
|
7
7
|
if TYPE_CHECKING:
|
8
8
|
import _typeshed
|
@@ -26,7 +26,7 @@ from .client import _Client
|
|
26
26
|
from .config import config
|
27
27
|
from .container_process import _ContainerProcess
|
28
28
|
from .exception import ExecutionError, InvalidError, SandboxTerminatedError, SandboxTimeoutError
|
29
|
-
from .file_io import _FileIO
|
29
|
+
from .file_io import FileWatchEvent, FileWatchEventType, _FileIO
|
30
30
|
from .gpu import GPU_T
|
31
31
|
from .image import _Image
|
32
32
|
from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
|
@@ -276,9 +276,9 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
276
276
|
|
277
277
|
app_id = app.app_id
|
278
278
|
app_client = app._client
|
279
|
-
elif _App.
|
280
|
-
app_id =
|
281
|
-
app_client =
|
279
|
+
elif (container_app := _App._get_container_app()) is not None:
|
280
|
+
app_id = container_app.app_id
|
281
|
+
app_client = container_app._client
|
282
282
|
else:
|
283
283
|
arglist = ", ".join(repr(s) for s in entrypoint_args)
|
284
284
|
deprecation_error(
|
@@ -320,7 +320,9 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
320
320
|
resp = await retry_transient_errors(client.stub.SandboxWait, req)
|
321
321
|
|
322
322
|
obj = _Sandbox._new_hydrated(sandbox_id, client, None)
|
323
|
-
|
323
|
+
|
324
|
+
if resp.result.status:
|
325
|
+
obj._result = resp.result
|
324
326
|
|
325
327
|
return obj
|
326
328
|
|
@@ -579,6 +581,17 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
579
581
|
task_id = await self._get_task_id()
|
580
582
|
return await _FileIO.rm(path, self._client, task_id, recursive)
|
581
583
|
|
584
|
+
async def watch(
|
585
|
+
self,
|
586
|
+
path: str,
|
587
|
+
filter: Optional[list[FileWatchEventType]] = None,
|
588
|
+
recursive: Optional[bool] = None,
|
589
|
+
timeout: Optional[int] = None,
|
590
|
+
) -> AsyncIterator[FileWatchEvent]:
|
591
|
+
task_id = await self._get_task_id()
|
592
|
+
async for event in _FileIO.watch(path, self._client, task_id, filter, recursive, timeout):
|
593
|
+
yield event
|
594
|
+
|
582
595
|
@property
|
583
596
|
def stdout(self) -> _StreamReader[str]:
|
584
597
|
"""
|
modal/sandbox.pyi
CHANGED
@@ -131,6 +131,13 @@ class _Sandbox(modal.object._Object):
|
|
131
131
|
async def ls(self, path: str) -> list[str]: ...
|
132
132
|
async def mkdir(self, path: str, parents: bool = False) -> None: ...
|
133
133
|
async def rm(self, path: str, recursive: bool = False) -> None: ...
|
134
|
+
def watch(
|
135
|
+
self,
|
136
|
+
path: str,
|
137
|
+
filter: typing.Optional[list[modal.file_io.FileWatchEventType]] = None,
|
138
|
+
recursive: typing.Optional[bool] = None,
|
139
|
+
timeout: typing.Optional[int] = None,
|
140
|
+
) -> typing.AsyncIterator[modal.file_io.FileWatchEvent]: ...
|
134
141
|
@property
|
135
142
|
def stdout(self) -> modal.io_streams._StreamReader[str]: ...
|
136
143
|
@property
|
@@ -388,6 +395,24 @@ class Sandbox(modal.object.Object):
|
|
388
395
|
|
389
396
|
rm: __rm_spec
|
390
397
|
|
398
|
+
class __watch_spec(typing_extensions.Protocol):
|
399
|
+
def __call__(
|
400
|
+
self,
|
401
|
+
path: str,
|
402
|
+
filter: typing.Optional[list[modal.file_io.FileWatchEventType]] = None,
|
403
|
+
recursive: typing.Optional[bool] = None,
|
404
|
+
timeout: typing.Optional[int] = None,
|
405
|
+
) -> typing.Iterator[modal.file_io.FileWatchEvent]: ...
|
406
|
+
def aio(
|
407
|
+
self,
|
408
|
+
path: str,
|
409
|
+
filter: typing.Optional[list[modal.file_io.FileWatchEventType]] = None,
|
410
|
+
recursive: typing.Optional[bool] = None,
|
411
|
+
timeout: typing.Optional[int] = None,
|
412
|
+
) -> typing.AsyncIterator[modal.file_io.FileWatchEvent]: ...
|
413
|
+
|
414
|
+
watch: __watch_spec
|
415
|
+
|
391
416
|
@property
|
392
417
|
def stdout(self) -> modal.io_streams.StreamReader[str]: ...
|
393
418
|
@property
|
@@ -2,7 +2,7 @@ modal/__init__.py,sha256=3NJLLHb0TRc2tc68kf8NHzORx38GbtbZvPEWDWrQ6N4,2234
|
|
2
2
|
modal/__main__.py,sha256=scYhGFqh8OJcVDo-VOxIT6CCwxOgzgflYWMnIZiMRqE,2871
|
3
3
|
modal/_clustered_functions.py,sha256=kTf-9YBXY88NutC1akI-gCbvf01RhMPCw-zoOI_YIUE,2700
|
4
4
|
modal/_clustered_functions.pyi,sha256=vllkegc99A0jrUOWa8mdlSbdp6uz36TsHhGxysAOpaQ,771
|
5
|
-
modal/_container_entrypoint.py,sha256
|
5
|
+
modal/_container_entrypoint.py,sha256=-zUa567FgOKmF0TtFWQ6DgehUD2CMfABDBQ8oLSpjyc,29171
|
6
6
|
modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
|
7
7
|
modal/_location.py,sha256=S3lSxIU3h9HkWpkJ3Pwo0pqjIOSB1fjeSgUsY3x7eec,1202
|
8
8
|
modal/_output.py,sha256=0fWX_KQwhER--U81ys16CL-pA5A-LN20C0EZjElKGJQ,25410
|
@@ -15,11 +15,11 @@ modal/_traceback.py,sha256=IZQzB3fVlUfMHOSyKUgw0H6qv4yHnpyq-XVCNZKfUdA,5023
|
|
15
15
|
modal/_tunnel.py,sha256=o-jJhS4vQ6-XswDhHcJWGMZZmD03SC0e9i8fEu1JTjo,6310
|
16
16
|
modal/_tunnel.pyi,sha256=JmmDYAy9F1FpgJ_hWx0xkom2nTOFQjn4mTPYlU3PFo4,1245
|
17
17
|
modal/_watcher.py,sha256=K6LYnlmSGQB4tWWI9JADv-tvSvQ1j522FwT71B51CX8,3584
|
18
|
-
modal/app.py,sha256=
|
19
|
-
modal/app.pyi,sha256=
|
18
|
+
modal/app.py,sha256=vEE0cK5QPF6_cdW5AJvcuWxz5KmeprHwBEtlDkVRHgE,45582
|
19
|
+
modal/app.pyi,sha256=Gx7gxjfQ70sxhbwfpx1VjvzEON-ZEMTJ_Vy8qt0oQvo,25302
|
20
20
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
21
21
|
modal/client.py,sha256=JAnd4-GCN093BwkvOFAK5a6iy5ycxofjpUncMxlrIMw,15253
|
22
|
-
modal/client.pyi,sha256=
|
22
|
+
modal/client.pyi,sha256=pjZG1Z_8vLGkYtlrkEBAkl9tV9wqACVl0a3qWxHPacQ,7278
|
23
23
|
modal/cloud_bucket_mount.py,sha256=G7T7jWLD0QkmrfKR75mSTwdUZ2xNfj7pkVqb4ipmxmI,5735
|
24
24
|
modal/cloud_bucket_mount.pyi,sha256=CEi7vrH3kDUF4LAy4qP6tfImy2UJuFRcRbsgRNM1wo8,1403
|
25
25
|
modal/cls.py,sha256=3hjb0JcoPjxKZNeK22f5rR43bZRBjoRI7_EMZXY7YrE,31172
|
@@ -31,20 +31,21 @@ modal/dict.py,sha256=ei9jsA5iTj4UFGPJxTAed6vjd49W47ezDtj0koUmVts,12497
|
|
31
31
|
modal/dict.pyi,sha256=VmbzxltA2vFlIHZCxpNGtd-ieXwcUwdw3iyy3WCweqU,7115
|
32
32
|
modal/environments.py,sha256=wbv9ttFCbzATGfwcmvYiG608PfHovx0AQmawsg-jmic,6660
|
33
33
|
modal/environments.pyi,sha256=rF7oaaELoSNuoD6qImGnIbuGPtgWwR5SlcExyYJ61hQ,3515
|
34
|
-
modal/exception.py,sha256=
|
35
|
-
modal/experimental.py,sha256=
|
36
|
-
modal/file_io.py,sha256=
|
37
|
-
modal/file_io.pyi,sha256=
|
38
|
-
modal/file_pattern_matcher.py,sha256=
|
39
|
-
modal/functions.py,sha256=
|
40
|
-
modal/functions.pyi,sha256=
|
34
|
+
modal/exception.py,sha256=4JyO-SACaLNDe2QC48EjsK8GMkZ8AgEurZ8j1YdRu8E,5263
|
35
|
+
modal/experimental.py,sha256=npfKbyMpI41uZZs9HW_QiB3E4ykWfDXZbACXXbw6qeA,2385
|
36
|
+
modal/file_io.py,sha256=ZR8VBCDsDt5uB9TNN9XbEh7sniJzM_5YL47m8WP0m5c,19617
|
37
|
+
modal/file_io.pyi,sha256=79Fg75BjmMEeCX0Lx-Z8C4XSNPCotwNdK6ZLIDFm2f4,9770
|
38
|
+
modal/file_pattern_matcher.py,sha256=LaI7Paxg0xR9D-D7Tgc60xR0w1KZee22LjGbFie1Vms,5571
|
39
|
+
modal/functions.py,sha256=3uJPbrEAWhpFfLfUnoRjGmvEUC-_wVh-8yNJBx8eVeM,68249
|
40
|
+
modal/functions.pyi,sha256=LiSDgH-X7jcZ56pAoLMwo3x9Dzdp_3Sd7W5MVAJPoCg,25407
|
41
41
|
modal/gpu.py,sha256=MTxj6ql8EpgfBg8YmZ5a1cLznyuZFssX1qXbEX4LKVM,7503
|
42
|
-
modal/image.py,sha256=
|
43
|
-
modal/image.pyi,sha256=
|
44
|
-
modal/io_streams.py,sha256=
|
42
|
+
modal/image.py,sha256=Krvcsclomp9YsqSNwFj2FoAyg10OvU47RDnsNCwjGbQ,84550
|
43
|
+
modal/image.pyi,sha256=1fgGvsL5Rb0Sa-_2OCgIyJ_QgHcL0_9MWD_oY7cyFFM,24937
|
44
|
+
modal/io_streams.py,sha256=Xxc5grJiO94nBA48FFWH3S3g6SPR0xFVgZ_DZ1oFmvI,14428
|
45
45
|
modal/io_streams.pyi,sha256=bCCVSxkMcosYd8O3PQDDwJw7TQ8JEcnYonLJ5t27TQs,4804
|
46
|
-
modal/
|
47
|
-
modal/mount.
|
46
|
+
modal/io_streams_helper.py,sha256=B5Ui56ph7LkRpZX0tAF80Q-gOMsvPPLx5bpIPX0kgDc,1772
|
47
|
+
modal/mount.py,sha256=wOr-2vmKImsE3lHBII8hL2gYy5ng46R58QwId4JultQ,29313
|
48
|
+
modal/mount.pyi,sha256=FiNV1wIKFvd0ZMZ0tm1mz6ZSA5Hjsge-kFSA5tPWfcI,10503
|
48
49
|
modal/network_file_system.py,sha256=INj1TfN_Fsmabmlte7anvey1epodjbMmjBW_TIJSST4,14406
|
49
50
|
modal/network_file_system.pyi,sha256=61M-sdWrtaRjmuNVsvusI6kf1Qw-jUOVXvEAeOkM8Aw,7751
|
50
51
|
modal/object.py,sha256=HZs3N59C6JxlMuPQWJYvrWV1FEEkH9txUovVDorVUbs,9763
|
@@ -52,7 +53,7 @@ modal/object.pyi,sha256=MO78H9yFSE5i1gExPEwyyQzLdlshkcGHN1aQ0ylyvq0,8802
|
|
52
53
|
modal/output.py,sha256=N0xf4qeudEaYrslzdAl35VKV8rapstgIM2e9wO8_iy0,1967
|
53
54
|
modal/parallel_map.py,sha256=4aoMXIrlG3wl5Ifk2YDNOQkXsGRsm6Xbfm6WtJ2t3WY,16002
|
54
55
|
modal/parallel_map.pyi,sha256=pOhT0P3DDYlwLx0fR3PTsecA7DI8uOdXC1N8i-ZkyOY,2328
|
55
|
-
modal/partial_function.py,sha256=
|
56
|
+
modal/partial_function.py,sha256=KSpHhu7Gsbe4h-5mcJjxnE4328biKOB7yVouHZbObA8,27798
|
56
57
|
modal/partial_function.pyi,sha256=pO6kf8i5HVsZ7CF0z_KkzLk4Aeq7NJhFJ_VNIycRXaU,9260
|
57
58
|
modal/proxy.py,sha256=ZrOsuQP7dSZFq1OrIxalNnt0Zvsnp1h86Th679sSL40,1417
|
58
59
|
modal/proxy.pyi,sha256=UvygdOYneLTuoDY6hVaMNCyZ947Tmx93IdLjErUqkvM,368
|
@@ -60,11 +61,11 @@ modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
61
|
modal/queue.py,sha256=zMUQtdAyqZzBg-2iAo3c3G54HLP7TEWfVhiQXLjewb4,18556
|
61
62
|
modal/queue.pyi,sha256=gGV97pWelSSYqMV9Bl4ys3mSP7q82fS71oqSWeAwyDE,9818
|
62
63
|
modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
|
63
|
-
modal/runner.py,sha256=
|
64
|
-
modal/runner.pyi,sha256=
|
65
|
-
modal/running_app.py,sha256=
|
66
|
-
modal/sandbox.py,sha256=
|
67
|
-
modal/sandbox.pyi,sha256=
|
64
|
+
modal/runner.py,sha256=mhqgRdjD5cUDpBQIokiX7OCfVblpGV6aWmZ-WvWJgGg,24114
|
65
|
+
modal/runner.pyi,sha256=YmP4EOCNjjkwSIPi2Gl6hF_ji_ytkxz9dw3iB9KXaOI,5275
|
66
|
+
modal/running_app.py,sha256=v61mapYNV1-O-Uaho5EfJlryMLvIT9We0amUOSvSGx8,1188
|
67
|
+
modal/sandbox.py,sha256=H63K3MTcgdb9KkKc79sMKe6UzFMGBNI7HB2TUwBbE_U,28609
|
68
|
+
modal/sandbox.pyi,sha256=lceWDeXqzdeRc1iIuM5YmpoZlBJcVBpQO1Jc3AT1AQI,20809
|
68
69
|
modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
|
69
70
|
modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
|
70
71
|
modal/secret.py,sha256=lebVTZi4fC9PXQpLVmsvgQLzy-2Kzxv1WBD0Jr2wsxQ,10117
|
@@ -78,7 +79,7 @@ modal/volume.py,sha256=T-pLxCYqmqRO6OolpAXlPxomMu0RWjti2e4kUpaj2cQ,29229
|
|
78
79
|
modal/volume.pyi,sha256=eekb2dnAAwFK_NO9ciAOOTthl8NP1iAmMFrCGgjDA2k,11100
|
79
80
|
modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
|
80
81
|
modal/_runtime/asgi.py,sha256=Mjs859pSgOmtZL-YmEsSKN557v1A2Ax_5-ERgPfj55E,21920
|
81
|
-
modal/_runtime/container_io_manager.py,sha256=
|
82
|
+
modal/_runtime/container_io_manager.py,sha256=HgDLjE78yy1P7WZTmsEVDf89YnFFWG63Ddes8uYLVDY,43764
|
82
83
|
modal/_runtime/execution_context.py,sha256=E6ofm6j1POXGPxS841X3V7JU6NheVb8OkQc7JpLq4Kg,2712
|
83
84
|
modal/_runtime/telemetry.py,sha256=T1RoAGyjBDr1swiM6pPsGRSITm7LI5FDK18oNXxY08U,5163
|
84
85
|
modal/_runtime/user_code_imports.py,sha256=n4CQOojzSdf0jwSKSy6MEnVX3IWl3t3Dq54-x9VS2Ds,14663
|
@@ -88,7 +89,8 @@ modal/_utils/async_utils.py,sha256=9ubwMkwiDB4gzOYG2jL9j7Fs-5dxHjcifZe3r7JRg-k,2
|
|
88
89
|
modal/_utils/blob_utils.py,sha256=N66LtZI8PpCkZ7maA7GLW5CAmYUoNJdG-GjaAUR4_NQ,14509
|
89
90
|
modal/_utils/bytes_io_segment_payload.py,sha256=uunxVJS4PE1LojF_UpURMzVK9GuvmYWRqQo_bxEj5TU,3385
|
90
91
|
modal/_utils/deprecation.py,sha256=dycySRBxyZf3ITzEqPNM6MxXTk9-0VVLA8oCPQ5j_Os,3426
|
91
|
-
modal/_utils/
|
92
|
+
modal/_utils/docker_utils.py,sha256=FLz1q0YicL6i_Iq-4inkgDVFfEINVG6YPT2s_P6ly0o,2264
|
93
|
+
modal/_utils/function_utils.py,sha256=q68HhFH16MwhHRnGD8jvIgqDjduRQVp3a_qMWXPyrgU,25518
|
92
94
|
modal/_utils/grpc_testing.py,sha256=H1zHqthv19eGPJz2HKXDyWXWGSqO4BRsxah3L5Xaa8A,8619
|
93
95
|
modal/_utils/grpc_utils.py,sha256=PPB5ay-vXencXNIWPVw5modr3EH7gfq2QPcO5YJ1lMU,7737
|
94
96
|
modal/_utils/hash_utils.py,sha256=zg3J6OGxTFGSFri1qQ12giDz90lWk8bzaxCTUCRtiX4,3034
|
@@ -114,18 +116,18 @@ modal/cli/dict.py,sha256=HaEcjfll7i3Uj3Fg56aj4407if5UljsYfr6fIq-D2W8,4589
|
|
114
116
|
modal/cli/entry_point.py,sha256=aaNxFAqZcmtSjwzkYIA_Ba9CkL4cL4_i2gy5VjoXxkM,4228
|
115
117
|
modal/cli/environment.py,sha256=Ayddkiq9jdj3XYDJ8ZmUqFpPPH8xajYlbexRkzGtUcg,4334
|
116
118
|
modal/cli/import_refs.py,sha256=wnqE5AMeyAN3IZmQvJCp54KRnJh8Nq_5fMqB6u6GEL8,9147
|
117
|
-
modal/cli/launch.py,sha256=
|
119
|
+
modal/cli/launch.py,sha256=44oOlGB0KYDBMfuIlkhW2uzjkWbHhDRR64UOEnGwsJ4,2989
|
118
120
|
modal/cli/network_file_system.py,sha256=o6VLTgN4xn5XUiNPBfxYec-5uWCgYrDmfFFLM1ZW_eE,8180
|
119
121
|
modal/cli/profile.py,sha256=rLXfjJObfPNjaZvNfHGIKqs7y9bGYyGe-K7V0w-Ni0M,3110
|
120
122
|
modal/cli/queues.py,sha256=MIh2OsliNE2QeL1erubfsRsNuG4fxqcqWA2vgIfQ4Mg,4494
|
121
|
-
modal/cli/run.py,sha256=
|
123
|
+
modal/cli/run.py,sha256=QMs3BVSkq8jve76BqgstGt4C6jilbDD9gpCCRPuHUy0,17879
|
122
124
|
modal/cli/secret.py,sha256=uQpwYrMY98iMCWeZOQTcktOYhPTZ8IHnyealDc2CZqo,4206
|
123
125
|
modal/cli/token.py,sha256=mxSgOWakXG6N71hQb1ko61XAR9ZGkTMZD-Txn7gmTac,1924
|
124
126
|
modal/cli/utils.py,sha256=hZmjyzcPjDnQSkLvycZD2LhGdcsfdZshs_rOU78EpvI,3717
|
125
127
|
modal/cli/volume.py,sha256=Oxc8WGP8wm2a_S87bp-P4OnPwoT1wIYQhbgkCvvFIdI,9998
|
126
128
|
modal/cli/programs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
|
127
129
|
modal/cli/programs/run_jupyter.py,sha256=RRr07CqZrStMbLdBM3PpzU6KM8t9FtLbdIPthg2-Mpw,2755
|
128
|
-
modal/cli/programs/vscode.py,sha256=
|
130
|
+
modal/cli/programs/vscode.py,sha256=m80wuQyTALTc7y-kAVqmMjtrcb6muCtpuhxsJm4Va2Y,3453
|
129
131
|
modal/extensions/__init__.py,sha256=waLjl5c6IPDhSsdWAm9Bji4e2PVxamYABKAze6CHVXY,28
|
130
132
|
modal/extensions/ipython.py,sha256=Xvzy-A7cvwMSDa9p4c4CEMLOX2_Xsg9DkM1J9uyu7jc,983
|
131
133
|
modal/requirements/2023.12.312.txt,sha256=zWWUVgVQ92GXBKNYYr2-5vn9rlnXcmkqlwlX5u1eTYw,400
|
@@ -147,13 +149,13 @@ modal_global_objects/mounts/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0
|
|
147
149
|
modal_global_objects/mounts/modal_client_package.py,sha256=W0E_yShsRojPzWm6LtIQqNVolapdnrZkm2hVEQuZK_4,767
|
148
150
|
modal_global_objects/mounts/python_standalone.py,sha256=SL_riIxpd8mP4i4CLDCWiFFNj0Ltknm9c_UIGfX5d60,1836
|
149
151
|
modal_proto/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
|
150
|
-
modal_proto/api.proto,sha256=
|
151
|
-
modal_proto/api_grpc.py,sha256=
|
152
|
-
modal_proto/api_pb2.py,sha256=
|
153
|
-
modal_proto/api_pb2.pyi,sha256=
|
154
|
-
modal_proto/api_pb2_grpc.py,sha256=
|
155
|
-
modal_proto/api_pb2_grpc.pyi,sha256=
|
156
|
-
modal_proto/modal_api_grpc.py,sha256=
|
152
|
+
modal_proto/api.proto,sha256=yxqa3djtNDAD6_AolYTUR_BM5w2apPN6UIXcvjRAFvY,80137
|
153
|
+
modal_proto/api_grpc.py,sha256=MLsxlZXikcv36aSs0iVZywIOANMWstVZMWJGQTDjdM0,102823
|
154
|
+
modal_proto/api_pb2.py,sha256=Mt0QjSEeSNi9vbpK8LoEAfrCF2obuDyJdFWAob2zYFw,294928
|
155
|
+
modal_proto/api_pb2.pyi,sha256=uSsIePIeIK06rkW3rPHSOnpKoagr5bhDWuXjk73W_l8,393499
|
156
|
+
modal_proto/api_pb2_grpc.py,sha256=4d5SwJPLldCqqHz_BGqmJLlX-BMG592WFKUQ6IBg5rg,222415
|
157
|
+
modal_proto/api_pb2_grpc.pyi,sha256=C4c3jndI6TKEgVnx3vAmT86In4T9JKmB1CImiye_aQk,51822
|
158
|
+
modal_proto/modal_api_grpc.py,sha256=eeH1vHXgwO768tM7DXqvj-P37u15SI00gZtm8_EK15I,13732
|
157
159
|
modal_proto/modal_options_grpc.py,sha256=qJ1cuwA54oRqrdTyPTbvfhFZYd9HhJKK5UCwt523r3Y,120
|
158
160
|
modal_proto/options.proto,sha256=a-siq4swVbZPfaFRXAipRZzGP2bq8OsdUvjlyzAeodQ,488
|
159
161
|
modal_proto/options_grpc.py,sha256=M18X3d-8F_cNYSVM3I25dUTO5rZ0rd-vCCfynfh13Nc,125
|
@@ -162,12 +164,12 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
|
|
162
164
|
modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
163
165
|
modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
|
164
166
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
165
|
-
modal_version/__init__.py,sha256=
|
167
|
+
modal_version/__init__.py,sha256=BEBWj9tcbFUwzEjUrqly601rauw5cYsHdcmJHs3iu0s,470
|
166
168
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
167
|
-
modal_version/_version_generated.py,sha256=
|
168
|
-
modal-0.
|
169
|
-
modal-0.
|
170
|
-
modal-0.
|
171
|
-
modal-0.
|
172
|
-
modal-0.
|
173
|
-
modal-0.
|
169
|
+
modal_version/_version_generated.py,sha256=Ryi8NC5BNPKr4cGNqMzFAc_4pmvMQHAGNycNZBu1EBI,148
|
170
|
+
modal-0.71.5.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
171
|
+
modal-0.71.5.dist-info/METADATA,sha256=-r6kJm_xHIGyfR0rcCVEpqeh7hJcMF9WlwUEaGzcm8k,2328
|
172
|
+
modal-0.71.5.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
173
|
+
modal-0.71.5.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
174
|
+
modal-0.71.5.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
|
175
|
+
modal-0.71.5.dist-info/RECORD,,
|
modal_proto/api.proto
CHANGED
@@ -1479,6 +1479,8 @@ message FunctionGetOutputsRequest {
|
|
1479
1479
|
string last_entry_id = 6;
|
1480
1480
|
bool clear_on_success = 7; // expires *any* remaining outputs soon after this call, not just the returned ones
|
1481
1481
|
double requested_at = 8; // Used for waypoints.
|
1482
|
+
// The jwts the client expects the server to be processing. This is optional and used for sync inputs only.
|
1483
|
+
repeated string input_jwts = 9;
|
1482
1484
|
}
|
1483
1485
|
|
1484
1486
|
message FunctionGetOutputsResponse {
|
@@ -1678,6 +1680,7 @@ message GenericResult { // Used for both tasks and function outputs
|
|
1678
1680
|
// Used when the user's function fails to initialize (ex. S3 mount failed due to invalid credentials).
|
1679
1681
|
// Terminates the function and all remaining inputs.
|
1680
1682
|
GENERIC_STATUS_INIT_FAILURE = 5;
|
1683
|
+
GENERIC_STATUS_INTERNAL_FAILURE = 6;
|
1681
1684
|
}
|
1682
1685
|
|
1683
1686
|
GenericStatus status = 1; // Status of the task or function output.
|
@@ -1727,6 +1730,15 @@ message ImageContextFile {
|
|
1727
1730
|
bytes data = 2;
|
1728
1731
|
}
|
1729
1732
|
|
1733
|
+
message ImageFromIdRequest {
|
1734
|
+
string image_id = 1;
|
1735
|
+
}
|
1736
|
+
|
1737
|
+
message ImageFromIdResponse {
|
1738
|
+
string image_id = 1;
|
1739
|
+
ImageMetadata metadata = 2;
|
1740
|
+
}
|
1741
|
+
|
1730
1742
|
message ImageGetOrCreateRequest {
|
1731
1743
|
Image image = 2;
|
1732
1744
|
string app_id = 4 [ (modal.options.audit_target_attr) = true ];
|
@@ -2794,6 +2806,7 @@ service ModalClient {
|
|
2794
2806
|
rpc FunctionUpdateSchedulingParams(FunctionUpdateSchedulingParamsRequest) returns (FunctionUpdateSchedulingParamsResponse);
|
2795
2807
|
|
2796
2808
|
// Images
|
2809
|
+
rpc ImageFromId(ImageFromIdRequest) returns (ImageFromIdResponse);
|
2797
2810
|
rpc ImageGetOrCreate(ImageGetOrCreateRequest) returns (ImageGetOrCreateResponse);
|
2798
2811
|
rpc ImageJoinStreaming(ImageJoinStreamingRequest) returns (stream ImageJoinStreamingResponse);
|
2799
2812
|
|