modal 1.5.2.dev22__tar.gz → 1.5.3.dev1__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.5.2.dev22 → modal-1.5.3.dev1}/PKG-INFO +1 -1
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/grpc_utils.py +19 -4
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/task_command_router_client.py +21 -161
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/changelog.py +7 -7
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/environment.py +9 -9
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/client.pyi +2 -2
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/container_process.py +1 -13
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/container_process.pyi +0 -27
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/functions.pyi +6 -6
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/parallel_map.py +56 -51
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/sandbox_fs.py +80 -32
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/sandbox_fs.pyi +0 -24
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/api_grpc.py +32 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/api_pb2.py +898 -847
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/api_pb2.pyi +134 -6
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/api_pb2_grpc.py +66 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/api_pb2_grpc.pyi +20 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/modal_api_grpc.py +2 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_version/__init__.py +1 -1
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/LICENSE +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/README.md +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/__main__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_billing.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_clustered_functions.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_environments.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_function_variants.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_functions.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_grpc_client.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_image.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_ipython.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_load_context.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_location.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_logs.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_object.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_output/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_output/manager.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_output/pty.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_output/rich.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_output/status.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_partial_function.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_resolver.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_resources.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_serialization.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_server.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_traceback.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_tunnel.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_tunnel.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_type_manager.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/logger.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_vendor/version.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_watcher.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/_workspace.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/app.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/app.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/billing.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/billing.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/README.md +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/builder/base-images.json +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/call_graph.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/_download.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/_help.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/_traceback.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/app.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/billing.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/cluster.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/config.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/container.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/curl.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/dashboard.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/dict.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/endpoint.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/entry_point.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/image.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/import_refs.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/launch.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/logo.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/profile.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/queues.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/run.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/secret.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/selector.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/shell.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/skills.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/token.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/utils.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/volume.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cli/workspace.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/client.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cls.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/cls.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/config.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/dict.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/dict.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/environments.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/environments.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/exception.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/experimental/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/experimental/flash.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/experimental/ipython.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/file_io.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/file_io.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/functions.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/image.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/image.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/io_streams.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/io_streams.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/mount.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/mount.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/network_file_system.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/network_file_system.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/object.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/object.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/output.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/parallel_map.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/partial_function.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/partial_function.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/proxy.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/proxy.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/py.typed +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/queue.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/queue.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/retries.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/runner.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/runner.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/running_app.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/sandbox.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/sandbox.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/schedule.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/scheduler_placement.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/secret.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/secret.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/server.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/server.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/serving.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/serving.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/snapshot.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/snapshot.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/stream_type.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/token_flow.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/token_flow.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/types.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/volume.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/volume.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/workspace.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal/workspace.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/__init__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/py.typed +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/modal_version/__main__.py +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/pyproject.toml +0 -0
- {modal-1.5.2.dev22 → modal-1.5.3.dev1}/setup.cfg +0 -0
|
@@ -164,6 +164,9 @@ RETRYABLE_GRPC_STATUS_CODES = [
|
|
|
164
164
|
]
|
|
165
165
|
SERVER_RETRY_WARNING_TIME_INTERVAL = 30.0
|
|
166
166
|
DEFAULT_MAX_RETRIES = 3
|
|
167
|
+
GRPC_KEEPALIVE_TIME_SECS = 30.0
|
|
168
|
+
GRPC_KEEPALIVE_TIMEOUT_SECS = 10.0
|
|
169
|
+
GRPC_WINDOW_SIZE = 64 * 1024 * 1024 # 64 MiB
|
|
167
170
|
|
|
168
171
|
|
|
169
172
|
@dataclass
|
|
@@ -251,6 +254,21 @@ class CustomProtoStatusDetailsCodec(StatusDetailsCodecBase):
|
|
|
251
254
|
custom_detail_codec = CustomProtoStatusDetailsCodec()
|
|
252
255
|
|
|
253
256
|
|
|
257
|
+
def create_channel_config() -> grpclib.config.Configuration:
|
|
258
|
+
"""Shared grpclib channel settings for Modal client connections.
|
|
259
|
+
|
|
260
|
+
HTTP/2 keepalive probes keep idle transports warm through stateful
|
|
261
|
+
middleboxes and surface dead connections before retries reuse them.
|
|
262
|
+
"""
|
|
263
|
+
return grpclib.config.Configuration(
|
|
264
|
+
_keepalive_time=GRPC_KEEPALIVE_TIME_SECS,
|
|
265
|
+
_keepalive_timeout=GRPC_KEEPALIVE_TIMEOUT_SECS,
|
|
266
|
+
_keepalive_permit_without_calls=True,
|
|
267
|
+
http2_connection_window_size=GRPC_WINDOW_SIZE,
|
|
268
|
+
http2_stream_window_size=GRPC_WINDOW_SIZE,
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
|
|
254
272
|
def create_channel(
|
|
255
273
|
server_url: str,
|
|
256
274
|
metadata: dict[str, str] = {},
|
|
@@ -262,10 +280,7 @@ def create_channel(
|
|
|
262
280
|
o = urllib.parse.urlparse(server_url)
|
|
263
281
|
|
|
264
282
|
channel: grpclib.client.Channel
|
|
265
|
-
config =
|
|
266
|
-
http2_connection_window_size=64 * 1024 * 1024, # 64 MiB
|
|
267
|
-
http2_stream_window_size=64 * 1024 * 1024, # 64 MiB
|
|
268
|
-
)
|
|
283
|
+
config = create_channel_config()
|
|
269
284
|
|
|
270
285
|
if o.scheme == "unix":
|
|
271
286
|
channel = grpclib.client.Channel(path=o.path, config=config, status_details_codec=custom_detail_codec)
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Copyright Modal Labs 2025
|
|
2
2
|
import asyncio
|
|
3
3
|
import base64
|
|
4
|
-
import io
|
|
5
4
|
import json
|
|
6
5
|
import socket
|
|
7
6
|
import ssl
|
|
@@ -9,36 +8,24 @@ import time
|
|
|
9
8
|
import typing
|
|
10
9
|
import urllib.parse
|
|
11
10
|
import weakref
|
|
12
|
-
from collections.abc import AsyncGenerator,
|
|
11
|
+
from collections.abc import AsyncGenerator, Callable
|
|
13
12
|
from contextlib import suppress
|
|
14
|
-
from typing import
|
|
13
|
+
from typing import TypeVar
|
|
15
14
|
|
|
16
15
|
import grpclib.client
|
|
17
|
-
import grpclib.config
|
|
18
16
|
from grpclib import GRPCError, Status
|
|
19
17
|
from grpclib.exceptions import StreamTerminatedError
|
|
20
18
|
|
|
21
19
|
from modal.config import logger
|
|
22
|
-
from modal.exception import
|
|
20
|
+
from modal.exception import ExecTimeoutError, TimeoutError as ModalTimeoutError
|
|
23
21
|
from modal_proto import api_pb2, task_command_router_pb2 as sr_pb2
|
|
24
22
|
from modal_proto.task_command_router_grpc import TaskCommandRouterStub
|
|
25
23
|
|
|
26
24
|
from .._grpc_client import grpc_error_converter
|
|
27
|
-
from .._utils.grpc_utils import ModalChannel
|
|
25
|
+
from .._utils.grpc_utils import ModalChannel, create_channel_config
|
|
28
26
|
from .async_utils import aclosing, retry
|
|
29
27
|
from .grpc_utils import RETRYABLE_GRPC_STATUS_CODES
|
|
30
28
|
|
|
31
|
-
STREAMING_STDIN_CHUNK_SIZE = 256 * 1024
|
|
32
|
-
|
|
33
|
-
_STREAMING_STDIN_RESUMABLE_EXCEPTIONS = (
|
|
34
|
-
AuthError,
|
|
35
|
-
InternalError,
|
|
36
|
-
ServiceError,
|
|
37
|
-
StreamTerminatedError,
|
|
38
|
-
OSError,
|
|
39
|
-
asyncio.TimeoutError,
|
|
40
|
-
)
|
|
41
|
-
|
|
42
29
|
|
|
43
30
|
@retry(n_attempts=34, base_delay=1, max_delay=10, attempt_timeout=10, total_timeout=310)
|
|
44
31
|
async def _connect_channel(channel: grpclib.client.Channel):
|
|
@@ -234,10 +221,7 @@ class TaskCommandRouterClient:
|
|
|
234
221
|
host,
|
|
235
222
|
port,
|
|
236
223
|
ssl=ssl_context,
|
|
237
|
-
config=
|
|
238
|
-
http2_connection_window_size=64 * 1024 * 1024, # 64 MiB
|
|
239
|
-
http2_stream_window_size=64 * 1024 * 1024, # 64 MiB
|
|
240
|
-
),
|
|
224
|
+
config=create_channel_config(),
|
|
241
225
|
closed_error_message="Unable to perform operation on a detached sandbox",
|
|
242
226
|
)
|
|
243
227
|
|
|
@@ -484,118 +468,6 @@ class TaskCommandRouterClient:
|
|
|
484
468
|
lambda: self._call_with_auth_retry(self._stub.TaskExecStdinWrite, request)
|
|
485
469
|
)
|
|
486
470
|
|
|
487
|
-
async def exec_stdin_write_stream(
|
|
488
|
-
self,
|
|
489
|
-
task_id: str,
|
|
490
|
-
exec_id: str,
|
|
491
|
-
source: BinaryIO,
|
|
492
|
-
chunk_size: int = STREAMING_STDIN_CHUNK_SIZE,
|
|
493
|
-
max_resume_attempts: int = 9,
|
|
494
|
-
) -> int:
|
|
495
|
-
"""Stream `source` into the exec's stdin, with bounded resume on transient failures.
|
|
496
|
-
|
|
497
|
-
Streams the full contents of `source` in one client-streaming RPC and
|
|
498
|
-
closes stdin (EOF) on success. On a resumable error, queries
|
|
499
|
-
`exec_stdin_status` for the server's canonical offset, seeks `source`
|
|
500
|
-
to that point, and reopens the stream.
|
|
501
|
-
|
|
502
|
-
Args:
|
|
503
|
-
task_id: The task ID of the task running the exec'd command.
|
|
504
|
-
exec_id: The execution ID of the command to write to.
|
|
505
|
-
source: A seekable byte source (file, BytesIO, etc.).
|
|
506
|
-
chunk_size: Bytes per outbound message.
|
|
507
|
-
max_resume_attempts: Upper bound on resume retries before giving up.
|
|
508
|
-
|
|
509
|
-
Returns:
|
|
510
|
-
The total number of bytes streamed into the exec's stdin.
|
|
511
|
-
"""
|
|
512
|
-
offset = 0
|
|
513
|
-
attempt = 0
|
|
514
|
-
while True:
|
|
515
|
-
|
|
516
|
-
async def _chunks():
|
|
517
|
-
while True:
|
|
518
|
-
chunk = source.read(chunk_size)
|
|
519
|
-
if not chunk:
|
|
520
|
-
return
|
|
521
|
-
yield chunk
|
|
522
|
-
|
|
523
|
-
try:
|
|
524
|
-
source.seek(offset)
|
|
525
|
-
await self._exec_stdin_write_stream(task_id, exec_id, offset, _chunks())
|
|
526
|
-
return source.tell()
|
|
527
|
-
except (*_STREAMING_STDIN_RESUMABLE_EXCEPTIONS, AttributeError) as e:
|
|
528
|
-
# StreamTerminatedError surfaces as AttributeError in grpclib<=0.4.7;
|
|
529
|
-
# see call_with_retries_on_transient_errors.
|
|
530
|
-
if isinstance(e, AttributeError) and "_write_appdata" not in str(e):
|
|
531
|
-
raise
|
|
532
|
-
attempt += 1
|
|
533
|
-
if attempt > max_resume_attempts:
|
|
534
|
-
raise
|
|
535
|
-
status = await self.exec_stdin_status(task_id=task_id, exec_id=exec_id)
|
|
536
|
-
if status.closed:
|
|
537
|
-
pos = source.tell()
|
|
538
|
-
if status.num_bytes_written == pos and source.seek(0, io.SEEK_END) == pos:
|
|
539
|
-
logger.debug(f"exec_stdin_write_stream completed but response was lost: {e}")
|
|
540
|
-
return pos
|
|
541
|
-
raise
|
|
542
|
-
offset = status.num_bytes_written
|
|
543
|
-
logger.debug(f"exec_stdin_write_stream resuming from offset {offset} after error: {e}")
|
|
544
|
-
|
|
545
|
-
async def _exec_stdin_write_stream(
|
|
546
|
-
self,
|
|
547
|
-
task_id: str,
|
|
548
|
-
exec_id: str,
|
|
549
|
-
start_offset: int,
|
|
550
|
-
chunks: AsyncIterable[bytes],
|
|
551
|
-
) -> sr_pb2.TaskExecStdinWriteStreamResponse | None:
|
|
552
|
-
"""Single client-streaming attempt: Start, Data chunks, then End (EOF).
|
|
553
|
-
|
|
554
|
-
Does not retry; `exec_stdin_write_stream` owns resume.
|
|
555
|
-
"""
|
|
556
|
-
with grpc_error_converter():
|
|
557
|
-
stream = self._stub.TaskExecStdinWriteStream.open(metadata=self._get_metadata())
|
|
558
|
-
async with stream as s:
|
|
559
|
-
start = sr_pb2.TaskExecStdinWriteStreamRequest(
|
|
560
|
-
start=sr_pb2.TaskExecStdinWriteStreamStart(
|
|
561
|
-
task_id=task_id,
|
|
562
|
-
exec_id=exec_id,
|
|
563
|
-
offset=start_offset,
|
|
564
|
-
),
|
|
565
|
-
)
|
|
566
|
-
await s.send_message(start)
|
|
567
|
-
async for data in chunks:
|
|
568
|
-
if not data:
|
|
569
|
-
continue
|
|
570
|
-
await s.send_message(sr_pb2.TaskExecStdinWriteStreamRequest(data=data))
|
|
571
|
-
# The server closes stdin only on this explicit End message. A
|
|
572
|
-
# stream that breaks before it leaves stdin open for resume.
|
|
573
|
-
await s.send_message(
|
|
574
|
-
sr_pb2.TaskExecStdinWriteStreamRequest(end=sr_pb2.TaskExecStdinWriteStreamEnd()),
|
|
575
|
-
end=True,
|
|
576
|
-
)
|
|
577
|
-
return await s.recv_message()
|
|
578
|
-
|
|
579
|
-
async def exec_stdin_status(self, task_id: str, exec_id: str) -> sr_pb2.TaskExecStdinStatusResponse:
|
|
580
|
-
"""Read the current stdin write status for an exec'd command, to support retries from the right offset.
|
|
581
|
-
|
|
582
|
-
Used by streaming clients to find the resume offset after a stream
|
|
583
|
-
failure. Evicts any in-flight stdin stream for the exec, so it is not
|
|
584
|
-
safe to call for read-only observability.
|
|
585
|
-
|
|
586
|
-
Args:
|
|
587
|
-
task_id: The task ID of the task running the exec'd command.
|
|
588
|
-
exec_id: The execution ID of the command to query.
|
|
589
|
-
Raises:
|
|
590
|
-
Other errors: If retries are exhausted on transient errors or if there's an error
|
|
591
|
-
from the RPC itself.
|
|
592
|
-
"""
|
|
593
|
-
request = sr_pb2.TaskExecStdinStatusRequest(task_id=task_id, exec_id=exec_id)
|
|
594
|
-
with grpc_error_converter():
|
|
595
|
-
return await call_with_retries_on_transient_errors(
|
|
596
|
-
lambda: self._call_with_auth_retry(self._stub.TaskExecStdinStatus, request)
|
|
597
|
-
)
|
|
598
|
-
|
|
599
471
|
async def sandbox_stdin_write_v2(
|
|
600
472
|
self, task_id: str, offset: int, data: bytes, eof: bool
|
|
601
473
|
) -> sr_pb2.SandboxStdinWriteV2Response:
|
|
@@ -625,16 +497,7 @@ class TaskCommandRouterClient:
|
|
|
625
497
|
TimeoutError: If the sandbox does not become ready within `timeout`.
|
|
626
498
|
"""
|
|
627
499
|
request = sr_pb2.SandboxWaitUntilReadyTcrRequest(task_id=task_id, timeout=timeout)
|
|
628
|
-
|
|
629
|
-
try:
|
|
630
|
-
return await asyncio.wait_for(
|
|
631
|
-
call_with_retries_on_transient_errors(
|
|
632
|
-
lambda: self._call_with_auth_retry(self._stub.SandboxWaitUntilReady, request, timeout=timeout),
|
|
633
|
-
),
|
|
634
|
-
timeout=timeout,
|
|
635
|
-
)
|
|
636
|
-
except asyncio.TimeoutError:
|
|
637
|
-
raise ModalTimeoutError("Timeout expired")
|
|
500
|
+
return await self._unary_call_with_deadline(self._stub.SandboxWaitUntilReady, request, timeout=timeout)
|
|
638
501
|
|
|
639
502
|
async def exec_poll(self, task_id: str, exec_id: str, deadline: float | None = None) -> sr_pb2.TaskExecPollResponse:
|
|
640
503
|
"""Poll for the exit status of an exec'd command, properly retrying on transient errors.
|
|
@@ -944,21 +807,14 @@ class TaskCommandRouterClient:
|
|
|
944
807
|
window, the call is cancelled and a `modal.exception.TimeoutError` is raised.
|
|
945
808
|
"""
|
|
946
809
|
request = sr_pb2.TaskReloadVolumesRequest(task_id=task_id)
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
lambda: self._call_with_auth_retry(self._stub.TaskReloadVolumes, request, timeout=timeout),
|
|
952
|
-
),
|
|
953
|
-
timeout=timeout,
|
|
954
|
-
)
|
|
955
|
-
except asyncio.TimeoutError:
|
|
956
|
-
raise ModalTimeoutError("Timeout expired")
|
|
810
|
+
return await self._unary_call_with_deadline(self._stub.TaskReloadVolumes, request, timeout=timeout)
|
|
811
|
+
|
|
812
|
+
async def _unary_call_with_deadline(self, rpc, request, *, timeout: float, **kwargs):
|
|
813
|
+
"""Call a unary RPC with transient-error retries bounded by a total deadline.
|
|
957
814
|
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
# the total deadline budget
|
|
815
|
+
Raises `modal.exception.TimeoutError` once the deadline has elapsed, or when
|
|
816
|
+
the server responds with `DEADLINE_EXCEEDED`.
|
|
817
|
+
"""
|
|
962
818
|
timeout_deadline = time.monotonic() + timeout
|
|
963
819
|
|
|
964
820
|
def call():
|
|
@@ -976,17 +832,21 @@ class TaskCommandRouterClient:
|
|
|
976
832
|
exclude_status_codes=[Status.DEADLINE_EXCEEDED, Status.CANCELLED],
|
|
977
833
|
timeout_deadline=timeout_deadline,
|
|
978
834
|
)
|
|
979
|
-
except Exception:
|
|
980
|
-
if time.monotonic() >= timeout_deadline:
|
|
835
|
+
except Exception as exc:
|
|
836
|
+
if time.monotonic() >= timeout_deadline or getattr(exc, "_grpc_status", None) == Status.DEADLINE_EXCEEDED:
|
|
981
837
|
raise ModalTimeoutError("Timeout expired")
|
|
982
838
|
raise
|
|
983
839
|
|
|
984
840
|
async def snapshot_directory(
|
|
985
841
|
self, request: sr_pb2.TaskSnapshotDirectoryRequest, *, timeout: float, **kwargs
|
|
986
842
|
) -> sr_pb2.TaskSnapshotDirectoryResponse:
|
|
987
|
-
return await self.
|
|
843
|
+
return await self._unary_call_with_deadline(
|
|
844
|
+
self._stub.TaskSnapshotDirectory, request, timeout=timeout, **kwargs
|
|
845
|
+
)
|
|
988
846
|
|
|
989
847
|
async def snapshot_filesystem(
|
|
990
848
|
self, request: sr_pb2.TaskSnapshotFilesystemRequest, *, timeout: float, **kwargs
|
|
991
849
|
) -> sr_pb2.TaskSnapshotFilesystemResponse:
|
|
992
|
-
return await self.
|
|
850
|
+
return await self._unary_call_with_deadline(
|
|
851
|
+
self._stub.TaskSnapshotFilesystem, request, timeout=timeout, **kwargs
|
|
852
|
+
)
|
|
@@ -120,17 +120,17 @@ def changelog(
|
|
|
120
120
|
|
|
121
121
|
Examples:
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
123
|
+
```bash
|
|
124
|
+
modal changelog --since 1.2.0 # Show updates added after a specific version
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
modal changelog --since 2026-01-01 # Show updates added after a specific date
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
modal changelog --newer # Show updates released after the currently installed version
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
modal changelog --last 3 # Show updates included in the 3 most recent releases
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
modal changelog --for 1.3.1 # Show the changelog for a specific release
|
|
133
|
+
```
|
|
134
134
|
|
|
135
135
|
Note: when using `--since` or `--last`, only changes up to the currently installed version are shown.
|
|
136
136
|
|
|
@@ -242,21 +242,21 @@ async def environment_billing(
|
|
|
242
242
|
|
|
243
243
|
Examples:
|
|
244
244
|
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
```bash
|
|
246
|
+
modal environment billing report --start 2025-12-01 --end 2026-01-01
|
|
247
247
|
|
|
248
|
-
|
|
248
|
+
modal environment billing report --for "last month" --tag-names team,project
|
|
249
249
|
|
|
250
|
-
|
|
250
|
+
modal environment billing report test_env --for today --resolution h
|
|
251
251
|
|
|
252
|
-
|
|
252
|
+
modal environment billing report test_env --for "this month" --show-resources
|
|
253
253
|
|
|
254
|
-
|
|
254
|
+
modal environment billing report prod_env --for yesterday -r h --tz local
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
modal environment billing report main_env --for "last month" --csv > report.csv
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
|
|
258
|
+
modal environment billing report main_env --start 2025-12-01 --json > report.json
|
|
259
|
+
```
|
|
260
260
|
|
|
261
261
|
"""
|
|
262
262
|
if json and csv:
|
|
@@ -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.5.
|
|
38
|
+
version: str = "1.5.3.dev1",
|
|
39
39
|
):
|
|
40
40
|
"""mdmd:hidden
|
|
41
41
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -205,7 +205,7 @@ class Client:
|
|
|
205
205
|
server_url: str,
|
|
206
206
|
client_type: int,
|
|
207
207
|
credentials: typing.Optional[tuple[str, str]],
|
|
208
|
-
version: str = "1.5.
|
|
208
|
+
version: str = "1.5.3.dev1",
|
|
209
209
|
):
|
|
210
210
|
"""mdmd:hidden
|
|
211
211
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright Modal Labs 2024
|
|
2
2
|
import asyncio
|
|
3
3
|
import platform
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Generic, TypeVar
|
|
5
5
|
|
|
6
6
|
from modal_proto import api_pb2
|
|
7
7
|
|
|
@@ -117,18 +117,6 @@ class _ContainerProcess(Generic[T]):
|
|
|
117
117
|
)
|
|
118
118
|
return self._returncode
|
|
119
119
|
|
|
120
|
-
async def _stdin_write_stream(self, source: BinaryIO) -> int:
|
|
121
|
-
"""mdmd:hidden
|
|
122
|
-
Stream `source` into the process's stdin and close it (EOF) on success.
|
|
123
|
-
|
|
124
|
-
Returns the total bytes streamed.
|
|
125
|
-
"""
|
|
126
|
-
return await self._command_router_client.exec_stdin_write_stream(
|
|
127
|
-
task_id=self._task_id,
|
|
128
|
-
exec_id=self._process_id,
|
|
129
|
-
source=source,
|
|
130
|
-
)
|
|
131
|
-
|
|
132
120
|
async def poll(self) -> int | None:
|
|
133
121
|
"""Check if the container process has finished running.
|
|
134
122
|
|
|
@@ -53,14 +53,6 @@ class _ContainerProcess(typing.Generic[T]):
|
|
|
53
53
|
|
|
54
54
|
@property
|
|
55
55
|
def returncode(self) -> int: ...
|
|
56
|
-
async def _stdin_write_stream(self, source: typing.BinaryIO) -> int:
|
|
57
|
-
"""mdmd:hidden
|
|
58
|
-
Stream `source` into the process's stdin and close it (EOF) on success.
|
|
59
|
-
|
|
60
|
-
Returns the total bytes streamed.
|
|
61
|
-
"""
|
|
62
|
-
...
|
|
63
|
-
|
|
64
56
|
async def poll(self) -> typing.Optional[int]:
|
|
65
57
|
"""Check if the container process has finished running.
|
|
66
58
|
|
|
@@ -113,25 +105,6 @@ class ContainerProcess(typing.Generic[T]):
|
|
|
113
105
|
@property
|
|
114
106
|
def returncode(self) -> int: ...
|
|
115
107
|
|
|
116
|
-
class ___stdin_write_stream_spec(typing_extensions.Protocol):
|
|
117
|
-
def __call__(self, /, source: typing.BinaryIO) -> int:
|
|
118
|
-
"""mdmd:hidden
|
|
119
|
-
Stream `source` into the process's stdin and close it (EOF) on success.
|
|
120
|
-
|
|
121
|
-
Returns the total bytes streamed.
|
|
122
|
-
"""
|
|
123
|
-
...
|
|
124
|
-
|
|
125
|
-
async def aio(self, /, source: typing.BinaryIO) -> int:
|
|
126
|
-
"""mdmd:hidden
|
|
127
|
-
Stream `source` into the process's stdin and close it (EOF) on success.
|
|
128
|
-
|
|
129
|
-
Returns the total bytes streamed.
|
|
130
|
-
"""
|
|
131
|
-
...
|
|
132
|
-
|
|
133
|
-
_stdin_write_stream: ___stdin_write_stream_spec
|
|
134
|
-
|
|
135
108
|
class __poll_spec(typing_extensions.Protocol):
|
|
136
109
|
def __call__(self, /) -> typing.Optional[int]:
|
|
137
110
|
"""Check if the container process has finished running.
|
|
@@ -491,7 +491,7 @@ class Function(
|
|
|
491
491
|
|
|
492
492
|
_call_generator: ___call_generator_spec
|
|
493
493
|
|
|
494
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
494
|
+
class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
495
495
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
496
496
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
497
497
|
|
|
@@ -516,7 +516,7 @@ class Function(
|
|
|
516
516
|
"""
|
|
517
517
|
...
|
|
518
518
|
|
|
519
|
-
remote: __remote_spec[modal._functions.
|
|
519
|
+
remote: __remote_spec[modal._functions.P, modal._functions.ReturnType]
|
|
520
520
|
|
|
521
521
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
522
522
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -566,7 +566,7 @@ class Function(
|
|
|
566
566
|
"""
|
|
567
567
|
...
|
|
568
568
|
|
|
569
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
569
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
570
570
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
571
571
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
572
572
|
|
|
@@ -599,7 +599,7 @@ class Function(
|
|
|
599
599
|
"""
|
|
600
600
|
...
|
|
601
601
|
|
|
602
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
602
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.P, modal._functions.ReturnType]
|
|
603
603
|
|
|
604
604
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
605
605
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -607,7 +607,7 @@ class Function(
|
|
|
607
607
|
|
|
608
608
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
609
609
|
|
|
610
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
610
|
+
class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER]):
|
|
611
611
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
612
612
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
613
613
|
|
|
@@ -640,7 +640,7 @@ class Function(
|
|
|
640
640
|
"""
|
|
641
641
|
...
|
|
642
642
|
|
|
643
|
-
spawn: __spawn_spec[modal._functions.
|
|
643
|
+
spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType]
|
|
644
644
|
|
|
645
645
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
646
646
|
"""Return the inner Python object wrapped by this Modal Function.
|