modal 1.0.5.dev9__tar.gz → 1.0.5.dev10__tar.gz
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-1.0.5.dev9 → modal-1.0.5.dev10}/PKG-INFO +1 -1
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/client.pyi +2 -2
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/experimental/__init__.py +71 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/api.proto +20 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/api_grpc.py +32 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/api_pb2.py +617 -587
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/api_pb2.pyi +54 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/api_pb2_grpc.py +67 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/api_pb2_grpc.pyi +22 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/modal_api_grpc.py +2 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_version/__init__.py +1 -1
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/LICENSE +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/README.md +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/__main__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_clustered_functions.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_clustered_functions.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_container_entrypoint.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_functions.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_ipython.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_location.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_object.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_output.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_partial_function.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_pty.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_resolver.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_resources.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/asgi.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/execution_context.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/telemetry.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_serialization.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_traceback.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_tunnel.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_tunnel.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_type_manager.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/app_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/async_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/blob_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/deprecation.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/docker_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/function_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/git_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/hash_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/http_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/logger.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/mount_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/name_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/package_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/shell_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_utils/time_utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_vendor/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_vendor/tblib.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/_watcher.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/app.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/app.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/call_graph.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/_download.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/_traceback.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/app.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/cluster.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/config.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/container.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/dict.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/entry_point.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/environment.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/import_refs.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/launch.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/network_file_system.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/profile.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/programs/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/programs/vscode.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/queues.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/run.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/secret.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/token.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/utils.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cli/volume.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/client.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cls.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/cls.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/config.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/container_process.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/container_process.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/dict.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/dict.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/environments.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/environments.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/exception.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/experimental/ipython.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/file_io.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/file_io.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/file_pattern_matcher.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/functions.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/functions.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/gpu.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/image.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/image.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/io_streams.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/io_streams.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/mount.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/mount.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/network_file_system.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/network_file_system.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/object.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/object.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/output.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/parallel_map.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/parallel_map.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/partial_function.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/partial_function.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/proxy.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/proxy.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/py.typed +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/queue.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/queue.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/2023.12.312.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/2023.12.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/2024.04.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/2024.10.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/PREVIEW.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/README.md +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/requirements/base-images.json +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/retries.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/runner.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/runner.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/running_app.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/sandbox.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/sandbox.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/schedule.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/scheduler_placement.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/secret.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/secret.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/serving.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/serving.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/snapshot.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/snapshot.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/stream_type.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/token_flow.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/token_flow.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/volume.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal/volume.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal.egg-info/requires.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal.egg-info/top_level.txt +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_docs/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/__init__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/options.proto +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/options_grpc.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/options_pb2.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_proto/py.typed +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/modal_version/__main__.py +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/pyproject.toml +0 -0
- {modal-1.0.5.dev9 → modal-1.0.5.dev10}/setup.cfg +0 -0
@@ -31,7 +31,7 @@ class _Client:
|
|
31
31
|
server_url: str,
|
32
32
|
client_type: int,
|
33
33
|
credentials: typing.Optional[tuple[str, str]],
|
34
|
-
version: str = "1.0.5.
|
34
|
+
version: str = "1.0.5.dev10",
|
35
35
|
):
|
36
36
|
"""mdmd:hidden
|
37
37
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -160,7 +160,7 @@ class Client:
|
|
160
160
|
server_url: str,
|
161
161
|
client_type: int,
|
162
162
|
credentials: typing.Optional[tuple[str, str]],
|
163
|
-
version: str = "1.0.5.
|
163
|
+
version: str = "1.0.5.dev10",
|
164
164
|
):
|
165
165
|
"""mdmd:hidden
|
166
166
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# Copyright Modal Labs 2025
|
2
|
+
import asyncio
|
2
3
|
import os
|
4
|
+
import sys
|
3
5
|
from dataclasses import dataclass
|
4
6
|
from pathlib import Path
|
5
7
|
from typing import Literal, Optional, Union
|
@@ -11,11 +13,13 @@ from .._functions import _Function
|
|
11
13
|
from .._object import _get_environment_name
|
12
14
|
from .._partial_function import _clustered
|
13
15
|
from .._runtime.container_io_manager import _ContainerIOManager
|
16
|
+
from .._tunnel import _forward as _forward_tunnel
|
14
17
|
from .._utils.async_utils import synchronize_api, synchronizer
|
15
18
|
from .._utils.deprecation import deprecation_warning
|
16
19
|
from .._utils.grpc_utils import retry_transient_errors
|
17
20
|
from ..client import _Client
|
18
21
|
from ..cls import _Obj
|
22
|
+
from ..config import logger
|
19
23
|
from ..exception import InvalidError
|
20
24
|
from ..image import DockerfileSpec, ImageBuilderVersion, _Image, _ImageRegistryConfig
|
21
25
|
from ..secret import _Secret
|
@@ -209,3 +213,70 @@ async def update_autoscaler(
|
|
209
213
|
|
210
214
|
request = api_pb2.FunctionUpdateSchedulingParamsRequest(function_id=f.object_id, settings=settings)
|
211
215
|
await retry_transient_errors(client.stub.FunctionUpdateSchedulingParams, request)
|
216
|
+
|
217
|
+
|
218
|
+
class _FlashManager:
|
219
|
+
def __init__(self, client: _Client, port: int):
|
220
|
+
self.client = client
|
221
|
+
self.port = port
|
222
|
+
self.tunnel_manager = _forward_tunnel(port, client=client)
|
223
|
+
|
224
|
+
async def _start(self):
|
225
|
+
tunnel = await self.tunnel_manager.__aenter__()
|
226
|
+
|
227
|
+
host, port = tunnel.url.split("://")[1].split(":")
|
228
|
+
self.heartbeat_task = asyncio.create_task(self._run_heartbeat(host, int(port)))
|
229
|
+
|
230
|
+
async def _run_heartbeat(self, host: str, port: int):
|
231
|
+
first_registration = True
|
232
|
+
while True:
|
233
|
+
try:
|
234
|
+
resp = await self.client.stub.FlashContainerRegister(
|
235
|
+
api_pb2.FlashContainerRegisterRequest(
|
236
|
+
priority=10,
|
237
|
+
weight=5,
|
238
|
+
host=host,
|
239
|
+
port=port,
|
240
|
+
),
|
241
|
+
timeout=1,
|
242
|
+
)
|
243
|
+
if first_registration:
|
244
|
+
logger.warning(f"[Modal Flash] Listening at {resp.url}")
|
245
|
+
first_registration = False
|
246
|
+
except asyncio.CancelledError:
|
247
|
+
logger.warning("[Modal Flash] Shutting down...")
|
248
|
+
break
|
249
|
+
except Exception as e:
|
250
|
+
logger.error(f"[Modal Flash] Heartbeat failed: {e}")
|
251
|
+
|
252
|
+
try:
|
253
|
+
await asyncio.sleep(1)
|
254
|
+
except asyncio.CancelledError:
|
255
|
+
logger.warning("[Modal Flash] Shutting down...")
|
256
|
+
break
|
257
|
+
|
258
|
+
async def stop(self):
|
259
|
+
self.heartbeat_task.cancel()
|
260
|
+
await retry_transient_errors(
|
261
|
+
self.client.stub.FlashContainerDeregister,
|
262
|
+
api_pb2.FlashContainerDeregisterRequest(),
|
263
|
+
)
|
264
|
+
await self.tunnel_manager.__aexit__(*sys.exc_info())
|
265
|
+
|
266
|
+
|
267
|
+
FlashManager = synchronize_api(_FlashManager)
|
268
|
+
|
269
|
+
|
270
|
+
@synchronizer.create_blocking
|
271
|
+
async def flash_forward(port: int) -> _FlashManager:
|
272
|
+
"""
|
273
|
+
Forward a port to the Modal Flash service, exposing that port as a stable web endpoint.
|
274
|
+
|
275
|
+
This is a highly experimental method that can break or be removed at any time without warning.
|
276
|
+
Do not use this method unless explicitly instructed to do so by Modal support.
|
277
|
+
"""
|
278
|
+
client = await _Client.from_env()
|
279
|
+
|
280
|
+
manager = _FlashManager(client, port)
|
281
|
+
await manager._start()
|
282
|
+
return manager
|
@@ -1242,6 +1242,22 @@ message FilesystemRuntimeOutputBatch {
|
|
1242
1242
|
bool eof = 4;
|
1243
1243
|
}
|
1244
1244
|
|
1245
|
+
message FlashContainerDeregisterRequest {
|
1246
|
+
string service_name = 1;
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
message FlashContainerRegisterRequest {
|
1250
|
+
string service_name = 1;
|
1251
|
+
uint32 priority = 2;
|
1252
|
+
uint32 weight = 3;
|
1253
|
+
string host = 4;
|
1254
|
+
uint32 port = 5;
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
message FlashContainerRegisterResponse {
|
1258
|
+
string url = 1;
|
1259
|
+
}
|
1260
|
+
|
1245
1261
|
message Function {
|
1246
1262
|
string module_name = 1;
|
1247
1263
|
string function_name = 2;
|
@@ -3268,6 +3284,10 @@ service ModalClient {
|
|
3268
3284
|
rpc EnvironmentList(google.protobuf.Empty) returns (EnvironmentListResponse);
|
3269
3285
|
rpc EnvironmentUpdate(EnvironmentUpdateRequest) returns (EnvironmentListItem);
|
3270
3286
|
|
3287
|
+
// Modal Flash (experimental)
|
3288
|
+
rpc FlashContainerDeregister(FlashContainerDeregisterRequest) returns (google.protobuf.Empty);
|
3289
|
+
rpc FlashContainerRegister(FlashContainerRegisterRequest) returns (FlashContainerRegisterResponse);
|
3290
|
+
|
3271
3291
|
// Functions
|
3272
3292
|
rpc FunctionAsyncInvoke(FunctionAsyncInvokeRequest) returns (FunctionAsyncInvokeResponse);
|
3273
3293
|
rpc FunctionBindParams(FunctionBindParamsRequest) returns (FunctionBindParamsResponse);
|
@@ -242,6 +242,14 @@ class ModalClientBase(abc.ABC):
|
|
242
242
|
async def EnvironmentUpdate(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.EnvironmentUpdateRequest, modal_proto.api_pb2.EnvironmentListItem]') -> None:
|
243
243
|
pass
|
244
244
|
|
245
|
+
@abc.abstractmethod
|
246
|
+
async def FlashContainerDeregister(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FlashContainerDeregisterRequest, google.protobuf.empty_pb2.Empty]') -> None:
|
247
|
+
pass
|
248
|
+
|
249
|
+
@abc.abstractmethod
|
250
|
+
async def FlashContainerRegister(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FlashContainerRegisterRequest, modal_proto.api_pb2.FlashContainerRegisterResponse]') -> None:
|
251
|
+
pass
|
252
|
+
|
245
253
|
@abc.abstractmethod
|
246
254
|
async def FunctionAsyncInvoke(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.FunctionAsyncInvokeRequest, modal_proto.api_pb2.FunctionAsyncInvokeResponse]') -> None:
|
247
255
|
pass
|
@@ -968,6 +976,18 @@ class ModalClientBase(abc.ABC):
|
|
968
976
|
modal_proto.api_pb2.EnvironmentUpdateRequest,
|
969
977
|
modal_proto.api_pb2.EnvironmentListItem,
|
970
978
|
),
|
979
|
+
'/modal.client.ModalClient/FlashContainerDeregister': grpclib.const.Handler(
|
980
|
+
self.FlashContainerDeregister,
|
981
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
982
|
+
modal_proto.api_pb2.FlashContainerDeregisterRequest,
|
983
|
+
google.protobuf.empty_pb2.Empty,
|
984
|
+
),
|
985
|
+
'/modal.client.ModalClient/FlashContainerRegister': grpclib.const.Handler(
|
986
|
+
self.FlashContainerRegister,
|
987
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
988
|
+
modal_proto.api_pb2.FlashContainerRegisterRequest,
|
989
|
+
modal_proto.api_pb2.FlashContainerRegisterResponse,
|
990
|
+
),
|
971
991
|
'/modal.client.ModalClient/FunctionAsyncInvoke': grpclib.const.Handler(
|
972
992
|
self.FunctionAsyncInvoke,
|
973
993
|
grpclib.const.Cardinality.UNARY_UNARY,
|
@@ -1892,6 +1912,18 @@ class ModalClientStub:
|
|
1892
1912
|
modal_proto.api_pb2.EnvironmentUpdateRequest,
|
1893
1913
|
modal_proto.api_pb2.EnvironmentListItem,
|
1894
1914
|
)
|
1915
|
+
self.FlashContainerDeregister = grpclib.client.UnaryUnaryMethod(
|
1916
|
+
channel,
|
1917
|
+
'/modal.client.ModalClient/FlashContainerDeregister',
|
1918
|
+
modal_proto.api_pb2.FlashContainerDeregisterRequest,
|
1919
|
+
google.protobuf.empty_pb2.Empty,
|
1920
|
+
)
|
1921
|
+
self.FlashContainerRegister = grpclib.client.UnaryUnaryMethod(
|
1922
|
+
channel,
|
1923
|
+
'/modal.client.ModalClient/FlashContainerRegister',
|
1924
|
+
modal_proto.api_pb2.FlashContainerRegisterRequest,
|
1925
|
+
modal_proto.api_pb2.FlashContainerRegisterResponse,
|
1926
|
+
)
|
1895
1927
|
self.FunctionAsyncInvoke = grpclib.client.UnaryUnaryMethod(
|
1896
1928
|
channel,
|
1897
1929
|
'/modal.client.ModalClient/FunctionAsyncInvoke',
|