modal 1.1.1.dev26__py3-none-any.whl → 1.1.1.dev28__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.
Potentially problematic release.
This version of modal might be problematic. Click here for more details.
- modal/_object.py +9 -1
- modal/_output.py +0 -19
- modal/client.pyi +2 -2
- modal/dict.py +45 -2
- modal/dict.pyi +55 -0
- modal/object.pyi +4 -0
- modal/queue.py +44 -2
- modal/queue.pyi +53 -0
- modal/secret.py +44 -2
- modal/secret.pyi +55 -0
- modal/volume.py +48 -18
- modal/volume.pyi +50 -8
- {modal-1.1.1.dev26.dist-info → modal-1.1.1.dev28.dist-info}/METADATA +1 -1
- {modal-1.1.1.dev26.dist-info → modal-1.1.1.dev28.dist-info}/RECORD +19 -19
- modal_version/__init__.py +1 -1
- {modal-1.1.1.dev26.dist-info → modal-1.1.1.dev28.dist-info}/WHEEL +0 -0
- {modal-1.1.1.dev26.dist-info → modal-1.1.1.dev28.dist-info}/entry_points.txt +0 -0
- {modal-1.1.1.dev26.dist-info → modal-1.1.1.dev28.dist-info}/licenses/LICENSE +0 -0
- {modal-1.1.1.dev26.dist-info → modal-1.1.1.dev28.dist-info}/top_level.txt +0 -0
modal/_object.py
CHANGED
|
@@ -48,6 +48,10 @@ class _Object:
|
|
|
48
48
|
_is_hydrated: bool
|
|
49
49
|
_is_rehydrated: bool
|
|
50
50
|
|
|
51
|
+
# Not all object subclasses have a meaningful "name" concept
|
|
52
|
+
# So whether they expose this is a matter of having a name property
|
|
53
|
+
_name: Optional[str]
|
|
54
|
+
|
|
51
55
|
@classmethod
|
|
52
56
|
def __init_subclass__(cls, type_prefix: Optional[str] = None):
|
|
53
57
|
super().__init_subclass__()
|
|
@@ -68,6 +72,7 @@ class _Object:
|
|
|
68
72
|
hydrate_lazily: bool = False,
|
|
69
73
|
deps: Optional[Callable[..., Sequence["_Object"]]] = None,
|
|
70
74
|
deduplication_key: Optional[Callable[[], Awaitable[Hashable]]] = None,
|
|
75
|
+
name: Optional[str] = None,
|
|
71
76
|
):
|
|
72
77
|
self._local_uuid = str(uuid.uuid4())
|
|
73
78
|
self._load = load
|
|
@@ -83,6 +88,8 @@ class _Object:
|
|
|
83
88
|
self._is_hydrated = False
|
|
84
89
|
self._is_rehydrated = False
|
|
85
90
|
|
|
91
|
+
self._name = name
|
|
92
|
+
|
|
86
93
|
self._initialize_from_empty()
|
|
87
94
|
|
|
88
95
|
def _unhydrate(self):
|
|
@@ -163,10 +170,11 @@ class _Object:
|
|
|
163
170
|
hydrate_lazily: bool = False,
|
|
164
171
|
deps: Optional[Callable[..., Sequence["_Object"]]] = None,
|
|
165
172
|
deduplication_key: Optional[Callable[[], Awaitable[Hashable]]] = None,
|
|
173
|
+
name: Optional[str] = None,
|
|
166
174
|
):
|
|
167
175
|
# TODO(erikbern): flip the order of the two first arguments
|
|
168
176
|
obj = _Object.__new__(cls)
|
|
169
|
-
obj._init(rep, load, is_another_app, preload, hydrate_lazily, deps, deduplication_key)
|
|
177
|
+
obj._init(rep, load, is_another_app, preload, hydrate_lazily, deps, deduplication_key, name)
|
|
170
178
|
return obj
|
|
171
179
|
|
|
172
180
|
@staticmethod
|
modal/_output.py
CHANGED
|
@@ -72,25 +72,6 @@ class FunctionQueuingColumn(ProgressColumn):
|
|
|
72
72
|
return Text(str(delta), style="progress.elapsed")
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
def download_progress_bar() -> Progress:
|
|
76
|
-
"""
|
|
77
|
-
Returns a progress bar suitable for showing file download progress.
|
|
78
|
-
Requires passing a `path: str` data field for rendering.
|
|
79
|
-
"""
|
|
80
|
-
return Progress(
|
|
81
|
-
TextColumn("[bold white]{task.fields[path]}", justify="right"),
|
|
82
|
-
BarColumn(bar_width=None),
|
|
83
|
-
"[progress.percentage]{task.percentage:>3.1f}%",
|
|
84
|
-
"•",
|
|
85
|
-
DownloadColumn(),
|
|
86
|
-
"•",
|
|
87
|
-
TransferSpeedColumn(),
|
|
88
|
-
"•",
|
|
89
|
-
TimeRemainingColumn(),
|
|
90
|
-
transient=True,
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
|
|
94
75
|
class LineBufferedOutput:
|
|
95
76
|
"""Output stream that buffers lines and passes them to a callback."""
|
|
96
77
|
|
modal/client.pyi
CHANGED
|
@@ -33,7 +33,7 @@ class _Client:
|
|
|
33
33
|
server_url: str,
|
|
34
34
|
client_type: int,
|
|
35
35
|
credentials: typing.Optional[tuple[str, str]],
|
|
36
|
-
version: str = "1.1.1.
|
|
36
|
+
version: str = "1.1.1.dev28",
|
|
37
37
|
):
|
|
38
38
|
"""mdmd:hidden
|
|
39
39
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -164,7 +164,7 @@ class Client:
|
|
|
164
164
|
server_url: str,
|
|
165
165
|
client_type: int,
|
|
166
166
|
credentials: typing.Optional[tuple[str, str]],
|
|
167
|
-
version: str = "1.1.1.
|
|
167
|
+
version: str = "1.1.1.dev28",
|
|
168
168
|
):
|
|
169
169
|
"""mdmd:hidden
|
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
modal/dict.py
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
# Copyright Modal Labs 2022
|
|
2
2
|
from collections.abc import AsyncIterator, Mapping
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
3
5
|
from typing import Any, Optional
|
|
4
6
|
|
|
7
|
+
from google.protobuf.message import Message
|
|
5
8
|
from grpclib import GRPCError
|
|
6
9
|
from synchronicity.async_wrap import asynccontextmanager
|
|
7
10
|
|
|
@@ -23,6 +26,18 @@ def _serialize_dict(data):
|
|
|
23
26
|
return [api_pb2.DictEntry(key=serialize(k), value=serialize(v)) for k, v in data.items()]
|
|
24
27
|
|
|
25
28
|
|
|
29
|
+
@dataclass
|
|
30
|
+
class DictInfo:
|
|
31
|
+
"""Information about the Dict object."""
|
|
32
|
+
|
|
33
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Dict,
|
|
34
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
35
|
+
|
|
36
|
+
name: Optional[str]
|
|
37
|
+
created_at: datetime
|
|
38
|
+
created_by: Optional[str]
|
|
39
|
+
|
|
40
|
+
|
|
26
41
|
class _Dict(_Object, type_prefix="di"):
|
|
27
42
|
"""Distributed dictionary for storage in Modal apps.
|
|
28
43
|
|
|
@@ -65,12 +80,29 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
65
80
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
66
81
|
"""
|
|
67
82
|
|
|
83
|
+
_name: Optional[str] = None
|
|
84
|
+
_metadata: Optional[api_pb2.DictMetadata] = None
|
|
85
|
+
|
|
68
86
|
def __init__(self, data={}):
|
|
69
87
|
"""mdmd:hidden"""
|
|
70
88
|
raise RuntimeError(
|
|
71
89
|
"`Dict(...)` constructor is not allowed. Please use `Dict.from_name` or `Dict.ephemeral` instead"
|
|
72
90
|
)
|
|
73
91
|
|
|
92
|
+
@property
|
|
93
|
+
def name(self) -> Optional[str]:
|
|
94
|
+
return self._name
|
|
95
|
+
|
|
96
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
97
|
+
if metadata:
|
|
98
|
+
assert isinstance(metadata, api_pb2.DictMetadata)
|
|
99
|
+
self._metadata = metadata
|
|
100
|
+
self._name = metadata.name
|
|
101
|
+
|
|
102
|
+
def _get_metadata(self) -> api_pb2.DictMetadata:
|
|
103
|
+
assert self._metadata
|
|
104
|
+
return self._metadata
|
|
105
|
+
|
|
74
106
|
@classmethod
|
|
75
107
|
@asynccontextmanager
|
|
76
108
|
async def ephemeral(
|
|
@@ -112,7 +144,7 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
112
144
|
async with TaskContext() as tc:
|
|
113
145
|
request = api_pb2.DictHeartbeatRequest(dict_id=response.dict_id)
|
|
114
146
|
tc.infinite_loop(lambda: client.stub.DictHeartbeat(request), sleep=_heartbeat_sleep)
|
|
115
|
-
yield cls._new_hydrated(response.dict_id, client,
|
|
147
|
+
yield cls._new_hydrated(response.dict_id, client, response.metadata, is_another_app=True)
|
|
116
148
|
|
|
117
149
|
@staticmethod
|
|
118
150
|
def from_name(
|
|
@@ -155,7 +187,7 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
155
187
|
logger.debug(f"Created dict with id {response.dict_id}")
|
|
156
188
|
self._hydrate(response.dict_id, resolver.client, response.metadata)
|
|
157
189
|
|
|
158
|
-
return _Dict._from_loader(_load, "Dict()", is_another_app=True, hydrate_lazily=True)
|
|
190
|
+
return _Dict._from_loader(_load, "Dict()", is_another_app=True, hydrate_lazily=True, name=name)
|
|
159
191
|
|
|
160
192
|
@staticmethod
|
|
161
193
|
async def lookup(
|
|
@@ -209,6 +241,17 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
209
241
|
req = api_pb2.DictDeleteRequest(dict_id=obj.object_id)
|
|
210
242
|
await retry_transient_errors(obj._client.stub.DictDelete, req)
|
|
211
243
|
|
|
244
|
+
@live_method
|
|
245
|
+
async def info(self) -> DictInfo:
|
|
246
|
+
"""Return information about the Dict object."""
|
|
247
|
+
metadata = self._get_metadata()
|
|
248
|
+
creation_info = metadata.creation_info
|
|
249
|
+
return DictInfo(
|
|
250
|
+
name=metadata.name or None,
|
|
251
|
+
created_at=datetime.fromtimestamp(creation_info.created_at),
|
|
252
|
+
created_by=creation_info.created_by or None,
|
|
253
|
+
)
|
|
254
|
+
|
|
212
255
|
@live_method
|
|
213
256
|
async def clear(self) -> None:
|
|
214
257
|
"""Remove all items from the Dict."""
|
modal/dict.pyi
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
+
import datetime
|
|
3
|
+
import google.protobuf.message
|
|
2
4
|
import modal._object
|
|
3
5
|
import modal.client
|
|
4
6
|
import modal.object
|
|
7
|
+
import modal_proto.api_pb2
|
|
5
8
|
import synchronicity.combined_types
|
|
6
9
|
import typing
|
|
7
10
|
import typing_extensions
|
|
8
11
|
|
|
9
12
|
def _serialize_dict(data): ...
|
|
10
13
|
|
|
14
|
+
class DictInfo:
|
|
15
|
+
"""Information about the Dict object."""
|
|
16
|
+
|
|
17
|
+
name: typing.Optional[str]
|
|
18
|
+
created_at: datetime.datetime
|
|
19
|
+
created_by: typing.Optional[str]
|
|
20
|
+
|
|
21
|
+
def __init__(
|
|
22
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
23
|
+
) -> None:
|
|
24
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
def __repr__(self):
|
|
28
|
+
"""Return repr(self)."""
|
|
29
|
+
...
|
|
30
|
+
|
|
31
|
+
def __eq__(self, other):
|
|
32
|
+
"""Return self==value."""
|
|
33
|
+
...
|
|
34
|
+
|
|
11
35
|
class _Dict(modal._object._Object):
|
|
12
36
|
"""Distributed dictionary for storage in Modal apps.
|
|
13
37
|
|
|
@@ -49,10 +73,18 @@ class _Dict(modal._object._Object):
|
|
|
49
73
|
|
|
50
74
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
51
75
|
"""
|
|
76
|
+
|
|
77
|
+
_name: typing.Optional[str]
|
|
78
|
+
_metadata: typing.Optional[modal_proto.api_pb2.DictMetadata]
|
|
79
|
+
|
|
52
80
|
def __init__(self, data={}):
|
|
53
81
|
"""mdmd:hidden"""
|
|
54
82
|
...
|
|
55
83
|
|
|
84
|
+
@property
|
|
85
|
+
def name(self) -> typing.Optional[str]: ...
|
|
86
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
87
|
+
def _get_metadata(self) -> modal_proto.api_pb2.DictMetadata: ...
|
|
56
88
|
@classmethod
|
|
57
89
|
def ephemeral(
|
|
58
90
|
cls: type[_Dict],
|
|
@@ -131,6 +163,10 @@ class _Dict(modal._object._Object):
|
|
|
131
163
|
client: typing.Optional[modal.client._Client] = None,
|
|
132
164
|
environment_name: typing.Optional[str] = None,
|
|
133
165
|
): ...
|
|
166
|
+
async def info(self) -> DictInfo:
|
|
167
|
+
"""Return information about the Dict object."""
|
|
168
|
+
...
|
|
169
|
+
|
|
134
170
|
async def clear(self) -> None:
|
|
135
171
|
"""Remove all items from the Dict."""
|
|
136
172
|
...
|
|
@@ -264,10 +300,18 @@ class Dict(modal.object.Object):
|
|
|
264
300
|
|
|
265
301
|
For more examples, see the [guide](https://modal.com/docs/guide/dicts-and-queues#modal-dicts).
|
|
266
302
|
"""
|
|
303
|
+
|
|
304
|
+
_name: typing.Optional[str]
|
|
305
|
+
_metadata: typing.Optional[modal_proto.api_pb2.DictMetadata]
|
|
306
|
+
|
|
267
307
|
def __init__(self, data={}):
|
|
268
308
|
"""mdmd:hidden"""
|
|
269
309
|
...
|
|
270
310
|
|
|
311
|
+
@property
|
|
312
|
+
def name(self) -> typing.Optional[str]: ...
|
|
313
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
314
|
+
def _get_metadata(self) -> modal_proto.api_pb2.DictMetadata: ...
|
|
271
315
|
@classmethod
|
|
272
316
|
def ephemeral(
|
|
273
317
|
cls: type[Dict],
|
|
@@ -388,6 +432,17 @@ class Dict(modal.object.Object):
|
|
|
388
432
|
|
|
389
433
|
delete: __delete_spec
|
|
390
434
|
|
|
435
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
436
|
+
def __call__(self, /) -> DictInfo:
|
|
437
|
+
"""Return information about the Dict object."""
|
|
438
|
+
...
|
|
439
|
+
|
|
440
|
+
async def aio(self, /) -> DictInfo:
|
|
441
|
+
"""Return information about the Dict object."""
|
|
442
|
+
...
|
|
443
|
+
|
|
444
|
+
info: __info_spec[typing_extensions.Self]
|
|
445
|
+
|
|
391
446
|
class __clear_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
392
447
|
def __call__(self, /) -> None:
|
|
393
448
|
"""Remove all items from the Dict."""
|
modal/object.pyi
CHANGED
|
@@ -31,6 +31,7 @@ class Object:
|
|
|
31
31
|
_client: typing.Optional[modal.client.Client]
|
|
32
32
|
_is_hydrated: bool
|
|
33
33
|
_is_rehydrated: bool
|
|
34
|
+
_name: typing.Optional[str]
|
|
34
35
|
|
|
35
36
|
def __init__(self, *args, **kwargs):
|
|
36
37
|
"""mdmd:hidden"""
|
|
@@ -54,6 +55,7 @@ class Object:
|
|
|
54
55
|
hydrate_lazily: bool = False,
|
|
55
56
|
deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
|
|
56
57
|
deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
|
|
58
|
+
name: typing.Optional[str] = None,
|
|
57
59
|
): ...
|
|
58
60
|
def aio(
|
|
59
61
|
self,
|
|
@@ -75,6 +77,7 @@ class Object:
|
|
|
75
77
|
deduplication_key: typing.Optional[
|
|
76
78
|
collections.abc.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
|
77
79
|
] = None,
|
|
80
|
+
name: typing.Optional[str] = None,
|
|
78
81
|
): ...
|
|
79
82
|
|
|
80
83
|
_init: ___init_spec[typing_extensions.Self]
|
|
@@ -107,6 +110,7 @@ class Object:
|
|
|
107
110
|
hydrate_lazily: bool = False,
|
|
108
111
|
deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
|
|
109
112
|
deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
|
|
113
|
+
name: typing.Optional[str] = None,
|
|
110
114
|
): ...
|
|
111
115
|
@staticmethod
|
|
112
116
|
def _get_type_from_id(object_id: str) -> type[Object]: ...
|
modal/queue.py
CHANGED
|
@@ -3,8 +3,11 @@ import queue # The system library
|
|
|
3
3
|
import time
|
|
4
4
|
import warnings
|
|
5
5
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from datetime import datetime
|
|
6
8
|
from typing import Any, Optional
|
|
7
9
|
|
|
10
|
+
from google.protobuf.message import Message
|
|
8
11
|
from grpclib import GRPCError, Status
|
|
9
12
|
from synchronicity.async_wrap import asynccontextmanager
|
|
10
13
|
|
|
@@ -21,6 +24,18 @@ from .client import _Client
|
|
|
21
24
|
from .exception import InvalidError, RequestSizeError
|
|
22
25
|
|
|
23
26
|
|
|
27
|
+
@dataclass
|
|
28
|
+
class QueueInfo:
|
|
29
|
+
"""Information about the Queue object."""
|
|
30
|
+
|
|
31
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Queue,
|
|
32
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
33
|
+
|
|
34
|
+
name: Optional[str]
|
|
35
|
+
created_at: datetime
|
|
36
|
+
created_by: Optional[str]
|
|
37
|
+
|
|
38
|
+
|
|
24
39
|
class _Queue(_Object, type_prefix="qu"):
|
|
25
40
|
"""Distributed, FIFO queue for data flow in Modal apps.
|
|
26
41
|
|
|
@@ -94,10 +109,26 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
94
109
|
Partition keys must be non-empty and must not exceed 64 bytes.
|
|
95
110
|
"""
|
|
96
111
|
|
|
112
|
+
_metadata: Optional[api_pb2.QueueMetadata] = None
|
|
113
|
+
|
|
97
114
|
def __init__(self):
|
|
98
115
|
"""mdmd:hidden"""
|
|
99
116
|
raise RuntimeError("Queue() is not allowed. Please use `Queue.from_name(...)` or `Queue.ephemeral()` instead.")
|
|
100
117
|
|
|
118
|
+
@property
|
|
119
|
+
def name(self) -> Optional[str]:
|
|
120
|
+
return self._name
|
|
121
|
+
|
|
122
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
123
|
+
if metadata:
|
|
124
|
+
assert isinstance(metadata, api_pb2.QueueMetadata)
|
|
125
|
+
self._metadata = metadata
|
|
126
|
+
self._name = metadata.name
|
|
127
|
+
|
|
128
|
+
def _get_metadata(self) -> api_pb2.QueueMetadata:
|
|
129
|
+
assert self._metadata
|
|
130
|
+
return self._metadata
|
|
131
|
+
|
|
101
132
|
@staticmethod
|
|
102
133
|
def validate_partition_key(partition: Optional[str]) -> bytes:
|
|
103
134
|
if partition is not None:
|
|
@@ -142,7 +173,7 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
142
173
|
async with TaskContext() as tc:
|
|
143
174
|
request = api_pb2.QueueHeartbeatRequest(queue_id=response.queue_id)
|
|
144
175
|
tc.infinite_loop(lambda: client.stub.QueueHeartbeat(request), sleep=_heartbeat_sleep)
|
|
145
|
-
yield cls._new_hydrated(response.queue_id, client,
|
|
176
|
+
yield cls._new_hydrated(response.queue_id, client, response.metadata, is_another_app=True)
|
|
146
177
|
|
|
147
178
|
@staticmethod
|
|
148
179
|
def from_name(
|
|
@@ -175,7 +206,7 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
175
206
|
response = await resolver.client.stub.QueueGetOrCreate(req)
|
|
176
207
|
self._hydrate(response.queue_id, resolver.client, response.metadata)
|
|
177
208
|
|
|
178
|
-
return _Queue._from_loader(_load, "Queue()", is_another_app=True, hydrate_lazily=True)
|
|
209
|
+
return _Queue._from_loader(_load, "Queue()", is_another_app=True, hydrate_lazily=True, name=name)
|
|
179
210
|
|
|
180
211
|
@staticmethod
|
|
181
212
|
async def lookup(
|
|
@@ -222,6 +253,17 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
222
253
|
req = api_pb2.QueueDeleteRequest(queue_id=obj.object_id)
|
|
223
254
|
await retry_transient_errors(obj._client.stub.QueueDelete, req)
|
|
224
255
|
|
|
256
|
+
@live_method
|
|
257
|
+
async def info(self) -> QueueInfo:
|
|
258
|
+
"""Return information about the Queue object."""
|
|
259
|
+
metadata = self._get_metadata()
|
|
260
|
+
creation_info = metadata.creation_info
|
|
261
|
+
return QueueInfo(
|
|
262
|
+
name=metadata.name or None,
|
|
263
|
+
created_at=datetime.fromtimestamp(creation_info.created_at),
|
|
264
|
+
created_by=creation_info.created_by or None,
|
|
265
|
+
)
|
|
266
|
+
|
|
225
267
|
async def _get_nonblocking(self, partition: Optional[str], n_values: int) -> list[Any]:
|
|
226
268
|
request = api_pb2.QueueGetRequest(
|
|
227
269
|
queue_id=self.object_id,
|
modal/queue.pyi
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import collections.abc
|
|
2
|
+
import datetime
|
|
3
|
+
import google.protobuf.message
|
|
2
4
|
import modal._object
|
|
3
5
|
import modal.client
|
|
4
6
|
import modal.object
|
|
7
|
+
import modal_proto.api_pb2
|
|
5
8
|
import synchronicity.combined_types
|
|
6
9
|
import typing
|
|
7
10
|
import typing_extensions
|
|
8
11
|
|
|
12
|
+
class QueueInfo:
|
|
13
|
+
"""Information about the Queue object."""
|
|
14
|
+
|
|
15
|
+
name: typing.Optional[str]
|
|
16
|
+
created_at: datetime.datetime
|
|
17
|
+
created_by: typing.Optional[str]
|
|
18
|
+
|
|
19
|
+
def __init__(
|
|
20
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
21
|
+
) -> None:
|
|
22
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
23
|
+
...
|
|
24
|
+
|
|
25
|
+
def __repr__(self):
|
|
26
|
+
"""Return repr(self)."""
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
def __eq__(self, other):
|
|
30
|
+
"""Return self==value."""
|
|
31
|
+
...
|
|
32
|
+
|
|
9
33
|
class _Queue(modal._object._Object):
|
|
10
34
|
"""Distributed, FIFO queue for data flow in Modal apps.
|
|
11
35
|
|
|
@@ -78,10 +102,17 @@ class _Queue(modal._object._Object):
|
|
|
78
102
|
|
|
79
103
|
Partition keys must be non-empty and must not exceed 64 bytes.
|
|
80
104
|
"""
|
|
105
|
+
|
|
106
|
+
_metadata: typing.Optional[modal_proto.api_pb2.QueueMetadata]
|
|
107
|
+
|
|
81
108
|
def __init__(self):
|
|
82
109
|
"""mdmd:hidden"""
|
|
83
110
|
...
|
|
84
111
|
|
|
112
|
+
@property
|
|
113
|
+
def name(self) -> typing.Optional[str]: ...
|
|
114
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
115
|
+
def _get_metadata(self) -> modal_proto.api_pb2.QueueMetadata: ...
|
|
85
116
|
@staticmethod
|
|
86
117
|
def validate_partition_key(partition: typing.Optional[str]) -> bytes: ...
|
|
87
118
|
@classmethod
|
|
@@ -155,6 +186,10 @@ class _Queue(modal._object._Object):
|
|
|
155
186
|
client: typing.Optional[modal.client._Client] = None,
|
|
156
187
|
environment_name: typing.Optional[str] = None,
|
|
157
188
|
): ...
|
|
189
|
+
async def info(self) -> QueueInfo:
|
|
190
|
+
"""Return information about the Queue object."""
|
|
191
|
+
...
|
|
192
|
+
|
|
158
193
|
async def _get_nonblocking(self, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
|
159
194
|
async def _get_blocking(
|
|
160
195
|
self, partition: typing.Optional[str], timeout: typing.Optional[float], n_values: int
|
|
@@ -335,10 +370,17 @@ class Queue(modal.object.Object):
|
|
|
335
370
|
|
|
336
371
|
Partition keys must be non-empty and must not exceed 64 bytes.
|
|
337
372
|
"""
|
|
373
|
+
|
|
374
|
+
_metadata: typing.Optional[modal_proto.api_pb2.QueueMetadata]
|
|
375
|
+
|
|
338
376
|
def __init__(self):
|
|
339
377
|
"""mdmd:hidden"""
|
|
340
378
|
...
|
|
341
379
|
|
|
380
|
+
@property
|
|
381
|
+
def name(self) -> typing.Optional[str]: ...
|
|
382
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
383
|
+
def _get_metadata(self) -> modal_proto.api_pb2.QueueMetadata: ...
|
|
342
384
|
@staticmethod
|
|
343
385
|
def validate_partition_key(partition: typing.Optional[str]) -> bytes: ...
|
|
344
386
|
@classmethod
|
|
@@ -453,6 +495,17 @@ class Queue(modal.object.Object):
|
|
|
453
495
|
|
|
454
496
|
delete: __delete_spec
|
|
455
497
|
|
|
498
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
499
|
+
def __call__(self, /) -> QueueInfo:
|
|
500
|
+
"""Return information about the Queue object."""
|
|
501
|
+
...
|
|
502
|
+
|
|
503
|
+
async def aio(self, /) -> QueueInfo:
|
|
504
|
+
"""Return information about the Queue object."""
|
|
505
|
+
...
|
|
506
|
+
|
|
507
|
+
info: __info_spec[typing_extensions.Self]
|
|
508
|
+
|
|
456
509
|
class ___get_nonblocking_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
457
510
|
def __call__(self, /, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
|
458
511
|
async def aio(self, /, partition: typing.Optional[str], n_values: int) -> list[typing.Any]: ...
|
modal/secret.py
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
# Copyright Modal Labs 2022
|
|
2
2
|
import os
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from datetime import datetime
|
|
3
5
|
from typing import Optional, Union
|
|
4
6
|
|
|
7
|
+
from google.protobuf.message import Message
|
|
5
8
|
from grpclib import GRPCError, Status
|
|
6
9
|
|
|
7
10
|
from modal_proto import api_pb2
|
|
8
11
|
|
|
9
|
-
from ._object import _get_environment_name, _Object
|
|
12
|
+
from ._object import _get_environment_name, _Object, live_method
|
|
10
13
|
from ._resolver import Resolver
|
|
11
14
|
from ._runtime.execution_context import is_local
|
|
12
15
|
from ._utils.async_utils import synchronize_api
|
|
@@ -19,6 +22,18 @@ from .exception import InvalidError, NotFoundError
|
|
|
19
22
|
ENV_DICT_WRONG_TYPE_ERR = "the env_dict argument to Secret has to be a dict[str, Union[str, None]]"
|
|
20
23
|
|
|
21
24
|
|
|
25
|
+
@dataclass
|
|
26
|
+
class SecretInfo:
|
|
27
|
+
"""Information about the Secret object."""
|
|
28
|
+
|
|
29
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Secret,
|
|
30
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
31
|
+
|
|
32
|
+
name: Optional[str]
|
|
33
|
+
created_at: datetime
|
|
34
|
+
created_by: Optional[str]
|
|
35
|
+
|
|
36
|
+
|
|
22
37
|
class _Secret(_Object, type_prefix="st"):
|
|
23
38
|
"""Secrets provide a dictionary of environment variables for images.
|
|
24
39
|
|
|
@@ -29,6 +44,22 @@ class _Secret(_Object, type_prefix="st"):
|
|
|
29
44
|
See [the secrets guide page](https://modal.com/docs/guide/secrets) for more information.
|
|
30
45
|
"""
|
|
31
46
|
|
|
47
|
+
_metadata: Optional[api_pb2.SecretMetadata] = None
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def name(self) -> Optional[str]:
|
|
51
|
+
return self._name
|
|
52
|
+
|
|
53
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
54
|
+
if metadata:
|
|
55
|
+
assert isinstance(metadata, api_pb2.SecretMetadata)
|
|
56
|
+
self._metadata = metadata
|
|
57
|
+
self._name = metadata.name
|
|
58
|
+
|
|
59
|
+
def _get_metadata(self) -> api_pb2.SecretMetadata:
|
|
60
|
+
assert self._metadata
|
|
61
|
+
return self._metadata
|
|
62
|
+
|
|
32
63
|
@staticmethod
|
|
33
64
|
def from_dict(
|
|
34
65
|
env_dict: dict[
|
|
@@ -202,7 +233,7 @@ class _Secret(_Object, type_prefix="st"):
|
|
|
202
233
|
raise
|
|
203
234
|
self._hydrate(response.secret_id, resolver.client, response.metadata)
|
|
204
235
|
|
|
205
|
-
return _Secret._from_loader(_load, "Secret()", hydrate_lazily=True)
|
|
236
|
+
return _Secret._from_loader(_load, "Secret()", hydrate_lazily=True, name=name)
|
|
206
237
|
|
|
207
238
|
@staticmethod
|
|
208
239
|
async def lookup(
|
|
@@ -261,5 +292,16 @@ class _Secret(_Object, type_prefix="st"):
|
|
|
261
292
|
resp = await retry_transient_errors(client.stub.SecretGetOrCreate, request)
|
|
262
293
|
return resp.secret_id
|
|
263
294
|
|
|
295
|
+
@live_method
|
|
296
|
+
async def info(self) -> SecretInfo:
|
|
297
|
+
"""Return information about the Secret object."""
|
|
298
|
+
metadata = self._get_metadata()
|
|
299
|
+
creation_info = metadata.creation_info
|
|
300
|
+
return SecretInfo(
|
|
301
|
+
name=metadata.name or None,
|
|
302
|
+
created_at=datetime.fromtimestamp(creation_info.created_at),
|
|
303
|
+
created_by=creation_info.created_by or None,
|
|
304
|
+
)
|
|
305
|
+
|
|
264
306
|
|
|
265
307
|
Secret = synchronize_api(_Secret)
|
modal/secret.pyi
CHANGED
|
@@ -1,9 +1,33 @@
|
|
|
1
|
+
import datetime
|
|
2
|
+
import google.protobuf.message
|
|
1
3
|
import modal._object
|
|
2
4
|
import modal.client
|
|
3
5
|
import modal.object
|
|
6
|
+
import modal_proto.api_pb2
|
|
4
7
|
import typing
|
|
5
8
|
import typing_extensions
|
|
6
9
|
|
|
10
|
+
class SecretInfo:
|
|
11
|
+
"""Information about the Secret object."""
|
|
12
|
+
|
|
13
|
+
name: typing.Optional[str]
|
|
14
|
+
created_at: datetime.datetime
|
|
15
|
+
created_by: typing.Optional[str]
|
|
16
|
+
|
|
17
|
+
def __init__(
|
|
18
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
19
|
+
) -> None:
|
|
20
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
21
|
+
...
|
|
22
|
+
|
|
23
|
+
def __repr__(self):
|
|
24
|
+
"""Return repr(self)."""
|
|
25
|
+
...
|
|
26
|
+
|
|
27
|
+
def __eq__(self, other):
|
|
28
|
+
"""Return self==value."""
|
|
29
|
+
...
|
|
30
|
+
|
|
7
31
|
class _Secret(modal._object._Object):
|
|
8
32
|
"""Secrets provide a dictionary of environment variables for images.
|
|
9
33
|
|
|
@@ -13,6 +37,13 @@ class _Secret(modal._object._Object):
|
|
|
13
37
|
|
|
14
38
|
See [the secrets guide page](https://modal.com/docs/guide/secrets) for more information.
|
|
15
39
|
"""
|
|
40
|
+
|
|
41
|
+
_metadata: typing.Optional[modal_proto.api_pb2.SecretMetadata]
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def name(self) -> typing.Optional[str]: ...
|
|
45
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
46
|
+
def _get_metadata(self) -> modal_proto.api_pb2.SecretMetadata: ...
|
|
16
47
|
@staticmethod
|
|
17
48
|
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}) -> _Secret:
|
|
18
49
|
"""Create a secret from a str-str dictionary. Values can also be `None`, which is ignored.
|
|
@@ -104,6 +135,12 @@ class _Secret(modal._object._Object):
|
|
|
104
135
|
"""mdmd:hidden"""
|
|
105
136
|
...
|
|
106
137
|
|
|
138
|
+
async def info(self) -> SecretInfo:
|
|
139
|
+
"""Return information about the Secret object."""
|
|
140
|
+
...
|
|
141
|
+
|
|
142
|
+
SUPERSELF = typing.TypeVar("SUPERSELF", covariant=True)
|
|
143
|
+
|
|
107
144
|
class Secret(modal.object.Object):
|
|
108
145
|
"""Secrets provide a dictionary of environment variables for images.
|
|
109
146
|
|
|
@@ -113,10 +150,17 @@ class Secret(modal.object.Object):
|
|
|
113
150
|
|
|
114
151
|
See [the secrets guide page](https://modal.com/docs/guide/secrets) for more information.
|
|
115
152
|
"""
|
|
153
|
+
|
|
154
|
+
_metadata: typing.Optional[modal_proto.api_pb2.SecretMetadata]
|
|
155
|
+
|
|
116
156
|
def __init__(self, *args, **kwargs):
|
|
117
157
|
"""mdmd:hidden"""
|
|
118
158
|
...
|
|
119
159
|
|
|
160
|
+
@property
|
|
161
|
+
def name(self) -> typing.Optional[str]: ...
|
|
162
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
163
|
+
def _get_metadata(self) -> modal_proto.api_pb2.SecretMetadata: ...
|
|
120
164
|
@staticmethod
|
|
121
165
|
def from_dict(env_dict: dict[str, typing.Optional[str]] = {}) -> Secret:
|
|
122
166
|
"""Create a secret from a str-str dictionary. Values can also be `None`, which is ignored.
|
|
@@ -240,3 +284,14 @@ class Secret(modal.object.Object):
|
|
|
240
284
|
...
|
|
241
285
|
|
|
242
286
|
create_deployed: __create_deployed_spec
|
|
287
|
+
|
|
288
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
289
|
+
def __call__(self, /) -> SecretInfo:
|
|
290
|
+
"""Return information about the Secret object."""
|
|
291
|
+
...
|
|
292
|
+
|
|
293
|
+
async def aio(self, /) -> SecretInfo:
|
|
294
|
+
"""Return information about the Secret object."""
|
|
295
|
+
...
|
|
296
|
+
|
|
297
|
+
info: __info_spec[typing_extensions.Self]
|
modal/volume.py
CHANGED
|
@@ -11,6 +11,7 @@ import time
|
|
|
11
11
|
import typing
|
|
12
12
|
from collections.abc import AsyncGenerator, AsyncIterator, Generator, Sequence
|
|
13
13
|
from dataclasses import dataclass
|
|
14
|
+
from datetime import datetime
|
|
14
15
|
from io import BytesIO
|
|
15
16
|
from pathlib import Path, PurePosixPath
|
|
16
17
|
from typing import (
|
|
@@ -92,6 +93,18 @@ class FileEntry:
|
|
|
92
93
|
)
|
|
93
94
|
|
|
94
95
|
|
|
96
|
+
@dataclass
|
|
97
|
+
class VolumeInfo:
|
|
98
|
+
"""Information about the Volume object."""
|
|
99
|
+
|
|
100
|
+
# This dataclass should be limited to information that is unchanging over the lifetime of the Volume,
|
|
101
|
+
# since it is transmitted from the server when the object is hydrated and could be stale when accessed.
|
|
102
|
+
|
|
103
|
+
name: Optional[str]
|
|
104
|
+
created_at: datetime
|
|
105
|
+
created_by: Optional[str]
|
|
106
|
+
|
|
107
|
+
|
|
95
108
|
class _Volume(_Object, type_prefix="vo"):
|
|
96
109
|
"""A writeable volume that can be used to share files between one or more Modal functions.
|
|
97
110
|
|
|
@@ -167,6 +180,19 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
167
180
|
obj = _Volume._from_loader(_load, "Volume()", hydrate_lazily=True, deps=lambda: [self])
|
|
168
181
|
return obj
|
|
169
182
|
|
|
183
|
+
@property
|
|
184
|
+
def name(self) -> Optional[str]:
|
|
185
|
+
return self._name
|
|
186
|
+
|
|
187
|
+
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
188
|
+
if metadata:
|
|
189
|
+
assert isinstance(metadata, api_pb2.VolumeMetadata)
|
|
190
|
+
self._metadata = metadata
|
|
191
|
+
self._name = metadata.name
|
|
192
|
+
|
|
193
|
+
def _get_metadata(self) -> Optional[Message]:
|
|
194
|
+
return self._metadata
|
|
195
|
+
|
|
170
196
|
async def _get_lock(self):
|
|
171
197
|
# To (mostly*) prevent multiple concurrent operations on the same volume, which can cause problems under
|
|
172
198
|
# some unlikely circumstances.
|
|
@@ -181,6 +207,14 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
181
207
|
self._lock = asyncio.Lock()
|
|
182
208
|
return self._lock
|
|
183
209
|
|
|
210
|
+
@property
|
|
211
|
+
def _is_v1(self) -> bool:
|
|
212
|
+
return self._metadata.version in [
|
|
213
|
+
None,
|
|
214
|
+
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_UNSPECIFIED,
|
|
215
|
+
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V1,
|
|
216
|
+
]
|
|
217
|
+
|
|
184
218
|
@staticmethod
|
|
185
219
|
def from_name(
|
|
186
220
|
name: str,
|
|
@@ -220,24 +254,7 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
220
254
|
response = await resolver.client.stub.VolumeGetOrCreate(req)
|
|
221
255
|
self._hydrate(response.volume_id, resolver.client, response.metadata)
|
|
222
256
|
|
|
223
|
-
return _Volume._from_loader(_load, "Volume()", hydrate_lazily=True)
|
|
224
|
-
|
|
225
|
-
def _hydrate_metadata(self, metadata: Optional[Message]):
|
|
226
|
-
if metadata and isinstance(metadata, api_pb2.VolumeMetadata):
|
|
227
|
-
self._metadata = metadata
|
|
228
|
-
else:
|
|
229
|
-
raise TypeError("_hydrate_metadata() requires an `api_pb2.VolumeMetadata` to determine volume version")
|
|
230
|
-
|
|
231
|
-
def _get_metadata(self) -> Optional[Message]:
|
|
232
|
-
return self._metadata
|
|
233
|
-
|
|
234
|
-
@property
|
|
235
|
-
def _is_v1(self) -> bool:
|
|
236
|
-
return self._metadata.version in [
|
|
237
|
-
None,
|
|
238
|
-
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_UNSPECIFIED,
|
|
239
|
-
api_pb2.VolumeFsVersion.VOLUME_FS_VERSION_V1,
|
|
240
|
-
]
|
|
257
|
+
return _Volume._from_loader(_load, "Volume()", hydrate_lazily=True, name=name)
|
|
241
258
|
|
|
242
259
|
@classmethod
|
|
243
260
|
@asynccontextmanager
|
|
@@ -338,6 +355,19 @@ class _Volume(_Object, type_prefix="vo"):
|
|
|
338
355
|
resp = await retry_transient_errors(client.stub.VolumeGetOrCreate, request)
|
|
339
356
|
return resp.volume_id
|
|
340
357
|
|
|
358
|
+
@live_method
|
|
359
|
+
async def info(self) -> VolumeInfo:
|
|
360
|
+
"""Return information about the Volume object."""
|
|
361
|
+
metadata = self._get_metadata()
|
|
362
|
+
if not metadata:
|
|
363
|
+
return VolumeInfo()
|
|
364
|
+
creation_info = metadata.creation_info
|
|
365
|
+
return VolumeInfo(
|
|
366
|
+
name=metadata.name or None,
|
|
367
|
+
created_at=datetime.fromtimestamp(creation_info.created_at) if creation_info.created_at else None,
|
|
368
|
+
created_by=creation_info.created_by or None,
|
|
369
|
+
)
|
|
370
|
+
|
|
341
371
|
@live_method
|
|
342
372
|
async def _do_reload(self, lock=True):
|
|
343
373
|
async with (await self._get_lock()) if lock else asyncnullcontext():
|
modal/volume.pyi
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _io
|
|
2
2
|
import asyncio.locks
|
|
3
3
|
import collections.abc
|
|
4
|
+
import datetime
|
|
4
5
|
import enum
|
|
5
6
|
import google.protobuf.message
|
|
6
7
|
import modal._object
|
|
@@ -57,6 +58,27 @@ class FileEntry:
|
|
|
57
58
|
"""Return hash(self)."""
|
|
58
59
|
...
|
|
59
60
|
|
|
61
|
+
class VolumeInfo:
|
|
62
|
+
"""Information about the Volume object."""
|
|
63
|
+
|
|
64
|
+
name: typing.Optional[str]
|
|
65
|
+
created_at: datetime.datetime
|
|
66
|
+
created_by: typing.Optional[str]
|
|
67
|
+
|
|
68
|
+
def __init__(
|
|
69
|
+
self, name: typing.Optional[str], created_at: datetime.datetime, created_by: typing.Optional[str]
|
|
70
|
+
) -> None:
|
|
71
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
72
|
+
...
|
|
73
|
+
|
|
74
|
+
def __repr__(self):
|
|
75
|
+
"""Return repr(self)."""
|
|
76
|
+
...
|
|
77
|
+
|
|
78
|
+
def __eq__(self, other):
|
|
79
|
+
"""Return self==value."""
|
|
80
|
+
...
|
|
81
|
+
|
|
60
82
|
class _Volume(modal._object._Object):
|
|
61
83
|
"""A writeable volume that can be used to share files between one or more Modal functions.
|
|
62
84
|
|
|
@@ -126,7 +148,13 @@ class _Volume(modal._object._Object):
|
|
|
126
148
|
"""
|
|
127
149
|
...
|
|
128
150
|
|
|
151
|
+
@property
|
|
152
|
+
def name(self) -> typing.Optional[str]: ...
|
|
153
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
154
|
+
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
|
129
155
|
async def _get_lock(self): ...
|
|
156
|
+
@property
|
|
157
|
+
def _is_v1(self) -> bool: ...
|
|
130
158
|
@staticmethod
|
|
131
159
|
def from_name(
|
|
132
160
|
name: str,
|
|
@@ -155,10 +183,6 @@ class _Volume(modal._object._Object):
|
|
|
155
183
|
"""
|
|
156
184
|
...
|
|
157
185
|
|
|
158
|
-
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
159
|
-
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
|
160
|
-
@property
|
|
161
|
-
def _is_v1(self) -> bool: ...
|
|
162
186
|
@classmethod
|
|
163
187
|
def ephemeral(
|
|
164
188
|
cls: type[_Volume],
|
|
@@ -218,6 +242,10 @@ class _Volume(modal._object._Object):
|
|
|
218
242
|
"""mdmd:hidden"""
|
|
219
243
|
...
|
|
220
244
|
|
|
245
|
+
async def info(self) -> VolumeInfo:
|
|
246
|
+
"""Return information about the Volume object."""
|
|
247
|
+
...
|
|
248
|
+
|
|
221
249
|
async def _do_reload(self, lock=True): ...
|
|
222
250
|
async def commit(self):
|
|
223
251
|
"""Commit changes to the volume.
|
|
@@ -424,12 +452,19 @@ class Volume(modal.object.Object):
|
|
|
424
452
|
"""
|
|
425
453
|
...
|
|
426
454
|
|
|
455
|
+
@property
|
|
456
|
+
def name(self) -> typing.Optional[str]: ...
|
|
457
|
+
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
458
|
+
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
|
459
|
+
|
|
427
460
|
class ___get_lock_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
428
461
|
def __call__(self, /): ...
|
|
429
462
|
async def aio(self, /): ...
|
|
430
463
|
|
|
431
464
|
_get_lock: ___get_lock_spec[typing_extensions.Self]
|
|
432
465
|
|
|
466
|
+
@property
|
|
467
|
+
def _is_v1(self) -> bool: ...
|
|
433
468
|
@staticmethod
|
|
434
469
|
def from_name(
|
|
435
470
|
name: str,
|
|
@@ -458,10 +493,6 @@ class Volume(modal.object.Object):
|
|
|
458
493
|
"""
|
|
459
494
|
...
|
|
460
495
|
|
|
461
|
-
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
462
|
-
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
|
463
|
-
@property
|
|
464
|
-
def _is_v1(self) -> bool: ...
|
|
465
496
|
@classmethod
|
|
466
497
|
def ephemeral(
|
|
467
498
|
cls: type[Volume],
|
|
@@ -566,6 +597,17 @@ class Volume(modal.object.Object):
|
|
|
566
597
|
|
|
567
598
|
create_deployed: __create_deployed_spec
|
|
568
599
|
|
|
600
|
+
class __info_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
601
|
+
def __call__(self, /) -> VolumeInfo:
|
|
602
|
+
"""Return information about the Volume object."""
|
|
603
|
+
...
|
|
604
|
+
|
|
605
|
+
async def aio(self, /) -> VolumeInfo:
|
|
606
|
+
"""Return information about the Volume object."""
|
|
607
|
+
...
|
|
608
|
+
|
|
609
|
+
info: __info_spec[typing_extensions.Self]
|
|
610
|
+
|
|
569
611
|
class ___do_reload_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
570
612
|
def __call__(self, /, lock=True): ...
|
|
571
613
|
async def aio(self, /, lock=True): ...
|
|
@@ -6,8 +6,8 @@ modal/_container_entrypoint.py,sha256=1qBMNY_E9ICC_sRCtillMxmKPsmxJl1J0_qOAG8rH-
|
|
|
6
6
|
modal/_functions.py,sha256=c1EeAcHcYP76wHbLomV0mFe73AoL-TUSjJNSDu6CELI,83065
|
|
7
7
|
modal/_ipython.py,sha256=TW1fkVOmZL3YYqdS2YlM1hqpf654Yf8ZyybHdBnlhSw,301
|
|
8
8
|
modal/_location.py,sha256=joiX-0ZeutEUDTrrqLF1GHXCdVLF-rHzstocbMcd_-k,366
|
|
9
|
-
modal/_object.py,sha256=
|
|
10
|
-
modal/_output.py,sha256=
|
|
9
|
+
modal/_object.py,sha256=nCkQeLibSuvVAEIheGaLnUfN5PIh1CGpJCnzPIXymGY,11563
|
|
10
|
+
modal/_output.py,sha256=T7CRq90W09d-WD4ko7T4PBe26JNeAXE1-8HNO9xpNPI,25787
|
|
11
11
|
modal/_partial_function.py,sha256=B1J4S9W-La0NHaVmY1aCuH0E3QxJHIX6ZWY5eNTQ7io,37142
|
|
12
12
|
modal/_pty.py,sha256=JZfPDDpzqICZqtyPI_oMJf_9w-p_lLNuzHhwhodUXio,1329
|
|
13
13
|
modal/_resolver.py,sha256=2RWvm34cNSnbv1v7izJMNZgfvpLDD6LzaBlr0lIrLnY,7364
|
|
@@ -22,7 +22,7 @@ modal/app.py,sha256=BBR2NmGzZbFGfhKAmtzllD0o4TbVDBbOEs0O2ysSdQo,48277
|
|
|
22
22
|
modal/app.pyi,sha256=h6JtBA6a7wobdZAuS3QuXrWCUZqfyKPuGV3XdjCqT3k,43753
|
|
23
23
|
modal/call_graph.py,sha256=1g2DGcMIJvRy-xKicuf63IVE98gJSnQsr8R_NVMptNc,2581
|
|
24
24
|
modal/client.py,sha256=kyAIVB3Ay-XKJizQ_1ufUFB__EagV0MLmHJpyYyJ7J0,18636
|
|
25
|
-
modal/client.pyi,sha256=
|
|
25
|
+
modal/client.pyi,sha256=lLCQ-T2OTowy_xclR3HuOrUHday0qON2GzIglWlsks4,15831
|
|
26
26
|
modal/cloud_bucket_mount.py,sha256=YOe9nnvSr4ZbeCn587d7_VhE9IioZYRvF9VYQTQux08,5914
|
|
27
27
|
modal/cloud_bucket_mount.pyi,sha256=-qSfYAQvIoO_l2wsCCGTG5ZUwQieNKXdAO00yP1-LYU,7394
|
|
28
28
|
modal/cls.py,sha256=7A0xGnugQzm8dOfnKMjLjtqekRlRtQ0jPFRYgq6xdUM,40018
|
|
@@ -30,8 +30,8 @@ modal/cls.pyi,sha256=_tZ5qrlL-ZDEcD-mf9BZkkNH5XPr4SmGTEQ-RVmqF3I,27772
|
|
|
30
30
|
modal/config.py,sha256=FqVewLPVVR4feq_46JBENiCzqTuXKpnvQZxaeWbS39g,12009
|
|
31
31
|
modal/container_process.py,sha256=XkPwNIW-iD_GB9u9yqv9q8y-i5cQ8eBbLZZ_GvEw9t8,6858
|
|
32
32
|
modal/container_process.pyi,sha256=9m-st3hCUlNN1GOTctfPPvIvoLtEl7FbuGWwif5-7YU,6037
|
|
33
|
-
modal/dict.py,sha256=
|
|
34
|
-
modal/dict.pyi,sha256=
|
|
33
|
+
modal/dict.py,sha256=IyhKwQPM-HX10ZT-0ouSxpM-oAWqrT5waXFHmunmtyo,15804
|
|
34
|
+
modal/dict.pyi,sha256=vUrNmCKWZqiPIQSdbMT6fCq9q1QV3qkGVdz2B_yld34,22578
|
|
35
35
|
modal/environments.py,sha256=gHFNLG78bqgizpQ4w_elz27QOqmcgAonFsmLs7NjUJ4,6804
|
|
36
36
|
modal/environments.pyi,sha256=9-KtrzAcUe55cCP4020lSUD7-fWS7OPakAHssq4-bro,4219
|
|
37
37
|
modal/exception.py,sha256=o0V93PK8Hcg2YQ2aeOB1Y-qWBw4Gz5ATfyokR8GapuQ,5634
|
|
@@ -50,7 +50,7 @@ modal/mount.pyi,sha256=n6AuS8J3bTCQj750nVZZdVBvzCAlSM2fyxAt_5LLFik,20264
|
|
|
50
50
|
modal/network_file_system.py,sha256=AdjxI_hCYaDZz60gOuJeig8yourfWhHmEpn13C_fnMA,14775
|
|
51
51
|
modal/network_file_system.pyi,sha256=Td_IobHr84iLo_9LZKQ4tNdUB60yjX8QWBaFiUvhfi8,17685
|
|
52
52
|
modal/object.py,sha256=bTeskuY8JFrESjU4_UL_nTwYlBQdOLmVaOX3X6EMxsg,164
|
|
53
|
-
modal/object.pyi,sha256=
|
|
53
|
+
modal/object.pyi,sha256=sgbaq_d3QSmnPKg5jRbMG3dOceKs0l54kHUAhAyZKAE,6796
|
|
54
54
|
modal/output.py,sha256=q4T9uHduunj4NwY-YSwkHGgjZlCXMuJbfQ5UFaAGRAc,1968
|
|
55
55
|
modal/parallel_map.py,sha256=-9nS9s1jbx1Iqh_5HQRK4xTdhnXF4AGIXwT4UGJ8R78,52666
|
|
56
56
|
modal/parallel_map.pyi,sha256=fCugFsGup4Cflesb10_uR-nt5_eguuvhvtvavus_F98,11186
|
|
@@ -59,8 +59,8 @@ modal/partial_function.pyi,sha256=lqqOzZ9-QvHTDWKQ_oAYYOvsXgTOBKhO9u-RI98JbUk,13
|
|
|
59
59
|
modal/proxy.py,sha256=NQJJMGo-D2IfmeU0vb10WWaE4oTLcuf9jTeEJvactOg,1446
|
|
60
60
|
modal/proxy.pyi,sha256=yWGWwADCRGrC2w81B7671UTH4Uv3HMZKy5vVqlJUZoA,1417
|
|
61
61
|
modal/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
62
|
-
modal/queue.py,sha256=
|
|
63
|
-
modal/queue.pyi,sha256=
|
|
62
|
+
modal/queue.py,sha256=19Xri5HzY0VgOxWMZ4y_mNco8jhNgn9klegXrSHWmGc,20306
|
|
63
|
+
modal/queue.pyi,sha256=Pv4OtY7j17Yb89HGKaMQRiIv0yol-aV-ZtelxQ9GrlU,28330
|
|
64
64
|
modal/retries.py,sha256=IvNLDM0f_GLUDD5VgEDoN09C88yoxSrCquinAuxT1Sc,5205
|
|
65
65
|
modal/runner.py,sha256=ostdzYpQb-20tlD6dIq7bpWTkZkOhjJBNuMNektqnJA,24068
|
|
66
66
|
modal/runner.pyi,sha256=lbwLljm1cC8d6PcNvmYQhkE8501V9fg0bYqqKX6G4r4,8489
|
|
@@ -69,8 +69,8 @@ modal/sandbox.py,sha256=_hAoBwParMzooNUo02LRt-nC5RrTGUtOutyO9oI79Kc,40896
|
|
|
69
69
|
modal/sandbox.pyi,sha256=GPPlsm-DiSUSgrxyA5bqkpuLlrfgmNR7Z7s3W0QLuQ0,41812
|
|
70
70
|
modal/schedule.py,sha256=ng0g0AqNY5GQI9KhkXZQ5Wam5G42glbkqVQsNpBtbDE,3078
|
|
71
71
|
modal/scheduler_placement.py,sha256=BAREdOY5HzHpzSBqt6jDVR6YC_jYfHMVqOzkyqQfngU,1235
|
|
72
|
-
modal/secret.py,sha256=
|
|
73
|
-
modal/secret.pyi,sha256=
|
|
72
|
+
modal/secret.py,sha256=UaUmwYmT52VarDh92b0QzAa8_BNUAgBs-wE4eMQ6-B8,11967
|
|
73
|
+
modal/secret.pyi,sha256=zcC_OM0JzIF1ccnhNvVIlL6sY3xVjq3t0s3fE1ZDDVs,9732
|
|
74
74
|
modal/serving.py,sha256=3I3WBeVbzZY258u9PXBCW_dZBgypq3OhwBuTVvlgubE,4423
|
|
75
75
|
modal/serving.pyi,sha256=YfixTaWikyYpwhnNxCHMZnDDQiPmV1xJ87QF91U_WGU,1924
|
|
76
76
|
modal/snapshot.py,sha256=E3oxYQkYVRB_LeFBfmUV1Y6vHz8-azXJfC4x7A1QKnI,1455
|
|
@@ -78,8 +78,8 @@ modal/snapshot.pyi,sha256=0q83hlmWxAhDu8xwZyL5VmYh0i8Tigf7S60or2k30L8,1682
|
|
|
78
78
|
modal/stream_type.py,sha256=A6320qoAAWhEfwOCZfGtymQTu5AfLfJXXgARqooTPvY,417
|
|
79
79
|
modal/token_flow.py,sha256=GWpar0gANs71vm9Bd_Cj87UG1K3ljTURbkEjG3JLsrY,7616
|
|
80
80
|
modal/token_flow.pyi,sha256=eirYjyqbRiT3GCKMIPHJPpkvBTu8WxDKqSHehWaJI_4,2533
|
|
81
|
-
modal/volume.py,sha256=
|
|
82
|
-
modal/volume.pyi,sha256=
|
|
81
|
+
modal/volume.py,sha256=b3VYD-0D8rZWxoeIIYpjqm2lgxrVOjFEgTyW2btUVnw,45396
|
|
82
|
+
modal/volume.pyi,sha256=lMXzeyeC85ji8g2j0Ghy1WQrk2A2J0LPVpLFpabbr6A,41933
|
|
83
83
|
modal/_runtime/__init__.py,sha256=MIEP8jhXUeGq_eCjYFcqN5b1bxBM4fdk0VESpjWR0fc,28
|
|
84
84
|
modal/_runtime/asgi.py,sha256=_2xSTsDD27Cit7xnMs4lzkJA2wzer2_N4Oa3BkXFzVA,22521
|
|
85
85
|
modal/_runtime/container_io_manager.py,sha256=hjkK4gke_A8_mULSfm3F1hZKR0C61lKbRUI8mHS-LGE,45464
|
|
@@ -151,7 +151,7 @@ modal/experimental/__init__.py,sha256=nuc7AL4r_Fs08DD5dciWFZhrV1nanwoClOfdTcudU0
|
|
|
151
151
|
modal/experimental/flash.py,sha256=7-_RBNvm0tEpdxXWuPAj5HCxfN-hSHVBep8SEWgAhCQ,19721
|
|
152
152
|
modal/experimental/flash.pyi,sha256=A8_qJGtGoXEzKDdHbvhmCw7oqfneFEvJQK3ZdTOvUdU,10830
|
|
153
153
|
modal/experimental/ipython.py,sha256=TrCfmol9LGsRZMeDoeMPx3Hv3BFqQhYnmD_iH0pqdhk,2904
|
|
154
|
-
modal-1.1.1.
|
|
154
|
+
modal-1.1.1.dev28.dist-info/licenses/LICENSE,sha256=psuoW8kuDP96RQsdhzwOqi6fyWv0ct8CR6Jr7He_P_k,10173
|
|
155
155
|
modal_docs/__init__.py,sha256=svYKtV8HDwDCN86zbdWqyq5T8sMdGDj0PVlzc2tIxDM,28
|
|
156
156
|
modal_docs/gen_cli_docs.py,sha256=c1yfBS_x--gL5bs0N4ihMwqwX8l3IBWSkBAKNNIi6bQ,3801
|
|
157
157
|
modal_docs/gen_reference_docs.py,sha256=d_CQUGQ0rfw28u75I2mov9AlS773z9rG40-yq5o7g2U,6359
|
|
@@ -174,10 +174,10 @@ modal_proto/options_pb2.pyi,sha256=l7DBrbLO7q3Ir-XDkWsajm0d0TQqqrfuX54i4BMpdQg,1
|
|
|
174
174
|
modal_proto/options_pb2_grpc.py,sha256=1oboBPFxaTEXt9Aw7EAj8gXHDCNMhZD2VXqocC9l_gk,159
|
|
175
175
|
modal_proto/options_pb2_grpc.pyi,sha256=CImmhxHsYnF09iENPoe8S4J-n93jtgUYD2JPAc0yJSI,247
|
|
176
176
|
modal_proto/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
177
|
-
modal_version/__init__.py,sha256=
|
|
177
|
+
modal_version/__init__.py,sha256=Bhn-Ugb3ll-Q8THvxH35TRv5X0r0MdFbSqaPDwMQcxE,121
|
|
178
178
|
modal_version/__main__.py,sha256=2FO0yYQQwDTh6udt1h-cBnGd1c4ZyHnHSI4BksxzVac,105
|
|
179
|
-
modal-1.1.1.
|
|
180
|
-
modal-1.1.1.
|
|
181
|
-
modal-1.1.1.
|
|
182
|
-
modal-1.1.1.
|
|
183
|
-
modal-1.1.1.
|
|
179
|
+
modal-1.1.1.dev28.dist-info/METADATA,sha256=YXzS8Vb0BSQAE7bFDxldcOyJEBLClAY01vE9LMjpnZQ,2460
|
|
180
|
+
modal-1.1.1.dev28.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
|
|
181
|
+
modal-1.1.1.dev28.dist-info/entry_points.txt,sha256=An-wYgeEUnm6xzrAP9_NTSTSciYvvEWsMZILtYrvpAI,46
|
|
182
|
+
modal-1.1.1.dev28.dist-info/top_level.txt,sha256=4BWzoKYREKUZ5iyPzZpjqx4G8uB5TWxXPDwibLcVa7k,43
|
|
183
|
+
modal-1.1.1.dev28.dist-info/RECORD,,
|
modal_version/__init__.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|