modAL 1.3.2.dev0__tar.gz → 1.3.3.dev0__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.3.2.dev0 → modal-1.3.3.dev0}/PKG-INFO +1 -1
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_object.py +40 -35
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_output.py +2 -1
- modal-1.3.3.dev0/modal/_utils/browser_utils.py +28 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/app.pyi +3 -3
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/_download.py +2 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/app.py +34 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/container.py +9 -1
- modal-1.3.3.dev0/modal/cli/dashboard.py +30 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/entry_point.py +3 -1
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/utils.py +4 -2
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/volume.py +28 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/client.pyi +2 -2
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/config.py +1 -1
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/functions.pyi +6 -6
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/image.pyi +1 -1
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/object.pyi +24 -57
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/partial_function.pyi +1 -2
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/runner.py +1 -5
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/token_flow.py +2 -17
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/token_flow.pyi +0 -3
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/volume.py +11 -4
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/volume.pyi +3 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal.egg-info/SOURCES.txt +2 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_docs/gen_reference_docs.py +1 -1
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/api.proto +10 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/api_grpc.py +16 -0
- modal-1.3.3.dev0/modal_proto/api_pb2.py +1139 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/api_pb2.pyi +28 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/api_pb2_grpc.py +33 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/api_pb2_grpc.pyi +10 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/modal_api_grpc.py +1 -0
- modal-1.3.3.dev0/modal_proto/task_command_router_pb2.py +60 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_version/__init__.py +1 -1
- modal-1.3.2.dev0/modal_proto/api_pb2.py +0 -5230
- modal-1.3.2.dev0/modal_proto/task_command_router_pb2.py +0 -180
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/LICENSE +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/README.md +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/__main__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_billing.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_clustered_functions.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_clustered_functions.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_container_entrypoint.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_functions.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_grpc_client.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_ipython.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_load_context.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_location.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_partial_function.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_pty.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_resolver.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_resources.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/asgi.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/execution_context.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/telemetry.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_serialization.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_server.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_traceback.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_tunnel.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_tunnel.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_type_manager.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/app_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/async_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/blob_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/deprecation.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/docker_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/function_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/git_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/hash_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/http_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/logger.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/mount_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/name_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/package_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/shell_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_utils/time_utils.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_vendor/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_vendor/tblib.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/_watcher.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/app.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/billing.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/2023.12.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/2024.04.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/2024.10.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/2025.06.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/README.md +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/builder/base-images.json +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/call_graph.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/_traceback.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/cluster.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/config.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/dict.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/environment.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/import_refs.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/launch.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/network_file_system.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/profile.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/programs/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/programs/vscode.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/queues.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/run.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/secret.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/shell.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cli/token.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/client.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cls.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/cls.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/container_process.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/container_process.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/dict.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/dict.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/environments.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/environments.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/exception.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/experimental/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/experimental/flash.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/experimental/flash.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/experimental/ipython.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/file_io.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/file_io.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/file_pattern_matcher.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/functions.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/gpu.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/image.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/io_streams.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/io_streams.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/mount.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/mount.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/network_file_system.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/network_file_system.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/object.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/output.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/parallel_map.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/parallel_map.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/partial_function.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/proxy.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/proxy.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/py.typed +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/queue.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/queue.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/retries.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/runner.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/running_app.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/sandbox.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/sandbox.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/schedule.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/scheduler_placement.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/secret.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/secret.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/server.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/server.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/serving.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/serving.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/snapshot.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/snapshot.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal/stream_type.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal.egg-info/requires.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal.egg-info/top_level.txt +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_docs/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/__init__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/py.typed +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/task_command_router.proto +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/modal_version/__main__.py +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/pyproject.toml +0 -0
- {modal-1.3.2.dev0 → modal-1.3.3.dev0}/setup.cfg +0 -0
|
@@ -39,6 +39,41 @@ def _get_environment_name(
|
|
|
39
39
|
return config.get("environment")
|
|
40
40
|
|
|
41
41
|
|
|
42
|
+
def live_method(method):
|
|
43
|
+
@wraps(method)
|
|
44
|
+
async def wrapped(self, *args, **kwargs):
|
|
45
|
+
await self.hydrate()
|
|
46
|
+
return await method(self, *args, **kwargs)
|
|
47
|
+
|
|
48
|
+
return wrapped
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def live_method_gen(method):
|
|
52
|
+
@wraps(method)
|
|
53
|
+
async def wrapped(self, *args, **kwargs):
|
|
54
|
+
await self.hydrate()
|
|
55
|
+
async with aclosing(method(self, *args, **kwargs)) as stream:
|
|
56
|
+
async for item in stream:
|
|
57
|
+
yield item
|
|
58
|
+
|
|
59
|
+
return wrapped
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def live_method_contextmanager(method):
|
|
63
|
+
# make sure a wrapped function returning an async context manager
|
|
64
|
+
# will not require both an `await func.aio()` and `async with`
|
|
65
|
+
# which would have been the case if it was wrapped in live_method
|
|
66
|
+
|
|
67
|
+
@wraps(method)
|
|
68
|
+
@contextlib.asynccontextmanager
|
|
69
|
+
async def wrapped(self, *args, **kwargs):
|
|
70
|
+
await self.hydrate()
|
|
71
|
+
async with method(self, *args, **kwargs) as ctx:
|
|
72
|
+
yield ctx
|
|
73
|
+
|
|
74
|
+
return wrapped
|
|
75
|
+
|
|
76
|
+
|
|
42
77
|
class _Object:
|
|
43
78
|
_type_prefix: ClassVar[Optional[str]] = None
|
|
44
79
|
_prefix_to_type: ClassVar[dict[str, type]] = {}
|
|
@@ -275,6 +310,11 @@ class _Object:
|
|
|
275
310
|
raise AttributeError(f"Attempting to get object_id of unhydrated {self}")
|
|
276
311
|
return self._object_id
|
|
277
312
|
|
|
313
|
+
@live_method
|
|
314
|
+
async def get_dashboard_url(self) -> str:
|
|
315
|
+
"""mdmd:hidden"""
|
|
316
|
+
return f"https://modal.com/id/{self.object_id}"
|
|
317
|
+
|
|
278
318
|
@property
|
|
279
319
|
def client(self) -> _Client:
|
|
280
320
|
"""mdmd:hidden"""
|
|
@@ -336,38 +376,3 @@ class _Object:
|
|
|
336
376
|
with suppress_tb_frame(): # skip this frame by default
|
|
337
377
|
await resolver.load(self, root_load_context)
|
|
338
378
|
return self
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
def live_method(method):
|
|
342
|
-
@wraps(method)
|
|
343
|
-
async def wrapped(self, *args, **kwargs):
|
|
344
|
-
await self.hydrate()
|
|
345
|
-
return await method(self, *args, **kwargs)
|
|
346
|
-
|
|
347
|
-
return wrapped
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
def live_method_gen(method):
|
|
351
|
-
@wraps(method)
|
|
352
|
-
async def wrapped(self, *args, **kwargs):
|
|
353
|
-
await self.hydrate()
|
|
354
|
-
async with aclosing(method(self, *args, **kwargs)) as stream:
|
|
355
|
-
async for item in stream:
|
|
356
|
-
yield item
|
|
357
|
-
|
|
358
|
-
return wrapped
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
def live_method_contextmanager(method):
|
|
362
|
-
# make sure a wrapped function returning an async context manager
|
|
363
|
-
# will not require both an `await func.aio()` and `async with`
|
|
364
|
-
# which would have been the case if it was wrapped in live_method
|
|
365
|
-
|
|
366
|
-
@wraps(method)
|
|
367
|
-
@contextlib.asynccontextmanager
|
|
368
|
-
async def wrapped(self, *args, **kwargs):
|
|
369
|
-
await self.hydrate()
|
|
370
|
-
async with method(self, *args, **kwargs) as ctx:
|
|
371
|
-
yield ctx
|
|
372
|
-
|
|
373
|
-
return wrapped
|
|
@@ -545,7 +545,7 @@ async def get_app_logs_loop(
|
|
|
545
545
|
output_mgr: OutputManager,
|
|
546
546
|
app_id: str | None = None,
|
|
547
547
|
task_id: str | None = None,
|
|
548
|
-
|
|
548
|
+
sandbox_id: str | None = None,
|
|
549
549
|
):
|
|
550
550
|
last_log_batch_entry_id = ""
|
|
551
551
|
|
|
@@ -600,6 +600,7 @@ async def get_app_logs_loop(
|
|
|
600
600
|
request = api_pb2.AppGetLogsRequest(
|
|
601
601
|
app_id=app_id or "",
|
|
602
602
|
task_id=task_id or "",
|
|
603
|
+
sandbox_id=sandbox_id or "",
|
|
603
604
|
timeout=55,
|
|
604
605
|
last_entry_id=last_log_batch_entry_id,
|
|
605
606
|
)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Copyright Modal Labs 2026
|
|
2
|
+
import webbrowser
|
|
3
|
+
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def open_url(url: str) -> bool:
|
|
8
|
+
"""Opens url in web browser, making sure we use a modern one (not Lynx etc)"""
|
|
9
|
+
try:
|
|
10
|
+
browser = webbrowser.get()
|
|
11
|
+
# zpresto defines `BROWSER=open` by default on macOS, which causes `webbrowser` to return `GenericBrowser`.
|
|
12
|
+
if isinstance(browser, webbrowser.GenericBrowser) and browser.name != "open":
|
|
13
|
+
return False
|
|
14
|
+
else:
|
|
15
|
+
return browser.open_new_tab(url)
|
|
16
|
+
except webbrowser.Error:
|
|
17
|
+
return False
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def open_url_and_display(url: str, target: str, console: Console) -> None:
|
|
21
|
+
"""Open a URL in the web browser and display it to the user."""
|
|
22
|
+
if open_url(url):
|
|
23
|
+
console.print(f"Opening {target} in your web browser...")
|
|
24
|
+
console.print(f"[link={url}]{url}[/link]")
|
|
25
|
+
else:
|
|
26
|
+
console.print("[yellow]Could not open web browser automatically.[/yellow]")
|
|
27
|
+
console.print("Please open this URL in your browser:")
|
|
28
|
+
console.print(f"[link={url}]{url}[/link]")
|
|
@@ -309,7 +309,7 @@ class _App:
|
|
|
309
309
|
environment_name: typing.Optional[str] = None,
|
|
310
310
|
tag: str = "",
|
|
311
311
|
client: typing.Optional[modal.client._Client] = None,
|
|
312
|
-
) ->
|
|
312
|
+
) -> typing.Self:
|
|
313
313
|
"""Deploy the App so that it is available persistently.
|
|
314
314
|
|
|
315
315
|
Deployed Apps will be available for lookup or web-based invocations until they are stopped.
|
|
@@ -625,7 +625,7 @@ class _App:
|
|
|
625
625
|
"""
|
|
626
626
|
...
|
|
627
627
|
|
|
628
|
-
def include(self, /, other_app: _App, inherit_tags: bool = True) ->
|
|
628
|
+
def include(self, /, other_app: _App, inherit_tags: bool = True) -> typing.Self:
|
|
629
629
|
"""Include another App's objects in this one.
|
|
630
630
|
|
|
631
631
|
Useful for splitting up Modal Apps across different self-contained files.
|
|
@@ -1347,7 +1347,7 @@ class App:
|
|
|
1347
1347
|
"""
|
|
1348
1348
|
...
|
|
1349
1349
|
|
|
1350
|
-
def include(self, /, other_app: App, inherit_tags: bool = True) ->
|
|
1350
|
+
def include(self, /, other_app: App, inherit_tags: bool = True) -> typing.Self:
|
|
1351
1351
|
"""Include another App's objects in this one.
|
|
1352
1352
|
|
|
1353
1353
|
Useful for splitting up Modal Apps across different self-contained files.
|
|
@@ -40,6 +40,7 @@ async def _volume_download(
|
|
|
40
40
|
q: asyncio.Queue[tuple[Optional[Path], Optional[FileEntry]]] = asyncio.Queue()
|
|
41
41
|
num_consumers = 1 if is_pipe else concurrency # concurrency limit for downloading files
|
|
42
42
|
download_semaphore = asyncio.Semaphore(concurrency)
|
|
43
|
+
rpc_semaphore = asyncio.Semaphore(64) # Limit concurrent RPCs to avoid overwhelming server.
|
|
43
44
|
|
|
44
45
|
async def producer():
|
|
45
46
|
iterator: AsyncIterator[FileEntry]
|
|
@@ -101,6 +102,7 @@ async def _volume_download(
|
|
|
101
102
|
path=entry.path,
|
|
102
103
|
fileobj=fp,
|
|
103
104
|
download_semaphore=download_semaphore,
|
|
105
|
+
rpc_semaphore=rpc_semaphore,
|
|
104
106
|
progress_cb=file_progress_cb,
|
|
105
107
|
)
|
|
106
108
|
else:
|
|
@@ -10,7 +10,9 @@ from rich.text import Text
|
|
|
10
10
|
from typer import Argument
|
|
11
11
|
|
|
12
12
|
from modal._object import _get_environment_name
|
|
13
|
+
from modal._output import make_console
|
|
13
14
|
from modal._utils.async_utils import synchronizer
|
|
15
|
+
from modal._utils.browser_utils import open_url_and_display
|
|
14
16
|
from modal.client import _Client
|
|
15
17
|
from modal.environments import ensure_env
|
|
16
18
|
from modal_proto import api_pb2
|
|
@@ -248,3 +250,35 @@ async def history(
|
|
|
248
250
|
|
|
249
251
|
if deployments_with_dirty_commit and not json:
|
|
250
252
|
rich.print("* - repo had uncommitted changes")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@app_cli.command("dashboard", no_args_is_help=True)
|
|
256
|
+
@synchronizer.create_blocking
|
|
257
|
+
async def dashboard(
|
|
258
|
+
app_identifier: str = APP_IDENTIFIER,
|
|
259
|
+
*,
|
|
260
|
+
env: Optional[str] = ENV_OPTION,
|
|
261
|
+
):
|
|
262
|
+
"""Open an App's dashboard page in your web browser.
|
|
263
|
+
|
|
264
|
+
**Examples:**
|
|
265
|
+
|
|
266
|
+
Open dashboard for an app by name:
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
modal app dashboard my-app
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Use a specified environment:
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
modal app dashboard my-app --env dev
|
|
276
|
+
```
|
|
277
|
+
"""
|
|
278
|
+
client = await _Client.from_env()
|
|
279
|
+
app_id = await get_app_id.aio(app_identifier, env, client)
|
|
280
|
+
|
|
281
|
+
console = make_console()
|
|
282
|
+
url = f"https://modal.com/id/{app_id}"
|
|
283
|
+
|
|
284
|
+
open_url_and_display(url, "App dashboard", console)
|
|
@@ -13,6 +13,7 @@ from modal.client import _Client
|
|
|
13
13
|
from modal.config import config
|
|
14
14
|
from modal.container_process import _ContainerProcess
|
|
15
15
|
from modal.environments import ensure_env
|
|
16
|
+
from modal.exception import InvalidError
|
|
16
17
|
from modal.stream_type import StreamType
|
|
17
18
|
from modal_proto import api_pb2
|
|
18
19
|
|
|
@@ -52,7 +53,14 @@ def logs(
|
|
|
52
53
|
timestamps: bool = typer.Option(False, "--timestamps", help="Show timestamps for each log line"),
|
|
53
54
|
):
|
|
54
55
|
"""Show logs for a specific container, streaming while active."""
|
|
55
|
-
|
|
56
|
+
task_id, sandbox_id = None, None
|
|
57
|
+
if container_id.startswith("sb-"):
|
|
58
|
+
sandbox_id = container_id
|
|
59
|
+
elif container_id.startswith("ta-"):
|
|
60
|
+
task_id = container_id
|
|
61
|
+
else:
|
|
62
|
+
raise InvalidError(f"Invalid container ID: {container_id}")
|
|
63
|
+
stream_app_logs(task_id=task_id, sandbox_id=sandbox_id, show_timestamps=timestamps)
|
|
56
64
|
|
|
57
65
|
|
|
58
66
|
@container_cli.command("exec")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Copyright Modal Labs 2026
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
import typer
|
|
5
|
+
|
|
6
|
+
from modal._output import make_console
|
|
7
|
+
from modal._utils.async_utils import synchronizer
|
|
8
|
+
from modal._utils.browser_utils import open_url_and_display
|
|
9
|
+
from modal.client import _Client
|
|
10
|
+
from modal.config import config
|
|
11
|
+
from modal_proto import api_pb2
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@synchronizer.create_blocking
|
|
15
|
+
async def dashboard(
|
|
16
|
+
object_id: Optional[str] = typer.Argument(None, help="Open a view for a specific object."),
|
|
17
|
+
):
|
|
18
|
+
"""Open the Modal Dashboard in a web browser."""
|
|
19
|
+
console = make_console()
|
|
20
|
+
|
|
21
|
+
if object_id:
|
|
22
|
+
url = f"https://modal.com/id/{object_id}"
|
|
23
|
+
else:
|
|
24
|
+
env = config.get("environment")
|
|
25
|
+
request = api_pb2.WorkspaceDashboardUrlRequest(environment_name=env)
|
|
26
|
+
client = await _Client.from_env()
|
|
27
|
+
response = await client.stub.WorkspaceDashboardUrlGet(request)
|
|
28
|
+
url = response.url
|
|
29
|
+
|
|
30
|
+
open_url_and_display(url, "dashboard", console)
|
|
@@ -13,6 +13,7 @@ from .app import app_cli
|
|
|
13
13
|
from .cluster import cluster_cli
|
|
14
14
|
from .config import config_cli
|
|
15
15
|
from .container import container_cli
|
|
16
|
+
from .dashboard import dashboard
|
|
16
17
|
from .dict import dict_cli
|
|
17
18
|
from .environment import environment_cli
|
|
18
19
|
from .launch import launch_cli
|
|
@@ -118,6 +119,7 @@ async def setup(profile: Optional[str] = None):
|
|
|
118
119
|
entrypoint_cli_typer.command("deploy", no_args_is_help=True)(run.deploy)
|
|
119
120
|
entrypoint_cli_typer.command("serve", no_args_is_help=True)(run.serve)
|
|
120
121
|
entrypoint_cli_typer.command("shell")(shell_module.shell)
|
|
122
|
+
entrypoint_cli_typer.command("dashboard")(dashboard)
|
|
121
123
|
entrypoint_cli_typer.add_typer(launch_cli)
|
|
122
124
|
|
|
123
125
|
# Deployments
|
|
@@ -128,7 +130,7 @@ entrypoint_cli_typer.add_typer(cluster_cli, rich_help_panel="Deployments", hidde
|
|
|
128
130
|
|
|
129
131
|
# Storage
|
|
130
132
|
entrypoint_cli_typer.add_typer(dict_cli, rich_help_panel="Storage")
|
|
131
|
-
entrypoint_cli_typer.add_typer(nfs_cli, rich_help_panel="Storage")
|
|
133
|
+
entrypoint_cli_typer.add_typer(nfs_cli, rich_help_panel="Storage", hidden=True)
|
|
132
134
|
entrypoint_cli_typer.add_typer(secret_cli, rich_help_panel="Storage")
|
|
133
135
|
entrypoint_cli_typer.add_typer(queue_cli, rich_help_panel="Storage")
|
|
134
136
|
entrypoint_cli_typer.add_typer(volume_cli, rich_help_panel="Storage")
|
|
@@ -21,14 +21,16 @@ from ..exception import NotFoundError
|
|
|
21
21
|
async def stream_app_logs(
|
|
22
22
|
app_id: Optional[str] = None,
|
|
23
23
|
task_id: Optional[str] = None,
|
|
24
|
+
sandbox_id: Optional[str] = None,
|
|
24
25
|
app_logs_url: Optional[str] = None,
|
|
25
26
|
show_timestamps: bool = False,
|
|
26
27
|
):
|
|
27
28
|
client = await _Client.from_env()
|
|
28
|
-
|
|
29
|
+
display_id = app_id or task_id or sandbox_id
|
|
30
|
+
output_mgr = OutputManager(status_spinner_text=f"Tailing logs for {display_id}", show_timestamps=show_timestamps)
|
|
29
31
|
try:
|
|
30
32
|
with output_mgr.show_status_spinner():
|
|
31
|
-
await get_app_logs_loop(client, output_mgr, app_id=app_id, task_id=task_id,
|
|
33
|
+
await get_app_logs_loop(client, output_mgr, app_id=app_id, task_id=task_id, sandbox_id=sandbox_id)
|
|
32
34
|
except asyncio.CancelledError:
|
|
33
35
|
pass
|
|
34
36
|
except KeyboardInterrupt:
|
|
@@ -12,6 +12,7 @@ from typer import Argument, Option, Typer
|
|
|
12
12
|
import modal
|
|
13
13
|
from modal._output import OutputManager, ProgressHandler, make_console
|
|
14
14
|
from modal._utils.async_utils import synchronizer
|
|
15
|
+
from modal._utils.browser_utils import open_url_and_display
|
|
15
16
|
from modal._utils.time_utils import timestamp_to_localized_str
|
|
16
17
|
from modal.cli._download import _volume_download
|
|
17
18
|
from modal.cli.utils import ENV_OPTION, YES_OPTION, display_table
|
|
@@ -310,3 +311,30 @@ async def rename(
|
|
|
310
311
|
)
|
|
311
312
|
|
|
312
313
|
await _Volume.rename(old_name, new_name, environment_name=env)
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
@volume_cli.command(
|
|
317
|
+
name="dashboard",
|
|
318
|
+
help="Open the Volume's dashboard page in your web browser.",
|
|
319
|
+
rich_help_panel="Management",
|
|
320
|
+
)
|
|
321
|
+
@synchronizer.create_blocking
|
|
322
|
+
async def dashboard(
|
|
323
|
+
volume_name: str = Argument(help="Name of the Volume to view in the dashboard."),
|
|
324
|
+
env: Optional[str] = ENV_OPTION,
|
|
325
|
+
):
|
|
326
|
+
"""Open a Volume's dashboard page in your web browser.
|
|
327
|
+
|
|
328
|
+
**Example:**
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
modal volume dashboard my-volume
|
|
332
|
+
```
|
|
333
|
+
"""
|
|
334
|
+
env = ensure_env(env)
|
|
335
|
+
volume = await _Volume.from_name(volume_name, environment_name=env).hydrate()
|
|
336
|
+
|
|
337
|
+
console = make_console()
|
|
338
|
+
url = f"https://modal.com/id/{volume.object_id}"
|
|
339
|
+
|
|
340
|
+
open_url_and_display(url, "Volume dashboard", console)
|
|
@@ -35,7 +35,7 @@ class _Client:
|
|
|
35
35
|
server_url: str,
|
|
36
36
|
client_type: int,
|
|
37
37
|
credentials: typing.Optional[tuple[str, str]],
|
|
38
|
-
version: str = "1.3.
|
|
38
|
+
version: str = "1.3.3.dev0",
|
|
39
39
|
):
|
|
40
40
|
"""mdmd:hidden
|
|
41
41
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -171,7 +171,7 @@ class Client:
|
|
|
171
171
|
server_url: str,
|
|
172
172
|
client_type: int,
|
|
173
173
|
credentials: typing.Optional[tuple[str, str]],
|
|
174
|
-
version: str = "1.3.
|
|
174
|
+
version: str = "1.3.3.dev0",
|
|
175
175
|
):
|
|
176
176
|
"""mdmd:hidden
|
|
177
177
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -261,7 +261,7 @@ _SETTINGS = {
|
|
|
261
261
|
),
|
|
262
262
|
"dev_suffix": _Setting("", transform=_enforce_suffix_rules),
|
|
263
263
|
"max_throttle_wait": _Setting(None, transform=lambda x: int(x) if x else None),
|
|
264
|
-
"async_warnings": _Setting(
|
|
264
|
+
"async_warnings": _Setting(True, transform=_to_boolean), # Activate synchronicity usage warnings
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
|
|
@@ -408,7 +408,7 @@ class Function(
|
|
|
408
408
|
|
|
409
409
|
_call_generator: ___call_generator_spec
|
|
410
410
|
|
|
411
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
411
|
+
class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
412
412
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
413
413
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
|
414
414
|
...
|
|
@@ -417,7 +417,7 @@ class Function(
|
|
|
417
417
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
|
418
418
|
...
|
|
419
419
|
|
|
420
|
-
remote: __remote_spec[modal._functions.
|
|
420
|
+
remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
|
|
421
421
|
|
|
422
422
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
423
423
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -444,7 +444,7 @@ class Function(
|
|
|
444
444
|
"""
|
|
445
445
|
...
|
|
446
446
|
|
|
447
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
447
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
448
448
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
449
449
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
450
450
|
|
|
@@ -467,7 +467,7 @@ class Function(
|
|
|
467
467
|
"""
|
|
468
468
|
...
|
|
469
469
|
|
|
470
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
470
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
|
|
471
471
|
|
|
472
472
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
473
473
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -475,7 +475,7 @@ class Function(
|
|
|
475
475
|
|
|
476
476
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
477
477
|
|
|
478
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
478
|
+
class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
479
479
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
480
480
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
481
481
|
|
|
@@ -496,7 +496,7 @@ class Function(
|
|
|
496
496
|
"""
|
|
497
497
|
...
|
|
498
498
|
|
|
499
|
-
spawn: __spawn_spec[modal._functions.
|
|
499
|
+
spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
|
|
500
500
|
|
|
501
501
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
502
502
|
"""Return the inner Python object wrapped by this Modal Function."""
|
|
@@ -1041,7 +1041,7 @@ class _Image(modal._object._Object):
|
|
|
1041
1041
|
"""
|
|
1042
1042
|
...
|
|
1043
1043
|
|
|
1044
|
-
async def hydrate(self, client: typing.Optional[modal.client._Client] = None) ->
|
|
1044
|
+
async def hydrate(self, client: typing.Optional[modal.client._Client] = None) -> typing.Self:
|
|
1045
1045
|
"""mdmd:hidden"""
|
|
1046
1046
|
...
|
|
1047
1047
|
|
|
@@ -13,13 +13,13 @@ class Object:
|
|
|
13
13
|
_prefix_to_type: typing.ClassVar[dict[str, type]]
|
|
14
14
|
_load: typing.Optional[
|
|
15
15
|
collections.abc.Callable[
|
|
16
|
-
[
|
|
16
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
17
17
|
collections.abc.Awaitable[None],
|
|
18
18
|
]
|
|
19
19
|
]
|
|
20
20
|
_preload: typing.Optional[
|
|
21
21
|
collections.abc.Callable[
|
|
22
|
-
[
|
|
22
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
23
23
|
collections.abc.Awaitable[None],
|
|
24
24
|
]
|
|
25
25
|
]
|
|
@@ -51,25 +51,13 @@ class Object:
|
|
|
51
51
|
rep: str,
|
|
52
52
|
load: typing.Optional[
|
|
53
53
|
collections.abc.Callable[
|
|
54
|
-
[
|
|
55
|
-
typing_extensions.Self,
|
|
56
|
-
modal._resolver.Resolver,
|
|
57
|
-
modal._load_context.LoadContext,
|
|
58
|
-
typing.Optional[str],
|
|
59
|
-
],
|
|
60
|
-
None,
|
|
54
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]], None
|
|
61
55
|
]
|
|
62
56
|
] = None,
|
|
63
57
|
is_another_app: bool = False,
|
|
64
58
|
preload: typing.Optional[
|
|
65
59
|
collections.abc.Callable[
|
|
66
|
-
[
|
|
67
|
-
typing_extensions.Self,
|
|
68
|
-
modal._resolver.Resolver,
|
|
69
|
-
modal._load_context.LoadContext,
|
|
70
|
-
typing.Optional[str],
|
|
71
|
-
],
|
|
72
|
-
None,
|
|
60
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]], None
|
|
73
61
|
]
|
|
74
62
|
] = None,
|
|
75
63
|
hydrate_lazily: bool = False,
|
|
@@ -85,24 +73,14 @@ class Object:
|
|
|
85
73
|
rep: str,
|
|
86
74
|
load: typing.Optional[
|
|
87
75
|
collections.abc.Callable[
|
|
88
|
-
[
|
|
89
|
-
typing_extensions.Self,
|
|
90
|
-
modal._resolver.Resolver,
|
|
91
|
-
modal._load_context.LoadContext,
|
|
92
|
-
typing.Optional[str],
|
|
93
|
-
],
|
|
76
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
94
77
|
collections.abc.Awaitable[None],
|
|
95
78
|
]
|
|
96
79
|
] = None,
|
|
97
80
|
is_another_app: bool = False,
|
|
98
81
|
preload: typing.Optional[
|
|
99
82
|
collections.abc.Callable[
|
|
100
|
-
[
|
|
101
|
-
typing_extensions.Self,
|
|
102
|
-
modal._resolver.Resolver,
|
|
103
|
-
modal._load_context.LoadContext,
|
|
104
|
-
typing.Optional[str],
|
|
105
|
-
],
|
|
83
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
106
84
|
collections.abc.Awaitable[None],
|
|
107
85
|
]
|
|
108
86
|
] = None,
|
|
@@ -127,7 +105,7 @@ class Object:
|
|
|
127
105
|
def _hydrate_metadata(self, metadata: typing.Optional[google.protobuf.message.Message]): ...
|
|
128
106
|
def _get_metadata(self) -> typing.Optional[google.protobuf.message.Message]: ...
|
|
129
107
|
def _validate_is_hydrated(self): ...
|
|
130
|
-
def clone(self) ->
|
|
108
|
+
def clone(self) -> typing.Self:
|
|
131
109
|
"""mdmd:hidden Clone a given hydrated object.
|
|
132
110
|
|
|
133
111
|
Note: This is not intended to be public API and has no public use. It will be removed in a future release.
|
|
@@ -139,25 +117,13 @@ class Object:
|
|
|
139
117
|
self,
|
|
140
118
|
/,
|
|
141
119
|
load: collections.abc.Callable[
|
|
142
|
-
[
|
|
143
|
-
typing_extensions.Self,
|
|
144
|
-
modal._resolver.Resolver,
|
|
145
|
-
modal._load_context.LoadContext,
|
|
146
|
-
typing.Optional[str],
|
|
147
|
-
],
|
|
148
|
-
None,
|
|
120
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]], None
|
|
149
121
|
],
|
|
150
122
|
rep: str,
|
|
151
123
|
is_another_app: bool = False,
|
|
152
124
|
preload: typing.Optional[
|
|
153
125
|
collections.abc.Callable[
|
|
154
|
-
[
|
|
155
|
-
typing_extensions.Self,
|
|
156
|
-
modal._resolver.Resolver,
|
|
157
|
-
modal._load_context.LoadContext,
|
|
158
|
-
typing.Optional[str],
|
|
159
|
-
],
|
|
160
|
-
None,
|
|
126
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]], None
|
|
161
127
|
]
|
|
162
128
|
] = None,
|
|
163
129
|
hydrate_lazily: bool = False,
|
|
@@ -171,24 +137,14 @@ class Object:
|
|
|
171
137
|
self,
|
|
172
138
|
/,
|
|
173
139
|
load: collections.abc.Callable[
|
|
174
|
-
[
|
|
175
|
-
typing_extensions.Self,
|
|
176
|
-
modal._resolver.Resolver,
|
|
177
|
-
modal._load_context.LoadContext,
|
|
178
|
-
typing.Optional[str],
|
|
179
|
-
],
|
|
140
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
180
141
|
collections.abc.Awaitable[None],
|
|
181
142
|
],
|
|
182
143
|
rep: str,
|
|
183
144
|
is_another_app: bool = False,
|
|
184
145
|
preload: typing.Optional[
|
|
185
146
|
collections.abc.Callable[
|
|
186
|
-
[
|
|
187
|
-
typing_extensions.Self,
|
|
188
|
-
modal._resolver.Resolver,
|
|
189
|
-
modal._load_context.LoadContext,
|
|
190
|
-
typing.Optional[str],
|
|
191
|
-
],
|
|
147
|
+
[typing.Self, modal._resolver.Resolver, modal._load_context.LoadContext, typing.Optional[str]],
|
|
192
148
|
collections.abc.Awaitable[None],
|
|
193
149
|
]
|
|
194
150
|
] = None,
|
|
@@ -218,8 +174,8 @@ class Object:
|
|
|
218
174
|
handle_metadata: typing.Optional[google.protobuf.message.Message],
|
|
219
175
|
is_another_app: bool = False,
|
|
220
176
|
rep: typing.Optional[str] = None,
|
|
221
|
-
) ->
|
|
222
|
-
def _hydrate_from_other(self, other:
|
|
177
|
+
) -> typing.Self: ...
|
|
178
|
+
def _hydrate_from_other(self, other: typing.Self): ...
|
|
223
179
|
def __repr__(self): ...
|
|
224
180
|
@property
|
|
225
181
|
def local_uuid(self):
|
|
@@ -231,6 +187,17 @@ class Object:
|
|
|
231
187
|
"""mdmd:hidden"""
|
|
232
188
|
...
|
|
233
189
|
|
|
190
|
+
class __get_dashboard_url_spec(typing_extensions.Protocol):
|
|
191
|
+
def __call__(self, /) -> str:
|
|
192
|
+
"""mdmd:hidden"""
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
async def aio(self, /) -> str:
|
|
196
|
+
"""mdmd:hidden"""
|
|
197
|
+
...
|
|
198
|
+
|
|
199
|
+
get_dashboard_url: __get_dashboard_url_spec
|
|
200
|
+
|
|
234
201
|
@property
|
|
235
202
|
def client(self) -> modal.client.Client:
|
|
236
203
|
"""mdmd:hidden"""
|
|
@@ -2,7 +2,6 @@ import collections.abc
|
|
|
2
2
|
import modal._partial_function
|
|
3
3
|
import modal.functions
|
|
4
4
|
import typing
|
|
5
|
-
import typing_extensions
|
|
6
5
|
|
|
7
6
|
class PartialFunction(
|
|
8
7
|
typing.Generic[
|
|
@@ -31,7 +30,7 @@ class PartialFunction(
|
|
|
31
30
|
self,
|
|
32
31
|
flags: modal._partial_function._PartialFunctionFlags,
|
|
33
32
|
params: modal._partial_function._PartialFunctionParams,
|
|
34
|
-
) ->
|
|
33
|
+
) -> typing.Self:
|
|
35
34
|
"""Implement decorator composition by combining the flags and params."""
|
|
36
35
|
...
|
|
37
36
|
|
|
@@ -340,11 +340,7 @@ async def _run_app(
|
|
|
340
340
|
|
|
341
341
|
# Start logs loop
|
|
342
342
|
|
|
343
|
-
logs_loop = tc.create_task(
|
|
344
|
-
get_app_logs_loop(
|
|
345
|
-
load_context.client, output_mgr, app_id=running_app.app_id, app_logs_url=running_app.app_logs_url
|
|
346
|
-
)
|
|
347
|
-
)
|
|
343
|
+
logs_loop = tc.create_task(get_app_logs_loop(load_context.client, output_mgr, app_id=running_app.app_id))
|
|
348
344
|
|
|
349
345
|
try:
|
|
350
346
|
# Create all members
|