modal 1.0.6.dev58__py3-none-any.whl → 1.2.3.dev7__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/__main__.py +3 -4
- modal/_billing.py +80 -0
- modal/_clustered_functions.py +7 -3
- modal/_clustered_functions.pyi +4 -2
- modal/_container_entrypoint.py +41 -49
- modal/_functions.py +424 -195
- modal/_grpc_client.py +171 -0
- modal/_load_context.py +105 -0
- modal/_object.py +68 -20
- modal/_output.py +58 -45
- modal/_partial_function.py +36 -11
- modal/_pty.py +7 -3
- modal/_resolver.py +21 -35
- modal/_runtime/asgi.py +4 -3
- modal/_runtime/container_io_manager.py +301 -186
- modal/_runtime/container_io_manager.pyi +70 -61
- modal/_runtime/execution_context.py +18 -2
- modal/_runtime/execution_context.pyi +4 -1
- modal/_runtime/gpu_memory_snapshot.py +170 -63
- modal/_runtime/user_code_imports.py +28 -58
- modal/_serialization.py +57 -1
- modal/_utils/async_utils.py +33 -12
- modal/_utils/auth_token_manager.py +2 -5
- modal/_utils/blob_utils.py +110 -53
- modal/_utils/function_utils.py +49 -42
- modal/_utils/grpc_utils.py +80 -50
- modal/_utils/mount_utils.py +26 -1
- modal/_utils/name_utils.py +17 -3
- modal/_utils/task_command_router_client.py +536 -0
- modal/_utils/time_utils.py +34 -6
- modal/app.py +219 -83
- modal/app.pyi +229 -56
- modal/billing.py +5 -0
- modal/{requirements → builder}/2025.06.txt +1 -0
- modal/{requirements → builder}/PREVIEW.txt +1 -0
- modal/cli/_download.py +19 -3
- modal/cli/_traceback.py +3 -2
- modal/cli/app.py +4 -4
- modal/cli/cluster.py +15 -7
- modal/cli/config.py +5 -3
- modal/cli/container.py +7 -6
- modal/cli/dict.py +22 -16
- modal/cli/entry_point.py +12 -5
- modal/cli/environment.py +5 -4
- modal/cli/import_refs.py +3 -3
- modal/cli/launch.py +102 -5
- modal/cli/network_file_system.py +9 -13
- modal/cli/profile.py +3 -2
- modal/cli/programs/launch_instance_ssh.py +94 -0
- modal/cli/programs/run_jupyter.py +1 -1
- modal/cli/programs/run_marimo.py +95 -0
- modal/cli/programs/vscode.py +1 -1
- modal/cli/queues.py +57 -26
- modal/cli/run.py +58 -16
- modal/cli/secret.py +48 -22
- modal/cli/utils.py +3 -4
- modal/cli/volume.py +28 -25
- modal/client.py +13 -116
- modal/client.pyi +9 -91
- modal/cloud_bucket_mount.py +5 -3
- modal/cloud_bucket_mount.pyi +5 -1
- modal/cls.py +130 -102
- modal/cls.pyi +45 -85
- modal/config.py +29 -10
- modal/container_process.py +291 -13
- modal/container_process.pyi +95 -32
- modal/dict.py +282 -63
- modal/dict.pyi +423 -73
- modal/environments.py +15 -27
- modal/environments.pyi +5 -15
- modal/exception.py +8 -0
- modal/experimental/__init__.py +143 -38
- modal/experimental/flash.py +247 -78
- modal/experimental/flash.pyi +137 -9
- modal/file_io.py +14 -28
- modal/file_io.pyi +2 -2
- modal/file_pattern_matcher.py +25 -16
- modal/functions.pyi +134 -61
- modal/image.py +255 -86
- modal/image.pyi +300 -62
- modal/io_streams.py +436 -126
- modal/io_streams.pyi +236 -171
- modal/mount.py +62 -157
- modal/mount.pyi +45 -172
- modal/network_file_system.py +30 -53
- modal/network_file_system.pyi +16 -76
- modal/object.pyi +42 -8
- modal/parallel_map.py +821 -113
- modal/parallel_map.pyi +134 -0
- modal/partial_function.pyi +4 -1
- modal/proxy.py +16 -7
- modal/proxy.pyi +10 -2
- modal/queue.py +263 -61
- modal/queue.pyi +409 -66
- modal/runner.py +112 -92
- modal/runner.pyi +45 -27
- modal/sandbox.py +451 -124
- modal/sandbox.pyi +513 -67
- modal/secret.py +291 -67
- modal/secret.pyi +425 -19
- modal/serving.py +7 -11
- modal/serving.pyi +7 -8
- modal/snapshot.py +11 -8
- modal/token_flow.py +4 -4
- modal/volume.py +344 -98
- modal/volume.pyi +464 -68
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/METADATA +9 -8
- modal-1.2.3.dev7.dist-info/RECORD +195 -0
- modal_docs/mdmd/mdmd.py +11 -1
- modal_proto/api.proto +399 -67
- modal_proto/api_grpc.py +241 -1
- modal_proto/api_pb2.py +1395 -1000
- modal_proto/api_pb2.pyi +1239 -79
- modal_proto/api_pb2_grpc.py +499 -4
- modal_proto/api_pb2_grpc.pyi +162 -14
- modal_proto/modal_api_grpc.py +175 -160
- modal_proto/sandbox_router.proto +145 -0
- modal_proto/sandbox_router_grpc.py +105 -0
- modal_proto/sandbox_router_pb2.py +149 -0
- modal_proto/sandbox_router_pb2.pyi +333 -0
- modal_proto/sandbox_router_pb2_grpc.py +203 -0
- modal_proto/sandbox_router_pb2_grpc.pyi +75 -0
- modal_proto/task_command_router.proto +144 -0
- modal_proto/task_command_router_grpc.py +105 -0
- modal_proto/task_command_router_pb2.py +149 -0
- modal_proto/task_command_router_pb2.pyi +333 -0
- modal_proto/task_command_router_pb2_grpc.py +203 -0
- modal_proto/task_command_router_pb2_grpc.pyi +75 -0
- modal_version/__init__.py +1 -1
- modal-1.0.6.dev58.dist-info/RECORD +0 -183
- modal_proto/modal_options_grpc.py +0 -3
- modal_proto/options.proto +0 -19
- modal_proto/options_grpc.py +0 -3
- modal_proto/options_pb2.py +0 -35
- modal_proto/options_pb2.pyi +0 -20
- modal_proto/options_pb2_grpc.py +0 -4
- modal_proto/options_pb2_grpc.pyi +0 -7
- /modal/{requirements → builder}/2023.12.312.txt +0 -0
- /modal/{requirements → builder}/2023.12.txt +0 -0
- /modal/{requirements → builder}/2024.04.txt +0 -0
- /modal/{requirements → builder}/2024.10.txt +0 -0
- /modal/{requirements → builder}/README.md +0 -0
- /modal/{requirements → builder}/base-images.json +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/WHEEL +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/entry_points.txt +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/licenses/LICENSE +0 -0
- {modal-1.0.6.dev58.dist-info → modal-1.2.3.dev7.dist-info}/top_level.txt +0 -0
modal/parallel_map.pyi
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import asyncio.events
|
|
3
|
+
import asyncio.queues
|
|
3
4
|
import collections.abc
|
|
4
5
|
import enum
|
|
5
6
|
import modal._functions
|
|
6
7
|
import modal._utils.async_utils
|
|
8
|
+
import modal._utils.grpc_utils
|
|
7
9
|
import modal.client
|
|
8
10
|
import modal.functions
|
|
9
11
|
import modal.retries
|
|
@@ -60,6 +62,80 @@ class _OutputValue:
|
|
|
60
62
|
"""Return self==value."""
|
|
61
63
|
...
|
|
62
64
|
|
|
65
|
+
class InputPreprocessor:
|
|
66
|
+
"""Constructs FunctionPutInputsItem objects from the raw-input queue, and puts them in the processed-input queue."""
|
|
67
|
+
def __init__(
|
|
68
|
+
self,
|
|
69
|
+
client: modal.client._Client,
|
|
70
|
+
*,
|
|
71
|
+
raw_input_queue: _SynchronizedQueue,
|
|
72
|
+
processed_input_queue: asyncio.queues.Queue,
|
|
73
|
+
function: modal._functions._Function,
|
|
74
|
+
created_callback: collections.abc.Callable[[int], None],
|
|
75
|
+
done_callback: collections.abc.Callable[[], None],
|
|
76
|
+
):
|
|
77
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
78
|
+
...
|
|
79
|
+
|
|
80
|
+
def input_iter(self): ...
|
|
81
|
+
def create_input_factory(self): ...
|
|
82
|
+
def drain_input_generator(self): ...
|
|
83
|
+
|
|
84
|
+
class InputPumper:
|
|
85
|
+
"""Reads inputs from a queue of FunctionPutInputsItems, and sends them to the server."""
|
|
86
|
+
def __init__(
|
|
87
|
+
self,
|
|
88
|
+
client: modal.client._Client,
|
|
89
|
+
*,
|
|
90
|
+
input_queue: asyncio.queues.Queue,
|
|
91
|
+
function: modal._functions._Function,
|
|
92
|
+
function_call_id: str,
|
|
93
|
+
max_batch_size: int,
|
|
94
|
+
map_items_manager: typing.Optional[_MapItemsManager] = None,
|
|
95
|
+
):
|
|
96
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
97
|
+
...
|
|
98
|
+
|
|
99
|
+
def pump_inputs(self): ...
|
|
100
|
+
@property
|
|
101
|
+
def _function_inputs_retry(self) -> modal._utils.grpc_utils.Retry: ...
|
|
102
|
+
|
|
103
|
+
class SyncInputPumper(InputPumper):
|
|
104
|
+
"""Reads inputs from a queue of FunctionPutInputsItems, and sends them to the server."""
|
|
105
|
+
def __init__(
|
|
106
|
+
self,
|
|
107
|
+
client: modal.client._Client,
|
|
108
|
+
*,
|
|
109
|
+
input_queue: asyncio.queues.Queue,
|
|
110
|
+
retry_queue: modal._utils.async_utils.TimestampPriorityQueue,
|
|
111
|
+
function: modal._functions._Function,
|
|
112
|
+
function_call_jwt: str,
|
|
113
|
+
function_call_id: str,
|
|
114
|
+
map_items_manager: _MapItemsManager,
|
|
115
|
+
):
|
|
116
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
117
|
+
...
|
|
118
|
+
|
|
119
|
+
def retry_inputs(self): ...
|
|
120
|
+
|
|
121
|
+
class AsyncInputPumper(InputPumper):
|
|
122
|
+
"""Reads inputs from a queue of FunctionPutInputsItems, and sends them to the server."""
|
|
123
|
+
def __init__(
|
|
124
|
+
self,
|
|
125
|
+
client: modal.client._Client,
|
|
126
|
+
*,
|
|
127
|
+
input_queue: asyncio.queues.Queue,
|
|
128
|
+
function: modal._functions._Function,
|
|
129
|
+
function_call_id: str,
|
|
130
|
+
):
|
|
131
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
132
|
+
...
|
|
133
|
+
|
|
134
|
+
def pump_inputs(self): ...
|
|
135
|
+
|
|
136
|
+
async def _spawn_map_invocation(
|
|
137
|
+
function: modal._functions._Function, raw_input_queue: _SynchronizedQueue, client: modal.client._Client
|
|
138
|
+
) -> tuple[str, int]: ...
|
|
63
139
|
def _map_invocation(
|
|
64
140
|
function: modal._functions._Function,
|
|
65
141
|
raw_input_queue: _SynchronizedQueue,
|
|
@@ -70,6 +146,23 @@ def _map_invocation(
|
|
|
70
146
|
count_update_callback: typing.Optional[collections.abc.Callable[[int, int], None]],
|
|
71
147
|
function_call_invocation_type: int,
|
|
72
148
|
): ...
|
|
149
|
+
def _map_invocation_inputplane(
|
|
150
|
+
function: modal._functions._Function,
|
|
151
|
+
raw_input_queue: _SynchronizedQueue,
|
|
152
|
+
client: modal.client._Client,
|
|
153
|
+
order_outputs: bool,
|
|
154
|
+
return_exceptions: bool,
|
|
155
|
+
wrap_returned_exceptions: bool,
|
|
156
|
+
count_update_callback: typing.Optional[collections.abc.Callable[[int, int], None]],
|
|
157
|
+
) -> typing.AsyncGenerator[typing.Any, None]:
|
|
158
|
+
"""Input-plane implementation of a function map invocation.
|
|
159
|
+
|
|
160
|
+
This is analogous to `_map_invocation`, but instead of the control-plane
|
|
161
|
+
`FunctionMap` / `FunctionPutInputs` / `FunctionGetOutputs` RPCs it speaks
|
|
162
|
+
the input-plane protocol consisting of `MapStartOrContinue`, `MapAwait`, and `MapCheckInputs`.
|
|
163
|
+
"""
|
|
164
|
+
...
|
|
165
|
+
|
|
73
166
|
def _map_helper(
|
|
74
167
|
self: modal.functions.Function,
|
|
75
168
|
async_input_gen: typing.AsyncGenerator[typing.Any, None],
|
|
@@ -162,6 +255,33 @@ def _map_sync(
|
|
|
162
255
|
"""
|
|
163
256
|
...
|
|
164
257
|
|
|
258
|
+
async def _experimental_spawn_map_async(self, *input_iterators, kwargs={}) -> modal._functions._FunctionCall: ...
|
|
259
|
+
async def _spawn_map_helper(
|
|
260
|
+
self: modal.functions.Function, async_input_gen, kwargs={}
|
|
261
|
+
) -> modal._functions._FunctionCall: ...
|
|
262
|
+
def _experimental_spawn_map_sync(self, *input_iterators, kwargs={}) -> modal._functions._FunctionCall:
|
|
263
|
+
"""mdmd:hidden
|
|
264
|
+
Spawn parallel execution over a set of inputs, returning as soon as the inputs are created.
|
|
265
|
+
|
|
266
|
+
Unlike `modal.Function.map`, this method does not block on completion of the remote execution but
|
|
267
|
+
returns a `modal.FunctionCall` object that can be used to poll status and retrieve results later.
|
|
268
|
+
|
|
269
|
+
Takes one iterator argument per argument in the function being mapped over.
|
|
270
|
+
|
|
271
|
+
Example:
|
|
272
|
+
```python
|
|
273
|
+
@app.function()
|
|
274
|
+
def my_func(a, b):
|
|
275
|
+
return a ** b
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@app.local_entrypoint()
|
|
279
|
+
def main():
|
|
280
|
+
fc = my_func.spawn_map([1, 2], [3, 4])
|
|
281
|
+
```
|
|
282
|
+
"""
|
|
283
|
+
...
|
|
284
|
+
|
|
165
285
|
async def _spawn_map_async(self, *input_iterators, kwargs={}) -> None:
|
|
166
286
|
"""This runs in an event loop on the main thread. It consumes inputs from the input iterators and creates async
|
|
167
287
|
function calls for each.
|
|
@@ -260,10 +380,12 @@ class _MapItemContext:
|
|
|
260
380
|
input: modal_proto.api_pb2.FunctionInput,
|
|
261
381
|
retry_manager: modal.retries.RetryManager,
|
|
262
382
|
sync_client_retries_enabled: bool,
|
|
383
|
+
is_input_plane_instance: bool = False,
|
|
263
384
|
):
|
|
264
385
|
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
265
386
|
...
|
|
266
387
|
|
|
388
|
+
def handle_map_start_or_continue_response(self, attempt_token: str): ...
|
|
267
389
|
def handle_put_inputs_response(self, item: modal_proto.api_pb2.FunctionPutInputsResponseItem): ...
|
|
268
390
|
async def handle_get_outputs_response(
|
|
269
391
|
self,
|
|
@@ -279,7 +401,9 @@ class _MapItemContext:
|
|
|
279
401
|
...
|
|
280
402
|
|
|
281
403
|
async def prepare_item_for_retry(self) -> modal_proto.api_pb2.FunctionRetryInputsItem: ...
|
|
404
|
+
def set_retry_policy(self, retry_policy: modal_proto.api_pb2.FunctionRetryPolicy): ...
|
|
282
405
|
def handle_retry_response(self, input_jwt: str): ...
|
|
406
|
+
async def create_map_start_or_continue_item(self, idx: int) -> modal_proto.api_pb2.MapStartOrContinueItem: ...
|
|
283
407
|
|
|
284
408
|
class _MapItemsManager:
|
|
285
409
|
def __init__(
|
|
@@ -289,22 +413,32 @@ class _MapItemsManager:
|
|
|
289
413
|
retry_queue: modal._utils.async_utils.TimestampPriorityQueue,
|
|
290
414
|
sync_client_retries_enabled: bool,
|
|
291
415
|
max_inputs_outstanding: int,
|
|
416
|
+
is_input_plane_instance: bool = False,
|
|
292
417
|
):
|
|
293
418
|
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
294
419
|
...
|
|
295
420
|
|
|
421
|
+
def set_retry_policy(self, retry_policy: modal_proto.api_pb2.FunctionRetryPolicy): ...
|
|
296
422
|
async def add_items(self, items: list[modal_proto.api_pb2.FunctionPutInputsItem]): ...
|
|
423
|
+
async def add_items_inputplane(self, items: list[modal_proto.api_pb2.MapStartOrContinueItem]): ...
|
|
297
424
|
async def prepare_items_for_retry(
|
|
298
425
|
self, retriable_idxs: list[int]
|
|
299
426
|
) -> list[modal_proto.api_pb2.FunctionRetryInputsItem]: ...
|
|
427
|
+
def update_items_retry_policy(self, retry_policy: modal_proto.api_pb2.FunctionRetryPolicy): ...
|
|
300
428
|
def get_input_jwts_waiting_for_output(self) -> list[str]:
|
|
301
429
|
"""Returns a list of input_jwts for inputs that are waiting for output."""
|
|
302
430
|
...
|
|
303
431
|
|
|
432
|
+
def get_input_idxs_waiting_for_output(self) -> list[tuple[int, str]]:
|
|
433
|
+
"""Returns a list of input_idxs for inputs that are waiting for output."""
|
|
434
|
+
...
|
|
435
|
+
|
|
304
436
|
def _remove_item(self, item_idx: int): ...
|
|
305
437
|
def get_item_context(self, item_idx: int) -> _MapItemContext: ...
|
|
438
|
+
def handle_put_continue_response(self, items: list[tuple[int, str]]): ...
|
|
306
439
|
def handle_put_inputs_response(self, items: list[modal_proto.api_pb2.FunctionPutInputsResponseItem]): ...
|
|
307
440
|
def handle_retry_response(self, input_jwts: list[str]): ...
|
|
441
|
+
async def handle_check_inputs_response(self, response: list[tuple[int, bool]]): ...
|
|
308
442
|
async def handle_get_outputs_response(
|
|
309
443
|
self, item: modal_proto.api_pb2.FunctionGetOutputsItem, now_seconds: int
|
|
310
444
|
) -> _OutputType: ...
|
modal/partial_function.pyi
CHANGED
|
@@ -329,7 +329,10 @@ def batched(
|
|
|
329
329
|
...
|
|
330
330
|
|
|
331
331
|
def concurrent(
|
|
332
|
-
_warn_parentheses_missing=None,
|
|
332
|
+
_warn_parentheses_missing=None,
|
|
333
|
+
*,
|
|
334
|
+
max_inputs: typing.Optional[int] = None,
|
|
335
|
+
target_inputs: typing.Optional[int] = None,
|
|
333
336
|
) -> collections.abc.Callable[
|
|
334
337
|
[
|
|
335
338
|
typing.Union[
|
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,15 +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,
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
response: api_pb2.ProxyGetResponse = await load_context.client.stub.ProxyGet(req)
|
|
40
|
+
self._hydrate(response.proxy.proxy_id, load_context.client, None)
|
|
41
|
+
|
|
42
|
+
rep = _Proxy._repr(name, environment_name)
|
|
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
|
+
)
|
|
40
49
|
|
|
41
50
|
|
|
42
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
|