modal 1.4.4.dev16__tar.gz → 1.4.4.dev18__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.4.4.dev16 → modal-1.4.4.dev18}/PKG-INFO +1 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_container_entrypoint.py +10 -12
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_function_variants.py +43 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_functions.py +23 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_image.py +8 -3
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_object.py +0 -18
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/user_code_imports.py +2 -4
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/grpc_utils.py +4 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/sandbox_fs_utils.py +47 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/billing.py +5 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/client.pyi +2 -2
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cls.py +8 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cls.pyi +14 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/dict.py +0 -21
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/dict.pyi +0 -56
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/file_io.py +4 -19
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/file_io.pyi +9 -34
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/functions.pyi +21 -7
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/object.pyi +0 -6
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/queue.py +0 -18
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/queue.pyi +0 -56
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/sandbox.py +34 -17
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/sandbox.pyi +35 -15
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/sandbox_fs.py +141 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/sandbox_fs.pyi +196 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/secret.py +0 -18
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/secret.pyi +0 -41
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/volume.py +0 -54
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/volume.pyi +0 -124
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/api_grpc.py +48 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/api_pb2.py +621 -581
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/api_pb2.pyi +83 -2
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/api_pb2_grpc.py +99 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/api_pb2_grpc.pyi +30 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/modal_api_grpc.py +3 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_version/__init__.py +1 -1
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/LICENSE +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/README.md +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/__main__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_billing.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_clustered_functions.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_clustered_functions.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_environments.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_grpc_client.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_ipython.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_load_context.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_location.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_logs.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_output/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_output/manager.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_output/pty.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_output/rich.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_output/status.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_partial_function.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_resolver.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_resources.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/asgi.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/execution_context.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/telemetry.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_serialization.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_server.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_traceback.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_tunnel.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_tunnel.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_type_manager.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/app_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/async_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/blob_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/browser_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/deprecation.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/docker_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/function_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/git_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/hash_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/http_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/logger.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/mount_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/name_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/package_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/shell_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_utils/time_utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_vendor/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_vendor/tblib.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_vendor/version.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_watcher.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/_workspace.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/app.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/app.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/2023.12.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/2024.04.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/2024.10.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/2025.06.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/README.md +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/builder/base-images.json +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/call_graph.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/_download.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/_help.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/_traceback.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/app.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/billing.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/bootstrap.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/changelog.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/cluster.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/config.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/container.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/dashboard.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/dict.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/entry_point.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/environment.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/import_refs.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/launch.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/logo.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/network_file_system.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/profile.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/programs/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/programs/vscode.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/queues.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/run.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/secret.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/selector.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/shell.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/skills.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/token.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/utils.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cli/volume.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/client.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/config.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/container_process.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/container_process.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/environments.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/environments.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/exception.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/experimental/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/experimental/flash.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/experimental/flash.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/experimental/ipython.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/file_pattern_matcher.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/functions.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/image.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/image.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/io_streams.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/io_streams.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/mount.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/mount.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/network_file_system.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/network_file_system.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/object.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/output.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/parallel_map.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/parallel_map.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/partial_function.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/partial_function.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/proxy.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/proxy.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/py.typed +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/retries.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/runner.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/runner.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/running_app.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/schedule.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/scheduler_placement.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/server.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/server.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/serving.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/serving.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/snapshot.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/snapshot.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/stream_type.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/token_flow.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/token_flow.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/workspace.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal/workspace.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal.egg-info/requires.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal.egg-info/top_level.txt +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_docs/mdmd/types.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/__init__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/py.typed +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/modal_version/__main__.py +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/pyproject.toml +0 -0
- {modal-1.4.4.dev16 → modal-1.4.4.dev18}/setup.cfg +0 -0
|
@@ -28,7 +28,7 @@ from modal._clustered_functions import initialize_clustered_function
|
|
|
28
28
|
from modal._runtime.user_code_event_loop import UserCodeEventLoop
|
|
29
29
|
from modal._serialization import deserialize, deserialize_params
|
|
30
30
|
from modal._utils.async_utils import TaskContext, aclosing, synchronizer
|
|
31
|
-
from modal.app import
|
|
31
|
+
from modal.app import _App
|
|
32
32
|
from modal.client import Client, _Client
|
|
33
33
|
from modal.config import logger
|
|
34
34
|
from modal.exception import ExecutionError, InputCancellation
|
|
@@ -288,7 +288,7 @@ def get_serialized_user_class_and_function(
|
|
|
288
288
|
|
|
289
289
|
|
|
290
290
|
def get_server_service(
|
|
291
|
-
container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client
|
|
291
|
+
container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client
|
|
292
292
|
) -> Service:
|
|
293
293
|
ser_usr_cls, ser_fun = get_serialized_user_class_and_function(function_def, _client)
|
|
294
294
|
service_base_function_id = container_args.app_layout.function_ids[function_def.function_name]
|
|
@@ -298,14 +298,14 @@ def get_server_service(
|
|
|
298
298
|
service = import_server_service(
|
|
299
299
|
function_def,
|
|
300
300
|
service_function_hydration_data,
|
|
301
|
-
|
|
301
|
+
_client,
|
|
302
302
|
ser_usr_cls,
|
|
303
303
|
)
|
|
304
304
|
return service
|
|
305
305
|
|
|
306
306
|
|
|
307
307
|
def get_class_service(
|
|
308
|
-
container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client
|
|
308
|
+
container_args: api_pb2.ContainerArguments, function_def: api_pb2.Function, _client: _Client
|
|
309
309
|
) -> Service:
|
|
310
310
|
ser_usr_cls, ser_fun = get_serialized_user_class_and_function(function_def, _client)
|
|
311
311
|
if container_args.serialized_params:
|
|
@@ -326,7 +326,7 @@ def get_class_service(
|
|
|
326
326
|
function_def,
|
|
327
327
|
service_function_hydration_data,
|
|
328
328
|
class_id,
|
|
329
|
-
|
|
329
|
+
_client,
|
|
330
330
|
ser_usr_cls,
|
|
331
331
|
param_args,
|
|
332
332
|
param_kwargs,
|
|
@@ -349,16 +349,15 @@ def hydrate_function(
|
|
|
349
349
|
task_lifecycle_manager: TaskLifecycleManager,
|
|
350
350
|
function_def: api_pb2.Function,
|
|
351
351
|
_client: _Client,
|
|
352
|
-
client: Client,
|
|
353
352
|
) -> Service:
|
|
354
353
|
active_app: _App
|
|
355
354
|
service: Service
|
|
356
355
|
with task_lifecycle_manager.handle_task_lifecycle_exception():
|
|
357
356
|
with execution_context._import_context():
|
|
358
357
|
if function_def.is_server:
|
|
359
|
-
service = get_server_service(container_args, function_def, _client
|
|
358
|
+
service = get_server_service(container_args, function_def, _client)
|
|
360
359
|
elif function_def.is_class:
|
|
361
|
-
service = get_class_service(container_args, function_def, _client
|
|
360
|
+
service = get_class_service(container_args, function_def, _client)
|
|
362
361
|
else:
|
|
363
362
|
service = get_function_service(function_def, _client)
|
|
364
363
|
|
|
@@ -369,8 +368,7 @@ def hydrate_function(
|
|
|
369
368
|
|
|
370
369
|
# Initialize objects on the app.
|
|
371
370
|
# This is basically only functions and classes - anything else is deprecated and will be unsupported soon
|
|
372
|
-
|
|
373
|
-
app._init_container(client, container_app)
|
|
371
|
+
active_app._init_container(_client, container_app)
|
|
374
372
|
|
|
375
373
|
# Hydrate all function dependencies.
|
|
376
374
|
# TODO(erikbern): we an remove this once we
|
|
@@ -406,7 +404,7 @@ def run_server(container_args: api_pb2.ContainerArguments, client: Client):
|
|
|
406
404
|
client,
|
|
407
405
|
)
|
|
408
406
|
|
|
409
|
-
service: Service = hydrate_function(container_args, task_lifecycle_manager, function_def, _client
|
|
407
|
+
service: Service = hydrate_function(container_args, task_lifecycle_manager, function_def, _client)
|
|
410
408
|
# Initialize clustered functions.
|
|
411
409
|
if function_def._experimental_group_size > 0:
|
|
412
410
|
initialize_clustered_function(
|
|
@@ -442,7 +440,7 @@ def run_function(container_args: api_pb2.ContainerArguments, client: Client):
|
|
|
442
440
|
with container_io_manager.heartbeats(is_snapshotting_function), UserCodeEventLoop() as event_loop:
|
|
443
441
|
# Initialize the function, importing user code.
|
|
444
442
|
service: Service = hydrate_function(
|
|
445
|
-
container_args, container_io_manager.get_task_lifecycle_manager(), function_def, _client
|
|
443
|
+
container_args, container_io_manager.get_task_lifecycle_manager(), function_def, _client
|
|
446
444
|
)
|
|
447
445
|
if function_def.pty_info.pty_type == api_pb2.PTYInfo.PTY_TYPE_SHELL:
|
|
448
446
|
# Concurrency and batching doesn't apply for `modal shell`.
|
|
@@ -185,6 +185,48 @@ class _FunctionOptions:
|
|
|
185
185
|
)
|
|
186
186
|
|
|
187
187
|
|
|
188
|
+
async def _function_bind_params_cached(
|
|
189
|
+
base_function: "_Function",
|
|
190
|
+
req: api_pb2.FunctionBindParamsRequest,
|
|
191
|
+
) -> api_pb2.FunctionBindParamsResponse:
|
|
192
|
+
"""Cache layer for FunctionBindParams RPCs, scoped to a base Function handle.
|
|
193
|
+
|
|
194
|
+
We have this because users probably do not realize that Function invocations structured as
|
|
195
|
+
|
|
196
|
+
res = f.with_options(...).remote(...)
|
|
197
|
+
|
|
198
|
+
would always need to do two sequential RPCs (bind params / call function variant).
|
|
199
|
+
|
|
200
|
+
The bound Function ID from FunctionBindParams is deterministic with respect to the full request,
|
|
201
|
+
so we can avoid the unnecessary call and hydrate the new instance from a cached response.
|
|
202
|
+
|
|
203
|
+
The cache is stored on the base Function handle so that the variant cache behaves similarly to
|
|
204
|
+
the local reference to the base Function metadata.
|
|
205
|
+
|
|
206
|
+
"""
|
|
207
|
+
cache = base_function._bind_params_cache
|
|
208
|
+
cache_key = req.SerializeToString(deterministic=True)
|
|
209
|
+
|
|
210
|
+
cached_response = cache.get(cache_key)
|
|
211
|
+
if cached_response is not None:
|
|
212
|
+
cache.move_to_end(cache_key)
|
|
213
|
+
response = api_pb2.FunctionBindParamsResponse()
|
|
214
|
+
response.ParseFromString(cached_response)
|
|
215
|
+
return response
|
|
216
|
+
|
|
217
|
+
assert base_function._client and base_function._client.stub
|
|
218
|
+
response = await base_function._client.stub.FunctionBindParams(req)
|
|
219
|
+
|
|
220
|
+
cache[cache_key] = response.SerializeToString(deterministic=True)
|
|
221
|
+
cache.move_to_end(cache_key)
|
|
222
|
+
|
|
223
|
+
max_cache_size = 32
|
|
224
|
+
while len(cache) > max_cache_size:
|
|
225
|
+
cache.popitem(last=False)
|
|
226
|
+
|
|
227
|
+
return response
|
|
228
|
+
|
|
229
|
+
|
|
188
230
|
def _make_function_variant(
|
|
189
231
|
base_function: "_Function",
|
|
190
232
|
options: _FunctionOptions | None,
|
|
@@ -229,7 +271,7 @@ def _make_function_variant(
|
|
|
229
271
|
or "", # TODO: investigate shouldn't environment name always be specified here?
|
|
230
272
|
)
|
|
231
273
|
|
|
232
|
-
response = await base_function
|
|
274
|
+
response = await _function_bind_params_cached(base_function, req)
|
|
233
275
|
function_variant._hydrate(response.bound_function_id, base_function._client, response.handle_metadata)
|
|
234
276
|
|
|
235
277
|
def _deps():
|
|
@@ -5,6 +5,7 @@ import inspect
|
|
|
5
5
|
import time
|
|
6
6
|
import typing
|
|
7
7
|
import warnings
|
|
8
|
+
from collections import OrderedDict
|
|
8
9
|
from collections.abc import AsyncGenerator, AsyncIterator, Callable, Collection, Sequence
|
|
9
10
|
from dataclasses import dataclass
|
|
10
11
|
from pathlib import PurePosixPath
|
|
@@ -1208,6 +1209,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1208
1209
|
app_name: str,
|
|
1209
1210
|
name: str,
|
|
1210
1211
|
*,
|
|
1212
|
+
version: int | None = None,
|
|
1211
1213
|
load_context_overrides: LoadContext,
|
|
1212
1214
|
):
|
|
1213
1215
|
# internal function lookup implementation that allows lookup of class "service functions"
|
|
@@ -1219,6 +1221,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1219
1221
|
app_name=app_name,
|
|
1220
1222
|
object_tag=name,
|
|
1221
1223
|
environment_name=load_context.environment_name,
|
|
1224
|
+
app_version=version or 0,
|
|
1222
1225
|
)
|
|
1223
1226
|
try:
|
|
1224
1227
|
response = await load_context.client.stub.FunctionGet(request)
|
|
@@ -1251,6 +1254,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1251
1254
|
app_name: str,
|
|
1252
1255
|
name: str,
|
|
1253
1256
|
*,
|
|
1257
|
+
version: int | None = None,
|
|
1254
1258
|
environment_name: str | None = None,
|
|
1255
1259
|
client: _Client | None = None,
|
|
1256
1260
|
) -> "_Function":
|
|
@@ -1273,6 +1277,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1273
1277
|
```python
|
|
1274
1278
|
f = modal.Function.from_name("other-app", "function")
|
|
1275
1279
|
```
|
|
1280
|
+
|
|
1281
|
+
The `version` parameter allows you to invoke a version-pinned function:
|
|
1282
|
+
|
|
1283
|
+
```python
|
|
1284
|
+
f_v3 = modal.Function.from_name("other-app", "function", version=3)
|
|
1285
|
+
```
|
|
1276
1286
|
"""
|
|
1277
1287
|
if "." in name:
|
|
1278
1288
|
raise InvalidError(
|
|
@@ -1281,7 +1291,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1281
1291
|
)
|
|
1282
1292
|
|
|
1283
1293
|
return cls._from_name(
|
|
1284
|
-
app_name,
|
|
1294
|
+
app_name,
|
|
1295
|
+
name,
|
|
1296
|
+
load_context_overrides=LoadContext(environment_name=environment_name, client=client),
|
|
1297
|
+
version=version,
|
|
1285
1298
|
)
|
|
1286
1299
|
|
|
1287
1300
|
@property
|
|
@@ -1342,6 +1355,11 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1342
1355
|
self._options = _FunctionOptions()
|
|
1343
1356
|
self._base_function = None
|
|
1344
1357
|
|
|
1358
|
+
# An OrderedDict[bytes, bytes] LRU of FunctionBindParams responses for
|
|
1359
|
+
# variants derived from this base Function. Omitted from class-level annotations because
|
|
1360
|
+
# Synchronicity doesn't understand OrderedDict as a type hint.
|
|
1361
|
+
self._bind_params_cache = OrderedDict()
|
|
1362
|
+
|
|
1345
1363
|
def _hydrate_metadata(self, metadata: Message | None):
|
|
1346
1364
|
# Overridden concrete implementation of base class method
|
|
1347
1365
|
assert metadata and isinstance(metadata, api_pb2.FunctionHandleMetadata), (
|
|
@@ -1370,6 +1388,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1370
1388
|
)
|
|
1371
1389
|
self._experimental_flash_urls = metadata._experimental_flash_urls
|
|
1372
1390
|
|
|
1391
|
+
# Invalidate the Function variant cache when we load new metadata, since the base Function handle
|
|
1392
|
+
# is now in sync with the server but any previously-cached variants may be stale.
|
|
1393
|
+
self._bind_params_cache.clear()
|
|
1394
|
+
|
|
1373
1395
|
def _get_metadata(self):
|
|
1374
1396
|
# Overridden concrete implementation of base class method
|
|
1375
1397
|
assert self._function_name, f"Function name must be set before metadata can be retrieved for {self}"
|
|
@@ -60,6 +60,7 @@ from .secret import _Secret
|
|
|
60
60
|
from .volume import _Volume, _volume_to_mount_proto
|
|
61
61
|
|
|
62
62
|
if typing.TYPE_CHECKING:
|
|
63
|
+
import modal
|
|
63
64
|
import modal._functions
|
|
64
65
|
import modal.client
|
|
65
66
|
|
|
@@ -531,7 +532,7 @@ class _Image(_Object, type_prefix="im"):
|
|
|
531
532
|
|
|
532
533
|
for secret in secrets:
|
|
533
534
|
if not isinstance(secret, _Secret):
|
|
534
|
-
raise InvalidError("All secrets of an
|
|
535
|
+
raise InvalidError("All secrets of an Image need to be modal.Secret instances.")
|
|
535
536
|
|
|
536
537
|
if build_function and len(base_images) != 1:
|
|
537
538
|
raise InvalidError("Cannot run a build function with multiple base images!")
|
|
@@ -2763,7 +2764,7 @@ class _Image(_Object, type_prefix="im"):
|
|
|
2763
2764
|
|
|
2764
2765
|
def pipe(
|
|
2765
2766
|
self,
|
|
2766
|
-
func: Callable[Concatenate["
|
|
2767
|
+
func: Callable[Concatenate["modal.Image", P], "modal.Image"],
|
|
2767
2768
|
*args: P.args,
|
|
2768
2769
|
**kwargs: P.kwargs,
|
|
2769
2770
|
) -> "_Image":
|
|
@@ -2785,7 +2786,11 @@ class _Image(_Object, type_prefix="im"):
|
|
|
2785
2786
|
)
|
|
2786
2787
|
```
|
|
2787
2788
|
"""
|
|
2788
|
-
|
|
2789
|
+
# Typing here is complicated because user callables accept the public
|
|
2790
|
+
# Image type, but `self` is an instance of the internal _Image type.
|
|
2791
|
+
self_ = synchronizer._translate_out(self)
|
|
2792
|
+
res = func(self_, *args, **kwargs) # type: ignore[reportUnknownReturnType]
|
|
2793
|
+
return typing.cast(_Image, synchronizer._translate_in(res))
|
|
2789
2794
|
|
|
2790
2795
|
# Live handle methods
|
|
2791
2796
|
|
|
@@ -14,7 +14,6 @@ from modal._traceback import suppress_tb_frame
|
|
|
14
14
|
from ._load_context import LoadContext
|
|
15
15
|
from ._resolver import Resolver
|
|
16
16
|
from ._utils.async_utils import TaskContext, aclosing
|
|
17
|
-
from ._utils.deprecation import deprecation_warning
|
|
18
17
|
from .client import _Client
|
|
19
18
|
from .config import config, logger
|
|
20
19
|
from .exception import ExecutionError, InvalidError
|
|
@@ -196,23 +195,6 @@ class _Object:
|
|
|
196
195
|
f"{object_type} has not been hydrated with the metadata it needs to run on Modal{reason}."
|
|
197
196
|
)
|
|
198
197
|
|
|
199
|
-
def clone(self) -> Self:
|
|
200
|
-
"""mdmd:hidden Clone a given hydrated object.
|
|
201
|
-
|
|
202
|
-
Note: This is not intended to be public API and has no public use. It will be removed in a future release.
|
|
203
|
-
"""
|
|
204
|
-
object_class = self.__class__.__name__.strip("_")
|
|
205
|
-
deprecation_warning(
|
|
206
|
-
(2025, 6, 30),
|
|
207
|
-
f"{object_class}.clone() is not intended to be public API and will be removed in a future release.",
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
# Object to clone must already be hydrated, otherwise from_loader is more suitable.
|
|
211
|
-
self._validate_is_hydrated()
|
|
212
|
-
obj = type(self).__new__(type(self))
|
|
213
|
-
obj._initialize_from_other(self)
|
|
214
|
-
return obj
|
|
215
|
-
|
|
216
198
|
@classmethod
|
|
217
199
|
def _from_loader(
|
|
218
200
|
cls,
|
|
@@ -571,7 +571,7 @@ def import_class_service(
|
|
|
571
571
|
function_def: api_pb2.Function,
|
|
572
572
|
service_function_hydration_data: api_pb2.Object,
|
|
573
573
|
class_id: str,
|
|
574
|
-
|
|
574
|
+
_client: "modal.client._Client",
|
|
575
575
|
ser_user_cls: type | None,
|
|
576
576
|
cls_args,
|
|
577
577
|
cls_kwargs,
|
|
@@ -599,7 +599,6 @@ def import_class_service(
|
|
|
599
599
|
# Undecorated user class (serialized or local scope-decoration).
|
|
600
600
|
service_deps = None # we can't infer service deps for now
|
|
601
601
|
active_app = get_active_app_fallback(function_def)
|
|
602
|
-
_client = typing.cast("modal.client._Client", synchronizer._translate_in(client))
|
|
603
602
|
_service_function: modal._functions._Function[Any, Any, Any] = modal._functions._Function._new_hydrated(
|
|
604
603
|
service_function_hydration_data.object_id,
|
|
605
604
|
_client,
|
|
@@ -627,7 +626,7 @@ def import_class_service(
|
|
|
627
626
|
def import_server_service(
|
|
628
627
|
function_def: api_pb2.Function,
|
|
629
628
|
service_function_hydration_data: api_pb2.Object,
|
|
630
|
-
|
|
629
|
+
_client: "modal.client._Client",
|
|
631
630
|
ser_user_cls: type | None,
|
|
632
631
|
) -> Service:
|
|
633
632
|
"""
|
|
@@ -654,7 +653,6 @@ def import_server_service(
|
|
|
654
653
|
# Undecorated user class (serialized or local scope-decoration).
|
|
655
654
|
service_deps = None # we can't infer service deps for now
|
|
656
655
|
active_app = get_active_app_fallback(function_def)
|
|
657
|
-
_client = typing.cast("modal.client._Client", synchronizer._translate_in(client))
|
|
658
656
|
_service_function: modal._functions._Function[Any, Any, Any] = modal._functions._Function._new_hydrated(
|
|
659
657
|
service_function_hydration_data.object_id,
|
|
660
658
|
_client,
|
|
@@ -153,7 +153,10 @@ class CustomProtoStatusDetailsCodec(StatusDetailsCodecBase):
|
|
|
153
153
|
if details is not None:
|
|
154
154
|
for detail in details:
|
|
155
155
|
detail_container = details_proto.details.add()
|
|
156
|
-
|
|
156
|
+
if detail.DESCRIPTOR.full_name.startswith("modal."):
|
|
157
|
+
detail_container.Pack(detail, type_url_prefix="type.modal.com/")
|
|
158
|
+
else:
|
|
159
|
+
detail_container.Pack(detail)
|
|
157
160
|
return details_proto.SerializeToString()
|
|
158
161
|
|
|
159
162
|
def decode(
|
|
@@ -285,6 +285,53 @@ def make_stat_command(remote_path: str) -> str:
|
|
|
285
285
|
return json.dumps({"Stat": {"path": remote_path}})
|
|
286
286
|
|
|
287
287
|
|
|
288
|
+
def raise_watch_error(returncode: int, stderr: str | bytes, remote_path: str) -> NoReturn:
|
|
289
|
+
if payload := try_parse_error_payload(stderr):
|
|
290
|
+
logger.debug(
|
|
291
|
+
f"sandbox-fs-tools watch error: path={remote_path}, "
|
|
292
|
+
f"error_kind={payload.error_kind}, message={payload.message}, detail={payload.detail}"
|
|
293
|
+
)
|
|
294
|
+
if payload.error_kind == "NotFound":
|
|
295
|
+
raise SandboxFilesystemNotFoundError(f"{payload.message}: {remote_path}")
|
|
296
|
+
if payload.error_kind == "PermissionDenied":
|
|
297
|
+
raise SandboxFilesystemPermissionError(f"{payload.message}: {remote_path}")
|
|
298
|
+
if payload.error_kind == "NotSupported":
|
|
299
|
+
raise InvalidError(
|
|
300
|
+
f"{payload.message}: {remote_path} - this operation is not supported for CloudBucketMounts"
|
|
301
|
+
)
|
|
302
|
+
raise SandboxFilesystemError(payload.message)
|
|
303
|
+
|
|
304
|
+
if stderr_text := _stderr_to_text(stderr):
|
|
305
|
+
logger.debug(f"Unstructured modal-sandbox-fs-tools stderr: {stderr_text}")
|
|
306
|
+
raise SandboxFilesystemError(f"Operation on '{remote_path}' failed with exit code {returncode}")
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def make_watch_command(
|
|
310
|
+
remote_path: str,
|
|
311
|
+
*,
|
|
312
|
+
recursive: bool,
|
|
313
|
+
filter: list[str] | None,
|
|
314
|
+
timeout: int | None,
|
|
315
|
+
) -> str:
|
|
316
|
+
"""Build the JSON command string for a Watch operation.
|
|
317
|
+
|
|
318
|
+
The returned JSON must match the `Command` enum in the modal-sandbox-fs-tools
|
|
319
|
+
Rust crate (crates/modal-sandbox-fs-tools/src/lib.rs). Treat changes to
|
|
320
|
+
this schema like protobuf changes: fields must not be removed or renamed,
|
|
321
|
+
only added with backwards-compatible defaults.
|
|
322
|
+
"""
|
|
323
|
+
return json.dumps(
|
|
324
|
+
{
|
|
325
|
+
"Watch": {
|
|
326
|
+
"path": remote_path,
|
|
327
|
+
"recursive": recursive,
|
|
328
|
+
"filter": filter,
|
|
329
|
+
"timeout_secs": timeout,
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
|
|
288
335
|
def validate_absolute_remote_path(remote_path: str, operation: str) -> None:
|
|
289
336
|
if not PurePosixPath(remote_path).is_absolute():
|
|
290
337
|
raise InvalidError(f"Sandbox.filesystem.{operation}() currently only supports absolute remote_path values")
|
|
@@ -3,4 +3,8 @@ from ._billing import WorkspaceBillingReportItem, _workspace_billing_report
|
|
|
3
3
|
from ._utils.async_utils import synchronize_api
|
|
4
4
|
|
|
5
5
|
workspace_billing_report = synchronize_api(_workspace_billing_report)
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"workspace_billing_report",
|
|
9
|
+
"WorkspaceBillingReportItem",
|
|
10
|
+
]
|
|
@@ -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.4.4.
|
|
38
|
+
version: str = "1.4.4.dev18",
|
|
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.4.4.
|
|
208
|
+
version: str = "1.4.4.dev18",
|
|
209
209
|
):
|
|
210
210
|
"""mdmd:hidden
|
|
211
211
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -641,6 +641,7 @@ More information on class parameterization can be found here: https://modal.com/
|
|
|
641
641
|
app_name: str,
|
|
642
642
|
name: str,
|
|
643
643
|
*,
|
|
644
|
+
version: int | None = None,
|
|
644
645
|
environment_name: str | None = None,
|
|
645
646
|
client: "_Client | None" = None,
|
|
646
647
|
) -> "_Cls":
|
|
@@ -663,6 +664,12 @@ More information on class parameterization can be found here: https://modal.com/
|
|
|
663
664
|
```python
|
|
664
665
|
Model = modal.Cls.from_name("other-app", "Model")
|
|
665
666
|
```
|
|
667
|
+
|
|
668
|
+
The `version` parameter constructs a version-pinned Cls:
|
|
669
|
+
|
|
670
|
+
```python
|
|
671
|
+
Modelv3 = modal.Cls.from_name("other-app", "Model", version=3)
|
|
672
|
+
```
|
|
666
673
|
"""
|
|
667
674
|
|
|
668
675
|
async def _load_remote(
|
|
@@ -705,6 +712,7 @@ More information on class parameterization can be found here: https://modal.com/
|
|
|
705
712
|
app_name,
|
|
706
713
|
class_service_name,
|
|
707
714
|
load_context_overrides=load_context_overrides,
|
|
715
|
+
version=version,
|
|
708
716
|
)
|
|
709
717
|
cls._name = name
|
|
710
718
|
return cls
|
|
@@ -291,6 +291,7 @@ class _Cls(modal._object._Object):
|
|
|
291
291
|
app_name: str,
|
|
292
292
|
name: str,
|
|
293
293
|
*,
|
|
294
|
+
version: typing.Optional[int] = None,
|
|
294
295
|
environment_name: typing.Optional[str] = None,
|
|
295
296
|
client: typing.Optional[modal.client._Client] = None,
|
|
296
297
|
) -> _Cls:
|
|
@@ -313,6 +314,12 @@ class _Cls(modal._object._Object):
|
|
|
313
314
|
```python
|
|
314
315
|
Model = modal.Cls.from_name("other-app", "Model")
|
|
315
316
|
```
|
|
317
|
+
|
|
318
|
+
The `version` parameter constructs a version-pinned Cls:
|
|
319
|
+
|
|
320
|
+
```python
|
|
321
|
+
Modelv3 = modal.Cls.from_name("other-app", "Model", version=3)
|
|
322
|
+
```
|
|
316
323
|
"""
|
|
317
324
|
...
|
|
318
325
|
|
|
@@ -498,6 +505,7 @@ class Cls(modal.object.Object):
|
|
|
498
505
|
app_name: str,
|
|
499
506
|
name: str,
|
|
500
507
|
*,
|
|
508
|
+
version: typing.Optional[int] = None,
|
|
501
509
|
environment_name: typing.Optional[str] = None,
|
|
502
510
|
client: typing.Optional[modal.client.Client] = None,
|
|
503
511
|
) -> Cls:
|
|
@@ -520,6 +528,12 @@ class Cls(modal.object.Object):
|
|
|
520
528
|
```python
|
|
521
529
|
Model = modal.Cls.from_name("other-app", "Model")
|
|
522
530
|
```
|
|
531
|
+
|
|
532
|
+
The `version` parameter constructs a version-pinned Cls:
|
|
533
|
+
|
|
534
|
+
```python
|
|
535
|
+
Modelv3 = modal.Cls.from_name("other-app", "Model", version=3)
|
|
536
|
+
```
|
|
523
537
|
"""
|
|
524
538
|
...
|
|
525
539
|
|
|
@@ -23,7 +23,6 @@ from ._object import (
|
|
|
23
23
|
from ._resolver import Resolver
|
|
24
24
|
from ._serialization import deserialize, serialize
|
|
25
25
|
from ._utils.async_utils import TaskContext, synchronize_api
|
|
26
|
-
from ._utils.deprecation import deprecation_warning
|
|
27
26
|
from ._utils.name_utils import check_object_name
|
|
28
27
|
from ._utils.time_utils import as_timestamp, timestamp_to_localized_dt
|
|
29
28
|
from .client import _Client
|
|
@@ -482,26 +481,6 @@ class _Dict(_Object, type_prefix="di"):
|
|
|
482
481
|
load_context_overrides=LoadContext(client=client),
|
|
483
482
|
)
|
|
484
483
|
|
|
485
|
-
@staticmethod
|
|
486
|
-
async def delete(
|
|
487
|
-
name: str,
|
|
488
|
-
*,
|
|
489
|
-
client: _Client | None = None,
|
|
490
|
-
environment_name: str | None = None,
|
|
491
|
-
):
|
|
492
|
-
"""mdmd:hidden
|
|
493
|
-
Delete a named Dict object.
|
|
494
|
-
|
|
495
|
-
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
496
|
-
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
497
|
-
|
|
498
|
-
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
499
|
-
"""
|
|
500
|
-
deprecation_warning(
|
|
501
|
-
(2025, 8, 6), "`modal.Dict.delete` is deprecated; we recommend using `modal.Dict.objects.delete` instead."
|
|
502
|
-
)
|
|
503
|
-
await _Dict.objects.delete(name, environment_name=environment_name, client=client)
|
|
504
|
-
|
|
505
484
|
@live_method
|
|
506
485
|
async def info(self) -> DictInfo:
|
|
507
486
|
"""Return information about the Dict object."""
|
|
@@ -576,23 +576,6 @@ class _Dict(modal._object._Object):
|
|
|
576
576
|
"""
|
|
577
577
|
...
|
|
578
578
|
|
|
579
|
-
@staticmethod
|
|
580
|
-
async def delete(
|
|
581
|
-
name: str,
|
|
582
|
-
*,
|
|
583
|
-
client: typing.Optional[modal.client._Client] = None,
|
|
584
|
-
environment_name: typing.Optional[str] = None,
|
|
585
|
-
):
|
|
586
|
-
"""mdmd:hidden
|
|
587
|
-
Delete a named Dict object.
|
|
588
|
-
|
|
589
|
-
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
590
|
-
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
591
|
-
|
|
592
|
-
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
593
|
-
"""
|
|
594
|
-
...
|
|
595
|
-
|
|
596
579
|
async def info(self) -> DictInfo:
|
|
597
580
|
"""Return information about the Dict object."""
|
|
598
581
|
...
|
|
@@ -877,45 +860,6 @@ class Dict(modal.object.Object):
|
|
|
877
860
|
"""
|
|
878
861
|
...
|
|
879
862
|
|
|
880
|
-
class __delete_spec(typing_extensions.Protocol):
|
|
881
|
-
def __call__(
|
|
882
|
-
self,
|
|
883
|
-
/,
|
|
884
|
-
name: str,
|
|
885
|
-
*,
|
|
886
|
-
client: typing.Optional[modal.client.Client] = None,
|
|
887
|
-
environment_name: typing.Optional[str] = None,
|
|
888
|
-
):
|
|
889
|
-
"""mdmd:hidden
|
|
890
|
-
Delete a named Dict object.
|
|
891
|
-
|
|
892
|
-
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
893
|
-
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
894
|
-
|
|
895
|
-
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
896
|
-
"""
|
|
897
|
-
...
|
|
898
|
-
|
|
899
|
-
async def aio(
|
|
900
|
-
self,
|
|
901
|
-
/,
|
|
902
|
-
name: str,
|
|
903
|
-
*,
|
|
904
|
-
client: typing.Optional[modal.client.Client] = None,
|
|
905
|
-
environment_name: typing.Optional[str] = None,
|
|
906
|
-
):
|
|
907
|
-
"""mdmd:hidden
|
|
908
|
-
Delete a named Dict object.
|
|
909
|
-
|
|
910
|
-
Warning: This deletes an *entire Dict*, not just a specific key.
|
|
911
|
-
Deletion is irreversible and will affect any Apps currently using the Dict.
|
|
912
|
-
|
|
913
|
-
DEPRECATED: This method is deprecated; we recommend using `modal.Dict.objects.delete` instead.
|
|
914
|
-
"""
|
|
915
|
-
...
|
|
916
|
-
|
|
917
|
-
delete: typing.ClassVar[__delete_spec]
|
|
918
|
-
|
|
919
863
|
class __info_spec(typing_extensions.Protocol):
|
|
920
864
|
def __call__(self, /) -> DictInfo:
|
|
921
865
|
"""Return information about the Dict object."""
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
# Copyright Modal Labs 2024
|
|
2
2
|
import asyncio
|
|
3
|
-
import enum
|
|
4
3
|
import io
|
|
5
4
|
from collections.abc import AsyncIterator, Sequence
|
|
6
|
-
from
|
|
7
|
-
from typing import TYPE_CHECKING, Generic, TypeVar, Union, cast
|
|
5
|
+
from typing import TYPE_CHECKING, Generic, Optional, TypeVar, Union, cast
|
|
8
6
|
|
|
9
7
|
if TYPE_CHECKING:
|
|
10
8
|
import _typeshed
|
|
@@ -15,6 +13,7 @@ from grpclib.exceptions import StreamTerminatedError
|
|
|
15
13
|
|
|
16
14
|
from modal._utils.async_utils import TaskContext
|
|
17
15
|
from modal.exception import ClientClosed
|
|
16
|
+
from modal.sandbox_fs import FileWatchEvent, FileWatchEventType
|
|
18
17
|
from modal_proto import api_pb2
|
|
19
18
|
|
|
20
19
|
from ._utils.async_utils import synchronize_api
|
|
@@ -60,21 +59,7 @@ async def _replace_bytes(file: "_FileIO", data: bytes, start: int | None = None,
|
|
|
60
59
|
deprecation_error((2025, 12, 3), "replace_bytes has been removed.")
|
|
61
60
|
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
Unknown = "Unknown"
|
|
65
|
-
Access = "Access"
|
|
66
|
-
Create = "Create"
|
|
67
|
-
Modify = "Modify"
|
|
68
|
-
Remove = "Remove"
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@dataclass
|
|
72
|
-
class FileWatchEvent:
|
|
73
|
-
paths: list[str]
|
|
74
|
-
type: FileWatchEventType
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
async def _consume_output(client: _Client, exec_id: str) -> AsyncIterator[bytes | None | Exception]:
|
|
62
|
+
async def _consume_output(client: _Client, exec_id: str) -> AsyncIterator[Optional[bytes] | Exception]:
|
|
78
63
|
req = api_pb2.ContainerFilesystemExecGetOutputRequest(
|
|
79
64
|
exec_id=exec_id,
|
|
80
65
|
timeout=55,
|
|
@@ -424,7 +409,7 @@ class _FileIO(Generic[T]):
|
|
|
424
409
|
) -> AsyncIterator[FileWatchEvent]:
|
|
425
410
|
deprecation_warning(
|
|
426
411
|
(2026, 3, 9),
|
|
427
|
-
"`FileIO.watch()` is deprecated. Use `Sandbox.watch()` instead.",
|
|
412
|
+
"`FileIO.watch()` is deprecated. Use `Sandbox.filesystem.watch()` instead.",
|
|
428
413
|
)
|
|
429
414
|
async for event in watch(path, client, task_id, filter, recursive, timeout):
|
|
430
415
|
yield event
|