modal 1.2.2.dev30__py3-none-any.whl → 1.2.2.dev31__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/_functions.py +69 -37
- modal/_load_context.py +105 -0
- modal/_object.py +47 -18
- modal/_resolver.py +21 -35
- modal/app.py +7 -0
- modal/app.pyi +3 -0
- modal/cli/dict.py +5 -2
- modal/cli/queues.py +4 -2
- modal/client.pyi +2 -2
- modal/cls.py +71 -32
- modal/cls.pyi +3 -0
- modal/dict.py +14 -5
- modal/dict.pyi +2 -0
- modal/environments.py +16 -7
- modal/environments.pyi +6 -2
- modal/functions.pyi +10 -3
- modal/image.py +22 -22
- modal/mount.py +34 -24
- modal/mount.pyi +33 -7
- modal/network_file_system.py +14 -5
- modal/network_file_system.pyi +12 -2
- modal/object.pyi +35 -8
- modal/proxy.py +14 -6
- modal/proxy.pyi +10 -2
- modal/queue.py +14 -5
- modal/queue.pyi +12 -2
- modal/runner.py +43 -47
- modal/runner.pyi +2 -2
- modal/sandbox.py +21 -12
- modal/secret.py +34 -17
- modal/secret.pyi +12 -2
- modal/serving.py +7 -11
- modal/serving.pyi +7 -8
- modal/snapshot.py +11 -5
- modal/volume.py +25 -7
- modal/volume.pyi +2 -0
- {modal-1.2.2.dev30.dist-info → modal-1.2.2.dev31.dist-info}/METADATA +1 -1
- {modal-1.2.2.dev30.dist-info → modal-1.2.2.dev31.dist-info}/RECORD +43 -42
- modal_version/__init__.py +1 -1
- {modal-1.2.2.dev30.dist-info → modal-1.2.2.dev31.dist-info}/WHEEL +0 -0
- {modal-1.2.2.dev30.dist-info → modal-1.2.2.dev31.dist-info}/entry_points.txt +0 -0
- {modal-1.2.2.dev30.dist-info → modal-1.2.2.dev31.dist-info}/licenses/LICENSE +0 -0
- {modal-1.2.2.dev30.dist-info → modal-1.2.2.dev31.dist-info}/top_level.txt +0 -0
modal/mount.py
CHANGED
|
@@ -20,7 +20,8 @@ import modal.file_pattern_matcher
|
|
|
20
20
|
from modal_proto import api_pb2
|
|
21
21
|
from modal_version import __version__
|
|
22
22
|
|
|
23
|
-
from .
|
|
23
|
+
from ._load_context import LoadContext
|
|
24
|
+
from ._object import _Object
|
|
24
25
|
from ._resolver import Resolver
|
|
25
26
|
from ._utils.async_utils import TaskContext, aclosing, async_map, synchronize_api
|
|
26
27
|
from ._utils.blob_utils import FileUploadSpec, blob_upload_file, get_file_upload_spec_from_path
|
|
@@ -310,7 +311,7 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
310
311
|
_entries: Optional[list[_MountEntry]] = None
|
|
311
312
|
_deployment_name: Optional[str] = None
|
|
312
313
|
_namespace: Optional[int] = None
|
|
313
|
-
|
|
314
|
+
|
|
314
315
|
_allow_overwrite: bool = False
|
|
315
316
|
_content_checksum_sha256_hex: Optional[str] = None
|
|
316
317
|
|
|
@@ -325,7 +326,12 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
325
326
|
return None
|
|
326
327
|
return (_Mount._type_prefix, "local", frozenset(included_files))
|
|
327
328
|
|
|
328
|
-
obj = _Mount._from_loader(
|
|
329
|
+
obj = _Mount._from_loader(
|
|
330
|
+
_Mount._load_mount,
|
|
331
|
+
rep,
|
|
332
|
+
deduplication_key=mount_content_deduplication_key,
|
|
333
|
+
load_context_overrides=LoadContext.empty(),
|
|
334
|
+
)
|
|
329
335
|
obj._entries = entries
|
|
330
336
|
obj._is_local = True
|
|
331
337
|
return obj
|
|
@@ -477,6 +483,7 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
477
483
|
async def _load_mount(
|
|
478
484
|
self: "_Mount",
|
|
479
485
|
resolver: Resolver,
|
|
486
|
+
load_context: LoadContext,
|
|
480
487
|
existing_object_id: Optional[str],
|
|
481
488
|
):
|
|
482
489
|
t0 = time.monotonic()
|
|
@@ -518,7 +525,7 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
518
525
|
|
|
519
526
|
request = api_pb2.MountPutFileRequest(sha256_hex=file_spec.sha256_hex)
|
|
520
527
|
accounted_hashes.add(file_spec.sha256_hex)
|
|
521
|
-
response = await
|
|
528
|
+
response = await load_context.client.stub.MountPutFile(request, retry=Retry(base_delay=1))
|
|
522
529
|
|
|
523
530
|
if response.exists:
|
|
524
531
|
n_finished += 1
|
|
@@ -532,7 +539,7 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
532
539
|
async with blob_upload_concurrency:
|
|
533
540
|
with file_spec.source() as fp:
|
|
534
541
|
blob_id = await blob_upload_file(
|
|
535
|
-
fp,
|
|
542
|
+
fp, load_context.client.stub, sha256_hex=file_spec.sha256_hex, md5_hex=file_spec.md5_hex
|
|
536
543
|
)
|
|
537
544
|
logger.debug(f"Uploading blob file {file_spec.source_description} as {remote_filename}")
|
|
538
545
|
request2 = api_pb2.MountPutFileRequest(data_blob_id=blob_id, sha256_hex=file_spec.sha256_hex)
|
|
@@ -544,7 +551,7 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
544
551
|
|
|
545
552
|
start_time = time.monotonic()
|
|
546
553
|
while time.monotonic() - start_time < MOUNT_PUT_FILE_CLIENT_TIMEOUT:
|
|
547
|
-
response = await
|
|
554
|
+
response = await load_context.client.stub.MountPutFile(request2, retry=Retry(base_delay=1))
|
|
548
555
|
if response.exists:
|
|
549
556
|
n_finished += 1
|
|
550
557
|
return mount_file
|
|
@@ -574,28 +581,28 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
574
581
|
req = api_pb2.MountGetOrCreateRequest(
|
|
575
582
|
deployment_name=self._deployment_name,
|
|
576
583
|
namespace=self._namespace,
|
|
577
|
-
environment_name=
|
|
584
|
+
environment_name=load_context.environment_name,
|
|
578
585
|
object_creation_type=creation_type,
|
|
579
586
|
files=files,
|
|
580
587
|
)
|
|
581
|
-
elif
|
|
588
|
+
elif load_context.app_id is not None:
|
|
582
589
|
req = api_pb2.MountGetOrCreateRequest(
|
|
583
590
|
object_creation_type=api_pb2.OBJECT_CREATION_TYPE_ANONYMOUS_OWNED_BY_APP,
|
|
584
591
|
files=files,
|
|
585
|
-
app_id=
|
|
592
|
+
app_id=load_context.app_id,
|
|
586
593
|
)
|
|
587
594
|
else:
|
|
588
595
|
req = api_pb2.MountGetOrCreateRequest(
|
|
589
596
|
object_creation_type=api_pb2.OBJECT_CREATION_TYPE_EPHEMERAL,
|
|
590
597
|
files=files,
|
|
591
|
-
environment_name=
|
|
598
|
+
environment_name=load_context.environment_name,
|
|
592
599
|
)
|
|
593
600
|
|
|
594
|
-
resp = await
|
|
601
|
+
resp = await load_context.client.stub.MountGetOrCreate(req, retry=Retry(base_delay=1))
|
|
595
602
|
status_row.finish(f"Created mount {message_label}")
|
|
596
603
|
|
|
597
604
|
logger.debug(f"Uploaded {total_uploads} new files and {total_bytes} bytes in {time.monotonic() - t0}s")
|
|
598
|
-
self._hydrate(resp.mount_id,
|
|
605
|
+
self._hydrate(resp.mount_id, load_context.client, resp.handle_metadata)
|
|
599
606
|
|
|
600
607
|
@staticmethod
|
|
601
608
|
def _from_local_python_packages(
|
|
@@ -628,19 +635,25 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
628
635
|
*,
|
|
629
636
|
namespace=api_pb2.DEPLOYMENT_NAMESPACE_WORKSPACE,
|
|
630
637
|
environment_name: Optional[str] = None,
|
|
638
|
+
client: Optional[_Client] = None,
|
|
631
639
|
) -> "_Mount":
|
|
632
640
|
"""mdmd:hidden"""
|
|
633
641
|
|
|
634
|
-
async def _load(provider: _Mount, resolver: Resolver, existing_object_id: Optional[str]):
|
|
642
|
+
async def _load(provider: _Mount, resolver: Resolver, load_context, existing_object_id: Optional[str]):
|
|
635
643
|
req = api_pb2.MountGetOrCreateRequest(
|
|
636
644
|
deployment_name=name,
|
|
637
645
|
namespace=namespace,
|
|
638
|
-
environment_name=
|
|
646
|
+
environment_name=load_context.environment_name,
|
|
639
647
|
)
|
|
640
|
-
response = await
|
|
641
|
-
provider._hydrate(response.mount_id,
|
|
642
|
-
|
|
643
|
-
return _Mount._from_loader(
|
|
648
|
+
response = await load_context.client.stub.MountGetOrCreate(req)
|
|
649
|
+
provider._hydrate(response.mount_id, load_context.client, response.handle_metadata)
|
|
650
|
+
|
|
651
|
+
return _Mount._from_loader(
|
|
652
|
+
_load,
|
|
653
|
+
"Mount()",
|
|
654
|
+
hydrate_lazily=True,
|
|
655
|
+
load_context_overrides=LoadContext(environment_name=environment_name, client=client),
|
|
656
|
+
)
|
|
644
657
|
|
|
645
658
|
async def _deploy(
|
|
646
659
|
self: "_Mount",
|
|
@@ -652,15 +665,12 @@ class _Mount(_Object, type_prefix="mo"):
|
|
|
652
665
|
client: Optional[_Client] = None,
|
|
653
666
|
) -> None:
|
|
654
667
|
check_object_name(deployment_name, "Mount")
|
|
655
|
-
environment_name = _get_environment_name(environment_name, resolver=None)
|
|
656
668
|
self._deployment_name = deployment_name
|
|
657
669
|
self._namespace = namespace
|
|
658
|
-
self._environment_name = environment_name
|
|
659
670
|
self._allow_overwrite = allow_overwrite
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
resolver
|
|
663
|
-
await resolver.load(self)
|
|
671
|
+
resolver = Resolver()
|
|
672
|
+
root_metadata = LoadContext(client=client, environment_name=environment_name)
|
|
673
|
+
await resolver.load(self, root_metadata)
|
|
664
674
|
|
|
665
675
|
def _get_metadata(self) -> api_pb2.MountHandleMetadata:
|
|
666
676
|
if self._content_checksum_sha256_hex is None:
|
modal/mount.pyi
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import collections.abc
|
|
2
2
|
import google.protobuf.message
|
|
3
|
+
import modal._load_context
|
|
3
4
|
import modal._object
|
|
4
5
|
import modal._resolver
|
|
5
6
|
import modal._utils.blob_utils
|
|
@@ -154,7 +155,6 @@ class _Mount(modal._object._Object):
|
|
|
154
155
|
_entries: typing.Optional[list[_MountEntry]]
|
|
155
156
|
_deployment_name: typing.Optional[str]
|
|
156
157
|
_namespace: typing.Optional[int]
|
|
157
|
-
_environment_name: typing.Optional[str]
|
|
158
158
|
_allow_overwrite: bool
|
|
159
159
|
_content_checksum_sha256_hex: typing.Optional[str]
|
|
160
160
|
|
|
@@ -216,7 +216,10 @@ class _Mount(modal._object._Object):
|
|
|
216
216
|
entries: list[_MountEntry],
|
|
217
217
|
) -> collections.abc.AsyncGenerator[modal._utils.blob_utils.FileUploadSpec, None]: ...
|
|
218
218
|
async def _load_mount(
|
|
219
|
-
self: _Mount,
|
|
219
|
+
self: _Mount,
|
|
220
|
+
resolver: modal._resolver.Resolver,
|
|
221
|
+
load_context: modal._load_context.LoadContext,
|
|
222
|
+
existing_object_id: typing.Optional[str],
|
|
220
223
|
): ...
|
|
221
224
|
@staticmethod
|
|
222
225
|
def _from_local_python_packages(
|
|
@@ -226,7 +229,13 @@ class _Mount(modal._object._Object):
|
|
|
226
229
|
ignore: typing.Union[typing.Sequence[str], collections.abc.Callable[[pathlib.Path], bool], None] = None,
|
|
227
230
|
) -> _Mount: ...
|
|
228
231
|
@staticmethod
|
|
229
|
-
def from_name(
|
|
232
|
+
def from_name(
|
|
233
|
+
name: str,
|
|
234
|
+
*,
|
|
235
|
+
namespace=1,
|
|
236
|
+
environment_name: typing.Optional[str] = None,
|
|
237
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
238
|
+
) -> _Mount:
|
|
230
239
|
"""mdmd:hidden"""
|
|
231
240
|
...
|
|
232
241
|
|
|
@@ -269,7 +278,6 @@ class Mount(modal.object.Object):
|
|
|
269
278
|
_entries: typing.Optional[list[_MountEntry]]
|
|
270
279
|
_deployment_name: typing.Optional[str]
|
|
271
280
|
_namespace: typing.Optional[int]
|
|
272
|
-
_environment_name: typing.Optional[str]
|
|
273
281
|
_allow_overwrite: bool
|
|
274
282
|
_content_checksum_sha256_hex: typing.Optional[str]
|
|
275
283
|
|
|
@@ -342,8 +350,20 @@ class Mount(modal.object.Object):
|
|
|
342
350
|
_get_files: ___get_files_spec
|
|
343
351
|
|
|
344
352
|
class ___load_mount_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
345
|
-
def __call__(
|
|
346
|
-
|
|
353
|
+
def __call__(
|
|
354
|
+
self,
|
|
355
|
+
/,
|
|
356
|
+
resolver: modal._resolver.Resolver,
|
|
357
|
+
load_context: modal._load_context.LoadContext,
|
|
358
|
+
existing_object_id: typing.Optional[str],
|
|
359
|
+
): ...
|
|
360
|
+
async def aio(
|
|
361
|
+
self,
|
|
362
|
+
/,
|
|
363
|
+
resolver: modal._resolver.Resolver,
|
|
364
|
+
load_context: modal._load_context.LoadContext,
|
|
365
|
+
existing_object_id: typing.Optional[str],
|
|
366
|
+
): ...
|
|
347
367
|
|
|
348
368
|
_load_mount: ___load_mount_spec[typing_extensions.Self]
|
|
349
369
|
|
|
@@ -355,7 +375,13 @@ class Mount(modal.object.Object):
|
|
|
355
375
|
ignore: typing.Union[typing.Sequence[str], collections.abc.Callable[[pathlib.Path], bool], None] = None,
|
|
356
376
|
) -> Mount: ...
|
|
357
377
|
@staticmethod
|
|
358
|
-
def from_name(
|
|
378
|
+
def from_name(
|
|
379
|
+
name: str,
|
|
380
|
+
*,
|
|
381
|
+
namespace=1,
|
|
382
|
+
environment_name: typing.Optional[str] = None,
|
|
383
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
384
|
+
) -> Mount:
|
|
359
385
|
"""mdmd:hidden"""
|
|
360
386
|
...
|
|
361
387
|
|
modal/network_file_system.py
CHANGED
|
@@ -11,6 +11,7 @@ from synchronicity.async_wrap import asynccontextmanager
|
|
|
11
11
|
import modal
|
|
12
12
|
from modal_proto import api_pb2
|
|
13
13
|
|
|
14
|
+
from ._load_context import LoadContext
|
|
14
15
|
from ._object import (
|
|
15
16
|
EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
|
|
16
17
|
_get_environment_name,
|
|
@@ -95,6 +96,7 @@ class _NetworkFileSystem(_Object, type_prefix="sv"):
|
|
|
95
96
|
namespace=None, # mdmd:line-hidden
|
|
96
97
|
environment_name: Optional[str] = None,
|
|
97
98
|
create_if_missing: bool = False,
|
|
99
|
+
client: Optional[_Client] = None,
|
|
98
100
|
) -> "_NetworkFileSystem":
|
|
99
101
|
"""Reference a NetworkFileSystem by its name, creating if necessary.
|
|
100
102
|
|
|
@@ -113,15 +115,17 @@ class _NetworkFileSystem(_Object, type_prefix="sv"):
|
|
|
113
115
|
check_object_name(name, "NetworkFileSystem")
|
|
114
116
|
warn_if_passing_namespace(namespace, "modal.NetworkFileSystem.from_name")
|
|
115
117
|
|
|
116
|
-
async def _load(
|
|
118
|
+
async def _load(
|
|
119
|
+
self: _NetworkFileSystem, resolver: Resolver, load_context: LoadContext, existing_object_id: Optional[str]
|
|
120
|
+
):
|
|
117
121
|
req = api_pb2.SharedVolumeGetOrCreateRequest(
|
|
118
122
|
deployment_name=name,
|
|
119
|
-
environment_name=
|
|
123
|
+
environment_name=load_context.environment_name,
|
|
120
124
|
object_creation_type=(api_pb2.OBJECT_CREATION_TYPE_CREATE_IF_MISSING if create_if_missing else None),
|
|
121
125
|
)
|
|
122
126
|
try:
|
|
123
|
-
response = await
|
|
124
|
-
self._hydrate(response.shared_volume_id,
|
|
127
|
+
response = await load_context.client.stub.SharedVolumeGetOrCreate(req)
|
|
128
|
+
self._hydrate(response.shared_volume_id, load_context.client, None)
|
|
125
129
|
except modal.exception.NotFoundError as exc:
|
|
126
130
|
if exc.args[0] == "App has wrong entity vo":
|
|
127
131
|
raise InvalidError(
|
|
@@ -129,7 +133,12 @@ class _NetworkFileSystem(_Object, type_prefix="sv"):
|
|
|
129
133
|
)
|
|
130
134
|
raise
|
|
131
135
|
|
|
132
|
-
return _NetworkFileSystem._from_loader(
|
|
136
|
+
return _NetworkFileSystem._from_loader(
|
|
137
|
+
_load,
|
|
138
|
+
"NetworkFileSystem()",
|
|
139
|
+
hydrate_lazily=True,
|
|
140
|
+
load_context_overrides=LoadContext(environment_name=environment_name, client=client),
|
|
141
|
+
)
|
|
133
142
|
|
|
134
143
|
@classmethod
|
|
135
144
|
@asynccontextmanager
|
modal/network_file_system.pyi
CHANGED
|
@@ -54,7 +54,12 @@ class _NetworkFileSystem(modal._object._Object):
|
|
|
54
54
|
"""
|
|
55
55
|
@staticmethod
|
|
56
56
|
def from_name(
|
|
57
|
-
name: str,
|
|
57
|
+
name: str,
|
|
58
|
+
*,
|
|
59
|
+
namespace=None,
|
|
60
|
+
environment_name: typing.Optional[str] = None,
|
|
61
|
+
create_if_missing: bool = False,
|
|
62
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
58
63
|
) -> _NetworkFileSystem:
|
|
59
64
|
"""Reference a NetworkFileSystem by its name, creating if necessary.
|
|
60
65
|
|
|
@@ -210,7 +215,12 @@ class NetworkFileSystem(modal.object.Object):
|
|
|
210
215
|
|
|
211
216
|
@staticmethod
|
|
212
217
|
def from_name(
|
|
213
|
-
name: str,
|
|
218
|
+
name: str,
|
|
219
|
+
*,
|
|
220
|
+
namespace=None,
|
|
221
|
+
environment_name: typing.Optional[str] = None,
|
|
222
|
+
create_if_missing: bool = False,
|
|
223
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
214
224
|
) -> NetworkFileSystem:
|
|
215
225
|
"""Reference a NetworkFileSystem by its name, creating if necessary.
|
|
216
226
|
|
modal/object.pyi
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import collections.abc
|
|
2
2
|
import google.protobuf.message
|
|
3
|
+
import modal._load_context
|
|
3
4
|
import modal._resolver
|
|
4
5
|
import modal.client
|
|
5
6
|
import typing
|
|
@@ -12,12 +13,14 @@ class Object:
|
|
|
12
13
|
_prefix_to_type: typing.ClassVar[dict[str, type]]
|
|
13
14
|
_load: typing.Optional[
|
|
14
15
|
collections.abc.Callable[
|
|
15
|
-
[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]],
|
|
16
|
+
[typing_extensions.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
17
|
+
collections.abc.Awaitable[None],
|
|
16
18
|
]
|
|
17
19
|
]
|
|
18
20
|
_preload: typing.Optional[
|
|
19
21
|
collections.abc.Callable[
|
|
20
|
-
[typing_extensions.Self, modal._resolver.Resolver, typing.Optional[str]],
|
|
22
|
+
[typing_extensions.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
23
|
+
collections.abc.Awaitable[None],
|
|
21
24
|
]
|
|
22
25
|
]
|
|
23
26
|
_rep: str
|
|
@@ -27,6 +30,7 @@ class Object:
|
|
|
27
30
|
_deduplication_key: typing.Optional[
|
|
28
31
|
collections.abc.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
|
29
32
|
]
|
|
33
|
+
_load_context_overrides: modal._load_context.LoadContext
|
|
30
34
|
_object_id: typing.Optional[str]
|
|
31
35
|
_client: typing.Optional[modal.client.Client]
|
|
32
36
|
_is_hydrated: bool
|
|
@@ -46,16 +50,22 @@ class Object:
|
|
|
46
50
|
/,
|
|
47
51
|
rep: str,
|
|
48
52
|
load: typing.Optional[
|
|
49
|
-
collections.abc.Callable[
|
|
53
|
+
collections.abc.Callable[
|
|
54
|
+
[SUPERSELF, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]], None
|
|
55
|
+
]
|
|
50
56
|
] = None,
|
|
51
57
|
is_another_app: bool = False,
|
|
52
58
|
preload: typing.Optional[
|
|
53
|
-
collections.abc.Callable[
|
|
59
|
+
collections.abc.Callable[
|
|
60
|
+
[SUPERSELF, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]], None
|
|
61
|
+
]
|
|
54
62
|
] = None,
|
|
55
63
|
hydrate_lazily: bool = False,
|
|
56
64
|
deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
|
|
57
65
|
deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
|
|
58
66
|
name: typing.Optional[str] = None,
|
|
67
|
+
*,
|
|
68
|
+
load_context_overrides: typing.Optional[modal._load_context.LoadContext] = None,
|
|
59
69
|
): ...
|
|
60
70
|
def aio(
|
|
61
71
|
self,
|
|
@@ -63,13 +73,15 @@ class Object:
|
|
|
63
73
|
rep: str,
|
|
64
74
|
load: typing.Optional[
|
|
65
75
|
collections.abc.Callable[
|
|
66
|
-
[SUPERSELF, modal._resolver.Resolver, typing.Optional[str]],
|
|
76
|
+
[SUPERSELF, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
77
|
+
collections.abc.Awaitable[None],
|
|
67
78
|
]
|
|
68
79
|
] = None,
|
|
69
80
|
is_another_app: bool = False,
|
|
70
81
|
preload: typing.Optional[
|
|
71
82
|
collections.abc.Callable[
|
|
72
|
-
[SUPERSELF, modal._resolver.Resolver, typing.Optional[str]],
|
|
83
|
+
[SUPERSELF, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
84
|
+
collections.abc.Awaitable[None],
|
|
73
85
|
]
|
|
74
86
|
] = None,
|
|
75
87
|
hydrate_lazily: bool = False,
|
|
@@ -78,6 +90,8 @@ class Object:
|
|
|
78
90
|
collections.abc.Callable[[], collections.abc.Awaitable[collections.abc.Hashable]]
|
|
79
91
|
] = None,
|
|
80
92
|
name: typing.Optional[str] = None,
|
|
93
|
+
*,
|
|
94
|
+
load_context_overrides: typing.Optional[modal._load_context.LoadContext] = None,
|
|
81
95
|
): ...
|
|
82
96
|
|
|
83
97
|
_init: ___init_spec[typing_extensions.Self]
|
|
@@ -101,16 +115,29 @@ class Object:
|
|
|
101
115
|
@classmethod
|
|
102
116
|
def _from_loader(
|
|
103
117
|
cls,
|
|
104
|
-
load: collections.abc.Callable[
|
|
118
|
+
load: collections.abc.Callable[
|
|
119
|
+
[typing_extensions.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
120
|
+
None,
|
|
121
|
+
],
|
|
105
122
|
rep: str,
|
|
106
123
|
is_another_app: bool = False,
|
|
107
124
|
preload: typing.Optional[
|
|
108
|
-
collections.abc.Callable[
|
|
125
|
+
collections.abc.Callable[
|
|
126
|
+
[
|
|
127
|
+
typing_extensions.Self,
|
|
128
|
+
modal._resolver.Resolver,
|
|
129
|
+
modal._load_context.LoadContext,
|
|
130
|
+
typing.Optional[str],
|
|
131
|
+
],
|
|
132
|
+
None,
|
|
133
|
+
]
|
|
109
134
|
] = None,
|
|
110
135
|
hydrate_lazily: bool = False,
|
|
111
136
|
deps: typing.Optional[collections.abc.Callable[..., collections.abc.Sequence[Object]]] = None,
|
|
112
137
|
deduplication_key: typing.Optional[collections.abc.Callable[[], collections.abc.Hashable]] = None,
|
|
113
138
|
name: typing.Optional[str] = None,
|
|
139
|
+
*,
|
|
140
|
+
load_context_overrides: modal._load_context.LoadContext,
|
|
114
141
|
): ...
|
|
115
142
|
@staticmethod
|
|
116
143
|
def _get_type_from_id(object_id: str) -> type[Object]: ...
|
modal/proxy.py
CHANGED
|
@@ -3,9 +3,11 @@ from typing import Optional
|
|
|
3
3
|
|
|
4
4
|
from modal_proto import api_pb2
|
|
5
5
|
|
|
6
|
-
from .
|
|
6
|
+
from ._load_context import LoadContext
|
|
7
|
+
from ._object import _Object
|
|
7
8
|
from ._resolver import Resolver
|
|
8
9
|
from ._utils.async_utils import synchronize_api
|
|
10
|
+
from .client import _Client
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class _Proxy(_Object, type_prefix="pr"):
|
|
@@ -20,6 +22,7 @@ class _Proxy(_Object, type_prefix="pr"):
|
|
|
20
22
|
name: str,
|
|
21
23
|
*,
|
|
22
24
|
environment_name: Optional[str] = None,
|
|
25
|
+
client: Optional[_Client] = None,
|
|
23
26
|
) -> "_Proxy":
|
|
24
27
|
"""Reference a Proxy by its name.
|
|
25
28
|
|
|
@@ -28,16 +31,21 @@ class _Proxy(_Object, type_prefix="pr"):
|
|
|
28
31
|
|
|
29
32
|
"""
|
|
30
33
|
|
|
31
|
-
async def _load(self: _Proxy, resolver: Resolver, existing_object_id: Optional[str]):
|
|
34
|
+
async def _load(self: _Proxy, resolver: Resolver, load_context: LoadContext, existing_object_id: Optional[str]):
|
|
32
35
|
req = api_pb2.ProxyGetRequest(
|
|
33
36
|
name=name,
|
|
34
|
-
environment_name=
|
|
37
|
+
environment_name=load_context.environment_name,
|
|
35
38
|
)
|
|
36
|
-
response: api_pb2.ProxyGetResponse = await
|
|
37
|
-
self._hydrate(response.proxy.proxy_id,
|
|
39
|
+
response: api_pb2.ProxyGetResponse = await load_context.client.stub.ProxyGet(req)
|
|
40
|
+
self._hydrate(response.proxy.proxy_id, load_context.client, None)
|
|
38
41
|
|
|
39
42
|
rep = _Proxy._repr(name, environment_name)
|
|
40
|
-
return _Proxy._from_loader(
|
|
43
|
+
return _Proxy._from_loader(
|
|
44
|
+
_load,
|
|
45
|
+
rep,
|
|
46
|
+
is_another_app=True,
|
|
47
|
+
load_context_overrides=LoadContext(client=client, environment_name=environment_name),
|
|
48
|
+
)
|
|
41
49
|
|
|
42
50
|
|
|
43
51
|
Proxy = synchronize_api(_Proxy, target_module=__name__)
|
modal/proxy.pyi
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import modal._object
|
|
2
|
+
import modal.client
|
|
2
3
|
import modal.object
|
|
3
4
|
import typing
|
|
4
5
|
|
|
@@ -9,7 +10,12 @@ class _Proxy(modal._object._Object):
|
|
|
9
10
|
a database. See [the guide](https://modal.com/docs/guide/proxy-ips) for more information.
|
|
10
11
|
"""
|
|
11
12
|
@staticmethod
|
|
12
|
-
def from_name(
|
|
13
|
+
def from_name(
|
|
14
|
+
name: str,
|
|
15
|
+
*,
|
|
16
|
+
environment_name: typing.Optional[str] = None,
|
|
17
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
18
|
+
) -> _Proxy:
|
|
13
19
|
"""Reference a Proxy by its name.
|
|
14
20
|
|
|
15
21
|
In contrast to most other Modal objects, new Proxy objects must be
|
|
@@ -28,7 +34,9 @@ class Proxy(modal.object.Object):
|
|
|
28
34
|
...
|
|
29
35
|
|
|
30
36
|
@staticmethod
|
|
31
|
-
def from_name(
|
|
37
|
+
def from_name(
|
|
38
|
+
name: str, *, environment_name: typing.Optional[str] = None, client: typing.Optional[modal.client.Client] = None
|
|
39
|
+
) -> Proxy:
|
|
32
40
|
"""Reference a Proxy by its name.
|
|
33
41
|
|
|
34
42
|
In contrast to most other Modal objects, new Proxy objects must be
|
modal/queue.py
CHANGED
|
@@ -14,6 +14,7 @@ from synchronicity.async_wrap import asynccontextmanager
|
|
|
14
14
|
|
|
15
15
|
from modal_proto import api_pb2
|
|
16
16
|
|
|
17
|
+
from ._load_context import LoadContext
|
|
17
18
|
from ._object import (
|
|
18
19
|
EPHEMERAL_OBJECT_HEARTBEAT_SLEEP,
|
|
19
20
|
_get_environment_name,
|
|
@@ -361,6 +362,7 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
361
362
|
namespace=None, # mdmd:line-hidden
|
|
362
363
|
environment_name: Optional[str] = None,
|
|
363
364
|
create_if_missing: bool = False,
|
|
365
|
+
client: Optional[_Client] = None,
|
|
364
366
|
) -> "_Queue":
|
|
365
367
|
"""Reference a named Queue, creating if necessary.
|
|
366
368
|
|
|
@@ -376,17 +378,24 @@ class _Queue(_Object, type_prefix="qu"):
|
|
|
376
378
|
check_object_name(name, "Queue")
|
|
377
379
|
warn_if_passing_namespace(namespace, "modal.Queue.from_name")
|
|
378
380
|
|
|
379
|
-
async def _load(self: _Queue, resolver: Resolver, existing_object_id: Optional[str]):
|
|
381
|
+
async def _load(self: _Queue, resolver: Resolver, load_context: LoadContext, existing_object_id: Optional[str]):
|
|
380
382
|
req = api_pb2.QueueGetOrCreateRequest(
|
|
381
383
|
deployment_name=name,
|
|
382
|
-
environment_name=
|
|
384
|
+
environment_name=load_context.environment_name,
|
|
383
385
|
object_creation_type=(api_pb2.OBJECT_CREATION_TYPE_CREATE_IF_MISSING if create_if_missing else None),
|
|
384
386
|
)
|
|
385
|
-
response = await
|
|
386
|
-
self._hydrate(response.queue_id,
|
|
387
|
+
response = await load_context.client.stub.QueueGetOrCreate(req)
|
|
388
|
+
self._hydrate(response.queue_id, load_context.client, response.metadata)
|
|
387
389
|
|
|
388
390
|
rep = _Queue._repr(name, environment_name)
|
|
389
|
-
return _Queue._from_loader(
|
|
391
|
+
return _Queue._from_loader(
|
|
392
|
+
_load,
|
|
393
|
+
rep,
|
|
394
|
+
is_another_app=True,
|
|
395
|
+
hydrate_lazily=True,
|
|
396
|
+
name=name,
|
|
397
|
+
load_context_overrides=LoadContext(environment_name=environment_name, client=client),
|
|
398
|
+
)
|
|
390
399
|
|
|
391
400
|
@staticmethod
|
|
392
401
|
async def delete(name: str, *, client: Optional[_Client] = None, environment_name: Optional[str] = None):
|
modal/queue.pyi
CHANGED
|
@@ -464,7 +464,12 @@ class _Queue(modal._object._Object):
|
|
|
464
464
|
|
|
465
465
|
@staticmethod
|
|
466
466
|
def from_name(
|
|
467
|
-
name: str,
|
|
467
|
+
name: str,
|
|
468
|
+
*,
|
|
469
|
+
namespace=None,
|
|
470
|
+
environment_name: typing.Optional[str] = None,
|
|
471
|
+
create_if_missing: bool = False,
|
|
472
|
+
client: typing.Optional[modal.client._Client] = None,
|
|
468
473
|
) -> _Queue:
|
|
469
474
|
"""Reference a named Queue, creating if necessary.
|
|
470
475
|
|
|
@@ -721,7 +726,12 @@ class Queue(modal.object.Object):
|
|
|
721
726
|
|
|
722
727
|
@staticmethod
|
|
723
728
|
def from_name(
|
|
724
|
-
name: str,
|
|
729
|
+
name: str,
|
|
730
|
+
*,
|
|
731
|
+
namespace=None,
|
|
732
|
+
environment_name: typing.Optional[str] = None,
|
|
733
|
+
create_if_missing: bool = False,
|
|
734
|
+
client: typing.Optional[modal.client.Client] = None,
|
|
725
735
|
) -> Queue:
|
|
726
736
|
"""Reference a named Queue, creating if necessary.
|
|
727
737
|
|