modAL 1.2.5.dev6__tar.gz → 1.2.5.dev8__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.2.5.dev6 → modal-1.2.5.dev8}/PKG-INFO +1 -1
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/user_code_imports.py +95 -77
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/client.pyi +2 -2
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/functions.pyi +6 -6
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/io_streams.py +7 -6
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_version/__init__.py +1 -1
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/LICENSE +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/README.md +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/__main__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_billing.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_clustered_functions.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_clustered_functions.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_container_entrypoint.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_functions.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_grpc_client.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_ipython.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_load_context.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_location.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_object.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_output.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_partial_function.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_pty.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_resolver.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_resources.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/asgi.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/execution_context.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/telemetry.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_serialization.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_traceback.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_tunnel.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_tunnel.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_type_manager.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/app_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/async_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/blob_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/deprecation.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/docker_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/function_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/git_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/hash_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/http_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/logger.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/mount_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/name_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/package_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/shell_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_utils/time_utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_vendor/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_vendor/tblib.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/_watcher.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/app.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/app.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/billing.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/2023.12.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/2024.04.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/2024.10.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/2025.06.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/README.md +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/builder/base-images.json +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/call_graph.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/_download.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/_traceback.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/app.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/cluster.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/config.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/container.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/dict.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/entry_point.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/environment.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/import_refs.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/launch.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/network_file_system.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/profile.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/programs/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/programs/vscode.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/queues.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/run.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/secret.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/shell.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/token.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/utils.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cli/volume.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/client.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cls.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/cls.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/config.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/container_process.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/container_process.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/dict.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/dict.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/environments.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/environments.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/exception.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/experimental/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/experimental/flash.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/experimental/flash.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/experimental/ipython.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/file_io.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/file_io.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/file_pattern_matcher.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/functions.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/gpu.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/image.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/image.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/io_streams.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/mount.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/mount.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/network_file_system.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/network_file_system.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/object.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/object.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/output.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/parallel_map.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/parallel_map.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/partial_function.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/partial_function.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/proxy.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/proxy.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/py.typed +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/queue.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/queue.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/retries.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/runner.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/runner.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/running_app.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/sandbox.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/sandbox.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/schedule.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/scheduler_placement.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/secret.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/secret.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/serving.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/serving.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/snapshot.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/snapshot.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/stream_type.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/token_flow.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/token_flow.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/volume.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal/volume.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal.egg-info/requires.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal.egg-info/top_level.txt +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_docs/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/__init__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/api.proto +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/api_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/api_pb2.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/py.typed +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/sandbox_router.proto +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/sandbox_router_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/sandbox_router_pb2.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/sandbox_router_pb2.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/sandbox_router_pb2_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/sandbox_router_pb2_grpc.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/task_command_router.proto +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/modal_version/__main__.py +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/pyproject.toml +0 -0
- {modal-1.2.5.dev6 → modal-1.2.5.dev8}/setup.cfg +0 -0
|
@@ -64,12 +64,10 @@ def call_lifecycle_functions(
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
@contextmanager
|
|
67
|
-
def
|
|
67
|
+
def lifecycle_asgi(
|
|
68
68
|
event_loop: UserCodeEventLoop,
|
|
69
69
|
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
70
|
-
function_def: api_pb2.Function,
|
|
71
70
|
finalized_functions: dict[str, FinalizedFunction],
|
|
72
|
-
exit_callback: Optional[Callable[[], None]],
|
|
73
71
|
) -> Generator[None, None, None]:
|
|
74
72
|
lifespan_background_tasks = []
|
|
75
73
|
try:
|
|
@@ -82,38 +80,34 @@ def _run_service_lifecycle(
|
|
|
82
80
|
event_loop.run(finalized_function.lifespan_manager.lifespan_startup())
|
|
83
81
|
yield
|
|
84
82
|
finally:
|
|
85
|
-
# Run exit handlers. From this point onward, ignore all SIGINT signals that come from
|
|
86
|
-
# graceful shutdowns originating on the worker, as well as stray SIGUSR1 signals that
|
|
87
|
-
# may have been sent to cancel inputs.
|
|
88
|
-
int_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
89
|
-
usr1_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
|
|
90
83
|
try:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
event_loop.run(finalized_function.lifespan_manager.lifespan_shutdown())
|
|
97
|
-
finally:
|
|
98
|
-
# no need to keep the lifespan asgi call around - we send it no more messages
|
|
99
|
-
for task in lifespan_background_tasks:
|
|
100
|
-
task.cancel()
|
|
101
|
-
|
|
102
|
-
# Identify "exit" methods and run them.
|
|
103
|
-
# want to make sure this is called even if the lifespan manager fails
|
|
104
|
-
if exit_callback:
|
|
105
|
-
exit_callback()
|
|
106
|
-
|
|
107
|
-
# Finally, commit on exit to catch uncommitted volume changes and surface background
|
|
108
|
-
# commit errors.
|
|
109
|
-
container_io_manager.volume_commit(
|
|
110
|
-
[v.volume_id for v in function_def.volume_mounts if v.allow_background_commits]
|
|
111
|
-
)
|
|
84
|
+
# run lifespan shutdown for asgi apps
|
|
85
|
+
for finalized_function in finalized_functions.values():
|
|
86
|
+
if finalized_function.lifespan_manager:
|
|
87
|
+
with container_io_manager.handle_user_exception():
|
|
88
|
+
event_loop.run(finalized_function.lifespan_manager.lifespan_shutdown())
|
|
112
89
|
finally:
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
90
|
+
# no need to keep the lifespan asgi call around - we send it no more messages
|
|
91
|
+
for task in lifespan_background_tasks:
|
|
92
|
+
task.cancel()
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def disable_signals():
|
|
96
|
+
int_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
97
|
+
usr1_handler = signal.signal(signal.SIGUSR1, signal.SIG_IGN)
|
|
98
|
+
return int_handler, usr1_handler
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def try_enable_signals(int_handler, usr1_handler):
|
|
102
|
+
if int_handler is not None and usr1_handler is not None:
|
|
103
|
+
signal.signal(signal.SIGINT, int_handler)
|
|
104
|
+
signal.signal(signal.SIGUSR1, usr1_handler)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def volume_commit(
|
|
108
|
+
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager", function_def: api_pb2.Function
|
|
109
|
+
):
|
|
110
|
+
container_io_manager.volume_commit([v.volume_id for v in function_def.volume_mounts if v.allow_background_commits])
|
|
117
111
|
|
|
118
112
|
|
|
119
113
|
class Service(metaclass=ABCMeta):
|
|
@@ -127,14 +121,30 @@ class Service(metaclass=ABCMeta):
|
|
|
127
121
|
user_cls_instance: Any
|
|
128
122
|
app: "modal.app._App"
|
|
129
123
|
service_deps: Optional[Sequence["modal._object._Object"]]
|
|
124
|
+
function_def: api_pb2.Function
|
|
130
125
|
|
|
131
126
|
@abstractmethod
|
|
132
127
|
def get_finalized_functions(
|
|
133
128
|
self, fun_def: api_pb2.Function, container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager"
|
|
134
129
|
) -> dict[str, "FinalizedFunction"]: ...
|
|
135
130
|
|
|
131
|
+
@abstractmethod
|
|
136
132
|
@contextmanager
|
|
133
|
+
def lifecycle_presnapshot(
|
|
134
|
+
self,
|
|
135
|
+
event_loop: UserCodeEventLoop,
|
|
136
|
+
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
137
|
+
) -> Generator[None, None, None]: ...
|
|
138
|
+
|
|
137
139
|
@abstractmethod
|
|
140
|
+
@contextmanager
|
|
141
|
+
def lifecycle_postsnapshot(
|
|
142
|
+
self,
|
|
143
|
+
event_loop: UserCodeEventLoop,
|
|
144
|
+
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
145
|
+
) -> Generator[None, None, None]: ...
|
|
146
|
+
|
|
147
|
+
@contextmanager
|
|
138
148
|
def execution_context(
|
|
139
149
|
self,
|
|
140
150
|
event_loop: UserCodeEventLoop,
|
|
@@ -150,6 +160,34 @@ class Service(metaclass=ABCMeta):
|
|
|
150
160
|
6. Yield finalized_functions for execution
|
|
151
161
|
7. Handles cleanup (lifespan shutdown, 'exit' methods)
|
|
152
162
|
"""
|
|
163
|
+
int_handler, usr1_handler = None, None
|
|
164
|
+
try:
|
|
165
|
+
# 1. Pre-snapshot Enter
|
|
166
|
+
with self.lifecycle_presnapshot(event_loop, container_io_manager):
|
|
167
|
+
# 2. Snapshot -- If this container is being used to create a checkpoint, checkpoint the container after
|
|
168
|
+
# global imports and initialization. Checkpointed containers run from this point onwards.
|
|
169
|
+
maybe_snapshot(container_io_manager, self.function_def)
|
|
170
|
+
# 3. Breakpoint wrapper
|
|
171
|
+
create_breakpoint_wrapper(container_io_manager)
|
|
172
|
+
# 4. Post-snapshot Enter
|
|
173
|
+
with self.lifecycle_postsnapshot(event_loop, container_io_manager):
|
|
174
|
+
# Get Functions
|
|
175
|
+
with container_io_manager.handle_user_exception():
|
|
176
|
+
finalized_functions = self.get_finalized_functions(self.function_def, container_io_manager)
|
|
177
|
+
# 5. Start ASGI lifespan
|
|
178
|
+
with lifecycle_asgi(event_loop, container_io_manager, finalized_functions):
|
|
179
|
+
# 6. Yield Finalized Functions
|
|
180
|
+
try:
|
|
181
|
+
yield finalized_functions
|
|
182
|
+
finally:
|
|
183
|
+
int_handler, usr1_handler = disable_signals()
|
|
184
|
+
finally:
|
|
185
|
+
# 9. Volume commit - runs OUTSIDE all lifecycle managers so exit handlers
|
|
186
|
+
# have a chance to write to disk before we commit volumes
|
|
187
|
+
try:
|
|
188
|
+
volume_commit(container_io_manager, self.function_def)
|
|
189
|
+
finally:
|
|
190
|
+
try_enable_signals(int_handler, usr1_handler)
|
|
153
191
|
|
|
154
192
|
|
|
155
193
|
def construct_webhook_callable(
|
|
@@ -265,27 +303,22 @@ class ImportedFunction(Service):
|
|
|
265
303
|
}
|
|
266
304
|
|
|
267
305
|
@contextmanager
|
|
268
|
-
def
|
|
306
|
+
def lifecycle_presnapshot(
|
|
269
307
|
self,
|
|
270
308
|
event_loop: UserCodeEventLoop,
|
|
271
309
|
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
272
|
-
)
|
|
273
|
-
#
|
|
274
|
-
|
|
275
|
-
maybe_snapshot(container_io_manager, self.function_def)
|
|
276
|
-
create_breakpoint_wrapper(container_io_manager)
|
|
277
|
-
|
|
278
|
-
with container_io_manager.handle_user_exception():
|
|
279
|
-
finalized_functions = self.get_finalized_functions(self.function_def, container_io_manager)
|
|
310
|
+
):
|
|
311
|
+
# This is a no-op for imported functions since @enter methods are not supported
|
|
312
|
+
yield
|
|
280
313
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
314
|
+
@contextmanager
|
|
315
|
+
def lifecycle_postsnapshot(
|
|
316
|
+
self,
|
|
317
|
+
event_loop: UserCodeEventLoop,
|
|
318
|
+
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
319
|
+
):
|
|
320
|
+
# This is a no-op for imported functions since @enter methods are not supported
|
|
321
|
+
yield
|
|
289
322
|
|
|
290
323
|
|
|
291
324
|
@dataclass
|
|
@@ -340,53 +373,38 @@ class ImportedClass(Service):
|
|
|
340
373
|
return finalized_functions
|
|
341
374
|
|
|
342
375
|
@contextmanager
|
|
343
|
-
def
|
|
376
|
+
def lifecycle_presnapshot(
|
|
344
377
|
self,
|
|
345
378
|
event_loop: UserCodeEventLoop,
|
|
346
379
|
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
347
|
-
)
|
|
348
|
-
# 1. Pre-snapshot Enter
|
|
380
|
+
):
|
|
349
381
|
# Identify all "enter" methods that need to run before we snapshot.
|
|
350
382
|
if not self.function_def.is_auto_snapshot:
|
|
351
383
|
pre_snapshot_methods = _find_callables_for_obj(
|
|
352
384
|
self.user_cls_instance, _PartialFunctionFlags.ENTER_PRE_SNAPSHOT
|
|
353
385
|
)
|
|
354
386
|
call_lifecycle_functions(event_loop, container_io_manager, list(pre_snapshot_methods.values()))
|
|
387
|
+
yield
|
|
355
388
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
create_breakpoint_wrapper(container_io_manager)
|
|
363
|
-
|
|
364
|
-
# 4. Post-snapshot Enter
|
|
389
|
+
@contextmanager
|
|
390
|
+
def lifecycle_postsnapshot(
|
|
391
|
+
self,
|
|
392
|
+
event_loop: UserCodeEventLoop,
|
|
393
|
+
container_io_manager: "modal._runtime.container_io_manager.ContainerIOManager",
|
|
394
|
+
):
|
|
365
395
|
# Identify the "enter" methods to run after resuming from a snapshot.
|
|
366
396
|
if not self.function_def.is_auto_snapshot:
|
|
367
397
|
post_snapshot_methods = _find_callables_for_obj(
|
|
368
398
|
self.user_cls_instance, _PartialFunctionFlags.ENTER_POST_SNAPSHOT
|
|
369
399
|
)
|
|
370
400
|
call_lifecycle_functions(event_loop, container_io_manager, list(post_snapshot_methods.values()))
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
finalized_functions = self.get_finalized_functions(self.function_def, container_io_manager)
|
|
375
|
-
|
|
376
|
-
def exit_callback():
|
|
401
|
+
try:
|
|
402
|
+
yield
|
|
403
|
+
finally:
|
|
377
404
|
if not self.function_def.is_auto_snapshot:
|
|
378
405
|
exit_methods = _find_callables_for_obj(self.user_cls_instance, _PartialFunctionFlags.EXIT)
|
|
379
406
|
call_lifecycle_functions(event_loop, container_io_manager, list(exit_methods.values()))
|
|
380
407
|
|
|
381
|
-
with _run_service_lifecycle(
|
|
382
|
-
event_loop,
|
|
383
|
-
container_io_manager,
|
|
384
|
-
self.function_def,
|
|
385
|
-
finalized_functions,
|
|
386
|
-
exit_callback,
|
|
387
|
-
):
|
|
388
|
-
yield finalized_functions
|
|
389
|
-
|
|
390
408
|
|
|
391
409
|
def get_user_class_instance(_cls: modal.cls._Cls, args: tuple[Any, ...], kwargs: dict[str, Any]) -> typing.Any:
|
|
392
410
|
"""Returns instance of the underlying class to be used as the `self`
|
|
@@ -32,7 +32,7 @@ class _Client:
|
|
|
32
32
|
server_url: str,
|
|
33
33
|
client_type: int,
|
|
34
34
|
credentials: typing.Optional[tuple[str, str]],
|
|
35
|
-
version: str = "1.2.5.
|
|
35
|
+
version: str = "1.2.5.dev8",
|
|
36
36
|
):
|
|
37
37
|
"""mdmd:hidden
|
|
38
38
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -163,7 +163,7 @@ class Client:
|
|
|
163
163
|
server_url: str,
|
|
164
164
|
client_type: int,
|
|
165
165
|
credentials: typing.Optional[tuple[str, str]],
|
|
166
|
-
version: str = "1.2.5.
|
|
166
|
+
version: str = "1.2.5.dev8",
|
|
167
167
|
):
|
|
168
168
|
"""mdmd:hidden
|
|
169
169
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -408,7 +408,7 @@ class Function(
|
|
|
408
408
|
|
|
409
409
|
_call_generator: ___call_generator_spec[typing_extensions.Self]
|
|
410
410
|
|
|
411
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
411
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
|
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.ReturnType, modal._functions.P, typing_extensions.Self]
|
|
421
421
|
|
|
422
422
|
class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
|
|
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[ReturnType_INNER, P_INNER, SUPERSELF]):
|
|
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
|
|
|
@@ -468,7 +468,7 @@ class Function(
|
|
|
468
468
|
...
|
|
469
469
|
|
|
470
470
|
_experimental_spawn: ___experimental_spawn_spec[
|
|
471
|
-
modal._functions.
|
|
471
|
+
modal._functions.ReturnType, modal._functions.P, typing_extensions.Self
|
|
472
472
|
]
|
|
473
473
|
|
|
474
474
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
|
|
@@ -477,7 +477,7 @@ class Function(
|
|
|
477
477
|
|
|
478
478
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
|
|
479
479
|
|
|
480
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
480
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER, SUPERSELF]):
|
|
481
481
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
482
482
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
483
483
|
|
|
@@ -498,7 +498,7 @@ class Function(
|
|
|
498
498
|
"""
|
|
499
499
|
...
|
|
500
500
|
|
|
501
|
-
spawn: __spawn_spec[modal._functions.
|
|
501
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P, typing_extensions.Self]
|
|
502
502
|
|
|
503
503
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
504
504
|
"""Return the inner Python object wrapped by this Modal Function."""
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import asyncio
|
|
3
3
|
import codecs
|
|
4
4
|
import contextlib
|
|
5
|
+
import io
|
|
5
6
|
import sys
|
|
6
7
|
import time
|
|
7
8
|
from collections.abc import AsyncGenerator, AsyncIterator
|
|
@@ -403,10 +404,10 @@ class _BytesStreamReaderThroughCommandRouter:
|
|
|
403
404
|
return self._params.file_descriptor
|
|
404
405
|
|
|
405
406
|
async def read(self) -> bytes:
|
|
406
|
-
|
|
407
|
+
buffer = io.BytesIO()
|
|
407
408
|
async for part in self:
|
|
408
|
-
|
|
409
|
-
return
|
|
409
|
+
buffer.write(part)
|
|
410
|
+
return buffer.getvalue()
|
|
410
411
|
|
|
411
412
|
def __aiter__(self) -> AsyncGenerator[bytes, None]:
|
|
412
413
|
return _stdio_stream_from_command_router(self._params)
|
|
@@ -438,10 +439,10 @@ class _TextStreamReaderThroughCommandRouter:
|
|
|
438
439
|
return self._params.file_descriptor
|
|
439
440
|
|
|
440
441
|
async def read(self) -> str:
|
|
441
|
-
|
|
442
|
+
buffer = io.StringIO()
|
|
442
443
|
async for part in self:
|
|
443
|
-
|
|
444
|
-
return
|
|
444
|
+
buffer.write(part)
|
|
445
|
+
return buffer.getvalue()
|
|
445
446
|
|
|
446
447
|
async def __aiter__(self) -> AsyncGenerator[str, None]:
|
|
447
448
|
async with aclosing(_stdio_stream_from_command_router(self._params)) as bytes_stream:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|