modal 0.67.13__py3-none-any.whl → 0.67.15__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/client.pyi +2 -2
- modal/container_process.py +6 -2
- modal/io_streams.py +6 -1
- modal/io_streams.pyi +9 -3
- modal/sandbox.py +3 -0
- modal/sandbox.pyi +3 -0
- {modal-0.67.13.dist-info → modal-0.67.15.dist-info}/METADATA +1 -1
- {modal-0.67.13.dist-info → modal-0.67.15.dist-info}/RECORD +13 -13
- modal_version/_version_generated.py +1 -1
- {modal-0.67.13.dist-info → modal-0.67.15.dist-info}/LICENSE +0 -0
- {modal-0.67.13.dist-info → modal-0.67.15.dist-info}/WHEEL +0 -0
- {modal-0.67.13.dist-info → modal-0.67.15.dist-info}/entry_points.txt +0 -0
- {modal-0.67.13.dist-info → modal-0.67.15.dist-info}/top_level.txt +0 -0
modal/client.pyi
CHANGED
@@ -26,7 +26,7 @@ class _Client:
|
|
26
26
|
_stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
|
27
27
|
|
28
28
|
def __init__(
|
29
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.
|
29
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.15"
|
30
30
|
): ...
|
31
31
|
def is_closed(self) -> bool: ...
|
32
32
|
@property
|
@@ -81,7 +81,7 @@ class Client:
|
|
81
81
|
_stub: typing.Optional[modal_proto.api_grpc.ModalClientStub]
|
82
82
|
|
83
83
|
def __init__(
|
84
|
-
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.
|
84
|
+
self, server_url: str, client_type: int, credentials: typing.Optional[tuple[str, str]], version: str = "0.67.15"
|
85
85
|
): ...
|
86
86
|
def is_closed(self) -> bool: ...
|
87
87
|
@property
|
modal/container_process.py
CHANGED
@@ -128,12 +128,16 @@ class _ContainerProcess(Generic[T]):
|
|
128
128
|
on_connect = asyncio.Event()
|
129
129
|
|
130
130
|
async def _write_to_fd_loop(stream: _StreamReader):
|
131
|
-
|
131
|
+
# Don't skip empty messages so we can detect when the process has booted.
|
132
|
+
async for chunk in stream._get_logs(skip_empty_messages=False):
|
133
|
+
if chunk is None:
|
134
|
+
break
|
135
|
+
|
132
136
|
if not on_connect.is_set():
|
133
137
|
connecting_status.stop()
|
134
138
|
on_connect.set()
|
135
139
|
|
136
|
-
await write_to_fd(stream.file_descriptor,
|
140
|
+
await write_to_fd(stream.file_descriptor, chunk)
|
137
141
|
|
138
142
|
async def _handle_input(data: bytes, message_index: int):
|
139
143
|
self.stdin.write(data)
|
modal/io_streams.py
CHANGED
@@ -224,7 +224,7 @@ class _StreamReader(Generic[T]):
|
|
224
224
|
|
225
225
|
entry_id += 1
|
226
226
|
|
227
|
-
async def _get_logs(self) -> AsyncGenerator[Optional[bytes], None]:
|
227
|
+
async def _get_logs(self, skip_empty_messages: bool = True) -> AsyncGenerator[Optional[bytes], None]:
|
228
228
|
"""Streams sandbox or process logs from the server to the reader.
|
229
229
|
|
230
230
|
Logs returned by this method may contain partial or multiple lines at a time.
|
@@ -253,6 +253,11 @@ class _StreamReader(Generic[T]):
|
|
253
253
|
|
254
254
|
async for message, entry_id in iterator:
|
255
255
|
self._last_entry_id = entry_id
|
256
|
+
# Empty messages are sent when the process boots up. Don't yield them unless
|
257
|
+
# we're using the empty message to signal process liveness.
|
258
|
+
if skip_empty_messages and message == b"":
|
259
|
+
continue
|
260
|
+
|
256
261
|
yield message
|
257
262
|
if message is None:
|
258
263
|
completed = True
|
modal/io_streams.pyi
CHANGED
@@ -31,7 +31,9 @@ class _StreamReader(typing.Generic[T]):
|
|
31
31
|
async def read(self) -> T: ...
|
32
32
|
async def _consume_container_process_stream(self): ...
|
33
33
|
def _stream_container_process(self) -> collections.abc.AsyncGenerator[tuple[typing.Optional[bytes], str], None]: ...
|
34
|
-
def _get_logs(
|
34
|
+
def _get_logs(
|
35
|
+
self, skip_empty_messages: bool = True
|
36
|
+
) -> collections.abc.AsyncGenerator[typing.Optional[bytes], None]: ...
|
35
37
|
def _get_logs_by_line(self) -> collections.abc.AsyncGenerator[typing.Optional[bytes], None]: ...
|
36
38
|
def __aiter__(self) -> collections.abc.AsyncIterator[T]: ...
|
37
39
|
async def __anext__(self) -> T: ...
|
@@ -82,8 +84,12 @@ class StreamReader(typing.Generic[T]):
|
|
82
84
|
_stream_container_process: ___stream_container_process_spec
|
83
85
|
|
84
86
|
class ___get_logs_spec(typing_extensions.Protocol):
|
85
|
-
def __call__(
|
86
|
-
|
87
|
+
def __call__(
|
88
|
+
self, skip_empty_messages: bool = True
|
89
|
+
) -> typing.Generator[typing.Optional[bytes], None, None]: ...
|
90
|
+
def aio(
|
91
|
+
self, skip_empty_messages: bool = True
|
92
|
+
) -> collections.abc.AsyncGenerator[typing.Optional[bytes], None]: ...
|
87
93
|
|
88
94
|
_get_logs: ___get_logs_spec
|
89
95
|
|
modal/sandbox.py
CHANGED
@@ -28,6 +28,7 @@ from .io_streams import StreamReader, StreamWriter, _StreamReader, _StreamWriter
|
|
28
28
|
from .mount import _Mount
|
29
29
|
from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
|
30
30
|
from .object import _get_environment_name, _Object
|
31
|
+
from .proxy import _Proxy
|
31
32
|
from .scheduler_placement import SchedulerPlacement
|
32
33
|
from .secret import _Secret
|
33
34
|
from .stream_type import StreamType
|
@@ -73,6 +74,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
73
74
|
pty_info: Optional[api_pb2.PTYInfo] = None,
|
74
75
|
encrypted_ports: Sequence[int] = [],
|
75
76
|
unencrypted_ports: Sequence[int] = [],
|
77
|
+
proxy: Optional[_Proxy] = None,
|
76
78
|
_experimental_scheduler_placement: Optional[SchedulerPlacement] = None,
|
77
79
|
) -> "_Sandbox":
|
78
80
|
"""mdmd:hidden"""
|
@@ -166,6 +168,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
166
168
|
worker_id=config.get("worker_id"),
|
167
169
|
open_ports=api_pb2.PortSpecs(ports=open_ports),
|
168
170
|
network_access=network_access,
|
171
|
+
proxy_id=(proxy.object_id if proxy else None),
|
169
172
|
)
|
170
173
|
|
171
174
|
# Note - `resolver.app_id` will be `None` for app-less sandboxes
|
modal/sandbox.pyi
CHANGED
@@ -11,6 +11,7 @@ import modal.io_streams
|
|
11
11
|
import modal.mount
|
12
12
|
import modal.network_file_system
|
13
13
|
import modal.object
|
14
|
+
import modal.proxy
|
14
15
|
import modal.scheduler_placement
|
15
16
|
import modal.secret
|
16
17
|
import modal.stream_type
|
@@ -51,6 +52,7 @@ class _Sandbox(modal.object._Object):
|
|
51
52
|
pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
|
52
53
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
53
54
|
unencrypted_ports: collections.abc.Sequence[int] = [],
|
55
|
+
proxy: typing.Optional[modal.proxy._Proxy] = None,
|
54
56
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
55
57
|
) -> _Sandbox: ...
|
56
58
|
@staticmethod
|
@@ -165,6 +167,7 @@ class Sandbox(modal.object.Object):
|
|
165
167
|
pty_info: typing.Optional[modal_proto.api_pb2.PTYInfo] = None,
|
166
168
|
encrypted_ports: collections.abc.Sequence[int] = [],
|
167
169
|
unencrypted_ports: collections.abc.Sequence[int] = [],
|
170
|
+
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
168
171
|
_experimental_scheduler_placement: typing.Optional[modal.scheduler_placement.SchedulerPlacement] = None,
|
169
172
|
) -> Sandbox: ...
|
170
173
|
|
@@ -19,13 +19,13 @@ modal/app.py,sha256=EJ7FUN6rWnSwLJoYJh8nmKg_t-8hdN8_rt0OrkP7JvQ,46084
|
|
19
19
|
modal/app.pyi,sha256=BE5SlR5tRECuc6-e2lUuOknDdov3zxgZ4N0AsLb5ZVQ,25270
|
20
20
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
21
21
|
modal/client.py,sha256=VMg_aIuo_LOEe2ttxBHEND3PLhTp5lo-onH4wELhIyY,16375
|
22
|
-
modal/client.pyi,sha256=
|
22
|
+
modal/client.pyi,sha256=omuAq-oRdFMqcdb731dEYbDNBp3cThARcleAXFIPVZs,7354
|
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=F2jk5zFCAA8h-GfM0dbdBG3Mu5wiG9k9Z9JLYRYuT2Q,24758
|
26
26
|
modal/cls.pyi,sha256=2_nbvSlkh2d0tfibTIxsThPiL0Xcrcosc5f_ET-i0sk,8147
|
27
27
|
modal/config.py,sha256=1KhNJkjYsJkX1V8RPPdRYPlM2HE-ZZs0JVSxbiXjmrw,11010
|
28
|
-
modal/container_process.py,sha256=
|
28
|
+
modal/container_process.py,sha256=YRCKjn56oqTtGjtLxpl_KSkOhYrcRitgF3LOI6o14Q4,5759
|
29
29
|
modal/container_process.pyi,sha256=k2kClwaSzz11eci1pzFZgCm-ptXapHAyHTOENorlazA,2594
|
30
30
|
modal/dict.py,sha256=RmJlEwFJOdSfAYcVa50hbbFccV8e7BvC5tc5g1HXF-c,12622
|
31
31
|
modal/dict.pyi,sha256=2cYgOqBxYZih4BYgMV0c3rNPuxYR6-cB1GBXzFkHA5c,7265
|
@@ -38,8 +38,8 @@ modal/functions.pyi,sha256=fifvDS5GDEYmXjko1UGZrKqmhfnQn6GRwCblM9hrRWo,25107
|
|
38
38
|
modal/gpu.py,sha256=r4rL6uH3UJIQthzYvfWauXNyh01WqCPtKZCmmSX1fd4,6881
|
39
39
|
modal/image.py,sha256=ZIC8tgjJnqWamN4sZ0Gch3x2VmcM671MWfRLR5SMmoc,79423
|
40
40
|
modal/image.pyi,sha256=JjicLNuaBsfuPZ_xo_eN0zKZkDrEm2alYg-szENhJjM,24591
|
41
|
-
modal/io_streams.py,sha256=
|
42
|
-
modal/io_streams.pyi,sha256=
|
41
|
+
modal/io_streams.py,sha256=4pF2HumRK1pVnrx6S9UwGqJn69rQqyQqpe5X_nifny0,14943
|
42
|
+
modal/io_streams.pyi,sha256=An766S3JKP78b2A4RphjdVNR73yblDc5uG_xp5--6k4,4715
|
43
43
|
modal/mount.py,sha256=_N_fd5NX_eWwmb_xh_X_28nNHW9upEDXDyXixZWnUiQ,27730
|
44
44
|
modal/mount.pyi,sha256=3e4nkXUeeVmUmOyK8Tiyk_EQlHeWruN3yGJVnmDUVrI,9761
|
45
45
|
modal/network_file_system.py,sha256=mwtYp25XtFaiGpSG7U0KSkiTzJWrxgGTcoxfPZ9yGR0,14141
|
@@ -60,8 +60,8 @@ modal/retries.py,sha256=HKR2Q9aNPWkMjQ5nwobqYTuZaSuw0a8lI2zrtY5IW98,5230
|
|
60
60
|
modal/runner.py,sha256=7obU-Gq1ocpBGCuR6pvn1T-D6ggg1T48qFo2TNUGWkU,24089
|
61
61
|
modal/runner.pyi,sha256=RAtCvx_lXWjyFjIaZ3t9-X1c7rqpgAQlhl4Hww53OY8,5038
|
62
62
|
modal/running_app.py,sha256=CshNvGDJtagOdKW54uYjY8HY73j2TpnsL9jkPFZAsfA,560
|
63
|
-
modal/sandbox.py,sha256=
|
64
|
-
modal/sandbox.pyi,sha256=
|
63
|
+
modal/sandbox.py,sha256=8cZ7eArLvUeR7bmvb9-XuE08ij-wSd5rbLhspdkAA9Y,25015
|
64
|
+
modal/sandbox.pyi,sha256=4sxZGsRpmXME9wGWWQOLukN0tCezdMSp3pVJWu6fe5g,17502
|
65
65
|
modal/schedule.py,sha256=0ZFpKs1bOxeo5n3HZjoL7OE2ktsb-_oGtq-WJEPO4tY,2615
|
66
66
|
modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
|
67
67
|
modal/secret.py,sha256=Y1WgybQIkfkxdzH9CQ1h-Wd1DJJpzipigMhyyvSxTww,10007
|
@@ -159,10 +159,10 @@ modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0y
|
|
159
159
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
160
160
|
modal_version/__init__.py,sha256=3IY-AWLH55r35_mQXIaut0jrJvoPuf1NZJBQQfSbPuo,470
|
161
161
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
162
|
-
modal_version/_version_generated.py,sha256=
|
163
|
-
modal-0.67.
|
164
|
-
modal-0.67.
|
165
|
-
modal-0.67.
|
166
|
-
modal-0.67.
|
167
|
-
modal-0.67.
|
168
|
-
modal-0.67.
|
162
|
+
modal_version/_version_generated.py,sha256=yW74Sph3leSunGQQCrZcsTL-NaIvPoOH06ZVkpapDHU,149
|
163
|
+
modal-0.67.15.dist-info/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
164
|
+
modal-0.67.15.dist-info/METADATA,sha256=w0WCe3LaidFdAW4u8XBv2gJhK23l0q-q4JPZoFLzGvQ,2329
|
165
|
+
modal-0.67.15.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
|
166
|
+
modal-0.67.15.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
167
|
+
modal-0.67.15.dist-info/top_level.txt,sha256=1nvYbOSIKcmU50fNrpnQnrrOpj269ei3LzgB6j9xGqg,64
|
168
|
+
modal-0.67.15.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|