modal 1.4.4.dev10__tar.gz → 1.4.4.dev11__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.dev10 → modal-1.4.4.dev11}/PKG-INFO +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/__init__.py +2 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_billing.py +4 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_clustered_functions.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_clustered_functions.pyi +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_container_entrypoint.py +13 -7
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_environments.py +23 -23
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_function_variants.py +34 -34
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_functions.py +99 -101
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_grpc_client.py +13 -12
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_load_context.py +14 -14
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_logs.py +7 -7
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_object.py +31 -31
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_output/manager.py +18 -18
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_output/pty.py +8 -8
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_output/rich.py +2 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_output/status.py +1 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_partial_function.py +46 -49
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_resolver.py +3 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_resources.py +6 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/asgi.py +3 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/container_io_manager.py +60 -190
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/container_io_manager.pyi +27 -80
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/execution_context.py +4 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/gpu_memory_snapshot.py +4 -5
- modal-1.4.4.dev11/modal/_runtime/task_lifecycle_manager.py +199 -0
- modal-1.4.4.dev11/modal/_runtime/task_lifecycle_manager.pyi +102 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/user_code_imports.py +124 -66
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_serialization.py +1 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_server.py +11 -12
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_traceback.py +6 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_tunnel.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/async_utils.py +19 -24
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/auth_token_manager.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/blob_utils.py +22 -25
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/bytes_io_segment_payload.py +4 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/deprecation.py +2 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/docker_utils.py +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/function_utils.py +20 -20
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/git_utils.py +2 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/grpc_testing.py +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/grpc_utils.py +16 -16
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/hash_utils.py +7 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/http_utils.py +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/jwt_utils.py +4 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/mount_utils.py +8 -10
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/pattern_utils.py +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/rand_pb_testing.py +4 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/sandbox_fs_utils.py +10 -10
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/shell_utils.py +3 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/task_command_router_client.py +15 -16
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/time_utils.py +4 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_vendor/a2wsgi_wsgi.py +6 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_vendor/cloudpickle.py +1 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_watcher.py +2 -3
- modal-1.4.4.dev11/modal/_workspace.py +116 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/app.py +106 -110
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/call_graph.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/_download.py +5 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/_help.py +12 -12
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/_traceback.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/app.py +17 -17
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/billing.py +5 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/bootstrap.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/changelog.py +6 -7
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/cluster.py +3 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/container.py +10 -11
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/dashboard.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/dict.py +6 -7
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/entry_point.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/environment.py +3 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/import_refs.py +4 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/launch.py +9 -9
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/network_file_system.py +7 -8
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/profile.py +2 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/queues.py +7 -8
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/run.py +11 -10
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/secret.py +5 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/shell.py +21 -20
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/token.py +4 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/utils.py +16 -17
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/volume.py +11 -12
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/client.py +16 -16
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/client.pyi +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cloud_bucket_mount.py +5 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cloud_bucket_mount.pyi +2 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cls.py +40 -40
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cls.pyi +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/config.py +5 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/container_process.py +3 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/dict.py +25 -25
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/exception.py +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/experimental/__init__.py +47 -7
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/experimental/flash.py +23 -22
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/file_io.py +15 -14
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/file_io.pyi +8 -7
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/file_pattern_matcher.py +6 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/functions.pyi +3 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/image.py +133 -137
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/image.pyi +7 -13
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/io_streams.py +21 -25
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/mount.py +29 -30
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/mount.pyi +8 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/network_file_system.py +17 -17
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/object.pyi +33 -75
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/parallel_map.py +16 -17
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/proxy.py +3 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/queue.py +37 -37
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/retries.py +1 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/runner.py +11 -11
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/running_app.py +5 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/sandbox.py +174 -179
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/sandbox.pyi +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/sandbox_fs.py +4 -4
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/scheduler_placement.py +5 -6
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/secret.py +23 -30
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/serving.py +5 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/snapshot.py +3 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/token_flow.py +8 -9
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/volume.py +65 -73
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/volume.pyi +3 -3
- modal-1.4.4.dev11/modal/workspace.py +12 -0
- modal-1.4.4.dev11/modal/workspace.pyi +105 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal.egg-info/PKG-INFO +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal.egg-info/SOURCES.txt +5 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal.egg-info/requires.txt +1 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/gen_cli_docs.py +2 -2
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/mdmd/mdmd.py +3 -3
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/api_pb2.py +802 -802
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/api_pb2.pyi +4 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_version/__init__.py +1 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/pyproject.toml +18 -5
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/LICENSE +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/README.md +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/__main__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_ipython.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_location.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_output/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/telemetry.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_tunnel.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_type_manager.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/app_utils.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/browser_utils.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/logger.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/name_utils.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_utils/package_utils.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_vendor/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_vendor/tblib.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/_vendor/version.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/app.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/billing.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/2023.12.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/2024.04.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/2024.10.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/2025.06.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/README.md +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/builder/base-images.json +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/config.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/logo.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/programs/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/programs/vscode.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/cli/selector.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/container_process.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/dict.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/environments.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/environments.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/experimental/flash.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/experimental/ipython.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/functions.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/io_streams.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/network_file_system.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/object.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/output.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/parallel_map.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/partial_function.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/partial_function.pyi +1 -1
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/proxy.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/py.typed +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/queue.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/runner.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/sandbox_fs.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/schedule.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/secret.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/server.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/server.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/serving.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/snapshot.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/stream_type.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal/token_flow.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal.egg-info/top_level.txt +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/__init__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/api_grpc.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/py.typed +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/modal_version/__main__.py +0 -0
- {modal-1.4.4.dev10 → modal-1.4.4.dev11}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.4.4.
|
|
3
|
+
Version: 1.4.4.dev11
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -23,7 +23,7 @@ Requires-Dist: grpclib<0.4.10,>=0.4.7; python_version < "3.14"
|
|
|
23
23
|
Requires-Dist: grpclib<0.4.10,>=0.4.9; python_version >= "3.14"
|
|
24
24
|
Requires-Dist: protobuf!=4.24.0,<7.0,>=3.19
|
|
25
25
|
Requires-Dist: rich>=12.0.0
|
|
26
|
-
Requires-Dist: synchronicity~=0.12.
|
|
26
|
+
Requires-Dist: synchronicity~=0.12.3
|
|
27
27
|
Requires-Dist: toml
|
|
28
28
|
Requires-Dist: types-certifi
|
|
29
29
|
Requires-Dist: types-toml
|
|
@@ -45,6 +45,7 @@ try:
|
|
|
45
45
|
from .secret import Secret
|
|
46
46
|
from .snapshot import SandboxSnapshot
|
|
47
47
|
from .volume import Volume
|
|
48
|
+
from .workspace import Workspace
|
|
48
49
|
except Exception:
|
|
49
50
|
print()
|
|
50
51
|
print("#" * 80)
|
|
@@ -81,6 +82,7 @@ __all__ = [
|
|
|
81
82
|
"Secret",
|
|
82
83
|
"Tunnel",
|
|
83
84
|
"Volume",
|
|
85
|
+
"Workspace",
|
|
84
86
|
"asgi_app",
|
|
85
87
|
"batched",
|
|
86
88
|
"billing",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright Modal Labs 2025
|
|
2
2
|
from datetime import datetime, timezone
|
|
3
3
|
from decimal import Decimal
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import TypedDict
|
|
5
5
|
|
|
6
6
|
from modal_proto import api_pb2
|
|
7
7
|
|
|
@@ -21,10 +21,10 @@ class WorkspaceBillingReportItem(TypedDict):
|
|
|
21
21
|
async def _workspace_billing_report(
|
|
22
22
|
*,
|
|
23
23
|
start: datetime, # Start of the report, inclusive
|
|
24
|
-
end:
|
|
24
|
+
end: datetime | None = None, # End of the report, exclusive
|
|
25
25
|
resolution: str = "d", # Resolution, e.g. "d" for daily or "h" for hourly
|
|
26
|
-
tag_names:
|
|
27
|
-
client:
|
|
26
|
+
tag_names: list[str] | None = None, # Optional additional metadata to include
|
|
27
|
+
client: _Client | None = None,
|
|
28
28
|
) -> list[WorkspaceBillingReportItem]:
|
|
29
29
|
"""Generate a tabular report of workspace usage by object and time.
|
|
30
30
|
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import os
|
|
3
3
|
import socket
|
|
4
4
|
from dataclasses import dataclass
|
|
5
|
-
from typing import Optional
|
|
6
5
|
|
|
7
6
|
from modal._utils.async_utils import synchronize_api
|
|
8
7
|
from modal.client import _Client
|
|
@@ -18,7 +17,7 @@ class ClusterInfo:
|
|
|
18
17
|
container_ipv4_ips: list[str]
|
|
19
18
|
|
|
20
19
|
|
|
21
|
-
cluster_info:
|
|
20
|
+
cluster_info: ClusterInfo | None = None
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
def get_cluster_info() -> ClusterInfo:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import modal.client
|
|
2
|
-
import
|
|
2
|
+
import types
|
|
3
3
|
import typing_extensions
|
|
4
4
|
|
|
5
5
|
class ClusterInfo:
|
|
@@ -31,4 +31,4 @@ class __initialize_clustered_function_spec(typing_extensions.Protocol):
|
|
|
31
31
|
|
|
32
32
|
initialize_clustered_function: __initialize_clustered_function_spec
|
|
33
33
|
|
|
34
|
-
cluster_info:
|
|
34
|
+
cluster_info: ClusterInfo | None
|
|
@@ -21,7 +21,7 @@ import signal
|
|
|
21
21
|
import threading
|
|
22
22
|
import time
|
|
23
23
|
import types
|
|
24
|
-
from typing import TYPE_CHECKING, Any,
|
|
24
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
25
25
|
|
|
26
26
|
from google.protobuf.message import Message
|
|
27
27
|
|
|
@@ -40,8 +40,8 @@ from ._runtime import execution_context
|
|
|
40
40
|
from ._runtime.container_io_manager import (
|
|
41
41
|
ContainerIOManager,
|
|
42
42
|
IOContext,
|
|
43
|
-
UserException,
|
|
44
43
|
)
|
|
44
|
+
from ._runtime.task_lifecycle_manager import UserException
|
|
45
45
|
|
|
46
46
|
if TYPE_CHECKING:
|
|
47
47
|
import modal._runtime.container_io_manager
|
|
@@ -268,7 +268,7 @@ def call_function(
|
|
|
268
268
|
|
|
269
269
|
def get_serialized_user_class_and_function(
|
|
270
270
|
function_def: api_pb2.Function, client: _Client
|
|
271
|
-
) -> tuple[
|
|
271
|
+
) -> tuple[type | None, types.FunctionType | None]:
|
|
272
272
|
if function_def.definition_type == api_pb2.Function.DEFINITION_TYPE_SERIALIZED:
|
|
273
273
|
assert function_def.function_serialized or function_def.class_serialized
|
|
274
274
|
|
|
@@ -310,7 +310,7 @@ def main(container_args: api_pb2.ContainerArguments, client: Client):
|
|
|
310
310
|
ser_usr_cls, ser_fun = get_serialized_user_class_and_function(function_def, _client)
|
|
311
311
|
|
|
312
312
|
# Initialize the function, importing user code.
|
|
313
|
-
with container_io_manager.
|
|
313
|
+
with container_io_manager.get_task_lifecycle_manager().handle_task_lifecycle_exception():
|
|
314
314
|
if container_args.serialized_params:
|
|
315
315
|
param_args, param_kwargs = deserialize_params(container_args.serialized_params, function_def, _client)
|
|
316
316
|
else:
|
|
@@ -390,7 +390,7 @@ def main(container_args: api_pb2.ContainerArguments, client: Client):
|
|
|
390
390
|
"that evaluates differently in the local and remote environments."
|
|
391
391
|
)
|
|
392
392
|
for object_id, obj in zip(dep_object_ids, service.service_deps):
|
|
393
|
-
metadata:
|
|
393
|
+
metadata: Message | None = container_app.object_handle_metadata[object_id]
|
|
394
394
|
obj._hydrate(object_id, _client, metadata)
|
|
395
395
|
|
|
396
396
|
# Initialize clustered functions.
|
|
@@ -401,7 +401,13 @@ def main(container_args: api_pb2.ContainerArguments, client: Client):
|
|
|
401
401
|
function_def._experimental_group_size,
|
|
402
402
|
)
|
|
403
403
|
|
|
404
|
-
with service.execution_context(
|
|
404
|
+
with service.execution_context(
|
|
405
|
+
event_loop=event_loop,
|
|
406
|
+
snapshot=container_io_manager.memory_snapshot,
|
|
407
|
+
container_io_manager=container_io_manager,
|
|
408
|
+
) as finalized_functions:
|
|
409
|
+
# This context managers handles pre/post snapshot lifecycle of the user code,
|
|
410
|
+
# finalized functions, ASGI/WSGI lifespan, and volume commit.
|
|
405
411
|
if function_def.is_server:
|
|
406
412
|
call_server(event_loop)
|
|
407
413
|
else:
|
|
@@ -412,7 +418,7 @@ if __name__ == "__main__":
|
|
|
412
418
|
logger.debug("Container: starting")
|
|
413
419
|
|
|
414
420
|
container_args = api_pb2.ContainerArguments()
|
|
415
|
-
container_arguments_path:
|
|
421
|
+
container_arguments_path: str | None = os.environ.get("MODAL_CONTAINER_ARGUMENTS_PATH")
|
|
416
422
|
if container_arguments_path is None:
|
|
417
423
|
raise RuntimeError("No path to the container arguments file provided!")
|
|
418
424
|
container_args.ParseFromString(open(container_arguments_path, "rb").read())
|
|
@@ -3,7 +3,7 @@ import asyncio
|
|
|
3
3
|
import builtins
|
|
4
4
|
from collections.abc import Iterable, Mapping
|
|
5
5
|
from dataclasses import dataclass
|
|
6
|
-
from typing import Literal
|
|
6
|
+
from typing import Literal
|
|
7
7
|
|
|
8
8
|
from google.protobuf.empty_pb2 import Empty
|
|
9
9
|
from google.protobuf.message import Message
|
|
@@ -35,7 +35,7 @@ class _EnvironmentManager:
|
|
|
35
35
|
name: str, # Name to use for the new Environment
|
|
36
36
|
*,
|
|
37
37
|
restricted: bool = False, # If True, enable RBAC restrictions on the Environment
|
|
38
|
-
client:
|
|
38
|
+
client: _Client | None = None, # Optional client with Modal credentials
|
|
39
39
|
) -> None:
|
|
40
40
|
"""Create a new Environment.
|
|
41
41
|
|
|
@@ -52,7 +52,7 @@ class _EnvironmentManager:
|
|
|
52
52
|
async def list(
|
|
53
53
|
self,
|
|
54
54
|
*,
|
|
55
|
-
client:
|
|
55
|
+
client: _Client | None = None, # Optional client with Modal credentials
|
|
56
56
|
) -> builtins.list["_Environment"]:
|
|
57
57
|
"""Return a list of hydrated Environment objects.
|
|
58
58
|
|
|
@@ -85,7 +85,7 @@ class _EnvironmentManager:
|
|
|
85
85
|
self,
|
|
86
86
|
name: str, # Name of the Environment to delete
|
|
87
87
|
*,
|
|
88
|
-
client:
|
|
88
|
+
client: _Client | None = None, # Optional client with Modal credentials
|
|
89
89
|
) -> None:
|
|
90
90
|
"""Delete a named Environment.
|
|
91
91
|
|
|
@@ -116,9 +116,9 @@ def _role_to_proto(role: str) -> api_pb2.EnvironmentRole.ValueType:
|
|
|
116
116
|
|
|
117
117
|
def _role_from_proto(proto_value: int) -> MemberRole:
|
|
118
118
|
match proto_value:
|
|
119
|
-
case
|
|
119
|
+
case api_pb2.ENVIRONMENT_ROLE_VIEWER:
|
|
120
120
|
return "viewer"
|
|
121
|
-
case
|
|
121
|
+
case api_pb2.ENVIRONMENT_ROLE_CONTRIBUTOR:
|
|
122
122
|
return "contributor"
|
|
123
123
|
case _:
|
|
124
124
|
raise ValueError(f"Unknown environment role: {proto_value}")
|
|
@@ -167,8 +167,8 @@ class _EnvironmentMembersManager:
|
|
|
167
167
|
async def update(
|
|
168
168
|
self,
|
|
169
169
|
*,
|
|
170
|
-
users:
|
|
171
|
-
service_users:
|
|
170
|
+
users: Mapping[str, MemberRole] | None = None,
|
|
171
|
+
service_users: Mapping[str, MemberRole] | None = None,
|
|
172
172
|
) -> None:
|
|
173
173
|
"""Add or modify roles for members of a restricted Environment.
|
|
174
174
|
|
|
@@ -224,8 +224,8 @@ class _EnvironmentMembersManager:
|
|
|
224
224
|
async def remove(
|
|
225
225
|
self,
|
|
226
226
|
*,
|
|
227
|
-
users:
|
|
228
|
-
service_users:
|
|
227
|
+
users: Iterable[str] | None = None,
|
|
228
|
+
service_users: Iterable[str] | None = None,
|
|
229
229
|
) -> None:
|
|
230
230
|
"""Remove members from a restricted Environment.
|
|
231
231
|
|
|
@@ -289,7 +289,7 @@ class _EnvironmentMembersManager:
|
|
|
289
289
|
|
|
290
290
|
|
|
291
291
|
class _Environment(_Object, type_prefix="en"):
|
|
292
|
-
_name:
|
|
292
|
+
_name: str | None = None
|
|
293
293
|
_settings: EnvironmentSettings
|
|
294
294
|
|
|
295
295
|
def __init__(self):
|
|
@@ -300,7 +300,7 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
300
300
|
)
|
|
301
301
|
|
|
302
302
|
@property
|
|
303
|
-
def name(self) ->
|
|
303
|
+
def name(self) -> str | None:
|
|
304
304
|
return self._name
|
|
305
305
|
|
|
306
306
|
@classproperty
|
|
@@ -331,10 +331,10 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
331
331
|
|
|
332
332
|
@staticmethod
|
|
333
333
|
def _get_or_create(
|
|
334
|
-
name: str, repr: str, create_if_missing: bool = False, client:
|
|
334
|
+
name: str, repr: str, create_if_missing: bool = False, client: _Client | None = None
|
|
335
335
|
) -> "_Environment":
|
|
336
336
|
async def _load(
|
|
337
|
-
self: _Environment, resolver: Resolver, load_context: LoadContext, existing_object_id:
|
|
337
|
+
self: _Environment, resolver: Resolver, load_context: LoadContext, existing_object_id: str | None
|
|
338
338
|
):
|
|
339
339
|
request = api_pb2.EnvironmentGetOrCreateRequest(
|
|
340
340
|
deployment_name=name,
|
|
@@ -358,7 +358,7 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
358
358
|
)
|
|
359
359
|
|
|
360
360
|
@staticmethod
|
|
361
|
-
def from_context(*, client:
|
|
361
|
+
def from_context(*, client: _Client | None = None) -> "_Environment":
|
|
362
362
|
"""Look up an Environment object using the current context.
|
|
363
363
|
|
|
364
364
|
This method returns the Environment that is defined by the local configuration
|
|
@@ -381,7 +381,7 @@ class _Environment(_Object, type_prefix="en"):
|
|
|
381
381
|
name: str,
|
|
382
382
|
*,
|
|
383
383
|
create_if_missing: bool = False,
|
|
384
|
-
client:
|
|
384
|
+
client: _Client | None = None,
|
|
385
385
|
) -> "_Environment":
|
|
386
386
|
"""Look up an Environment object using its name."""
|
|
387
387
|
check_environment_name(name)
|
|
@@ -412,7 +412,7 @@ async def _get_environment_cached(name: str, client: _Client) -> _Environment:
|
|
|
412
412
|
# and migrate users to the new object-oriented API, but that should happen gracefully.
|
|
413
413
|
|
|
414
414
|
|
|
415
|
-
async def _delete_environment(name: str, client:
|
|
415
|
+
async def _delete_environment(name: str, client: _Client | None = None):
|
|
416
416
|
if client is None:
|
|
417
417
|
client = await _Client.from_env()
|
|
418
418
|
await client.stub.EnvironmentDelete(api_pb2.EnvironmentDeleteRequest(name=name))
|
|
@@ -421,9 +421,9 @@ async def _delete_environment(name: str, client: Optional[_Client] = None):
|
|
|
421
421
|
async def _update_environment(
|
|
422
422
|
current_name: str,
|
|
423
423
|
*,
|
|
424
|
-
new_name:
|
|
425
|
-
new_web_suffix:
|
|
426
|
-
client:
|
|
424
|
+
new_name: str | None = None,
|
|
425
|
+
new_web_suffix: str | None = None,
|
|
426
|
+
client: _Client | None = None,
|
|
427
427
|
):
|
|
428
428
|
new_name_pb2 = None
|
|
429
429
|
new_web_suffix_pb2 = None
|
|
@@ -444,20 +444,20 @@ async def _update_environment(
|
|
|
444
444
|
await client.stub.EnvironmentUpdate(update_payload)
|
|
445
445
|
|
|
446
446
|
|
|
447
|
-
async def _create_environment(name: str, client:
|
|
447
|
+
async def _create_environment(name: str, client: _Client | None = None):
|
|
448
448
|
if client is None:
|
|
449
449
|
client = await _Client.from_env()
|
|
450
450
|
await client.stub.EnvironmentCreate(api_pb2.EnvironmentCreateRequest(name=name))
|
|
451
451
|
|
|
452
452
|
|
|
453
|
-
async def _list_environments(client:
|
|
453
|
+
async def _list_environments(client: _Client | None = None) -> list[api_pb2.EnvironmentListItem]:
|
|
454
454
|
if client is None:
|
|
455
455
|
client = await _Client.from_env()
|
|
456
456
|
resp = await client.stub.EnvironmentList(Empty())
|
|
457
457
|
return list(resp.items)
|
|
458
458
|
|
|
459
459
|
|
|
460
|
-
def ensure_env(environment_name:
|
|
460
|
+
def ensure_env(environment_name: str | None = None) -> str:
|
|
461
461
|
"""Override config environment with environment from environment_name
|
|
462
462
|
|
|
463
463
|
This is necessary since a cli command that runs Modal code, without explicit
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import dataclasses
|
|
3
3
|
from collections.abc import Collection, Sequence, Sized
|
|
4
4
|
from pathlib import PurePosixPath
|
|
5
|
-
from typing import TYPE_CHECKING, Any
|
|
5
|
+
from typing import TYPE_CHECKING, Any
|
|
6
6
|
|
|
7
7
|
from modal_proto import api_pb2
|
|
8
8
|
|
|
@@ -39,40 +39,40 @@ class _FunctionOptions:
|
|
|
39
39
|
secrets: Collection[_Secret] = ()
|
|
40
40
|
validated_volumes: Sequence[tuple[str, _Volume]] = ()
|
|
41
41
|
cloud_bucket_mounts: Sequence[tuple[str, _CloudBucketMount]] = ()
|
|
42
|
-
resources:
|
|
43
|
-
retry_policy:
|
|
44
|
-
max_containers:
|
|
45
|
-
buffer_containers:
|
|
46
|
-
scaledown_window:
|
|
47
|
-
timeout_secs:
|
|
48
|
-
scheduler_placement:
|
|
49
|
-
cloud:
|
|
50
|
-
max_concurrent_inputs:
|
|
51
|
-
target_concurrent_inputs:
|
|
52
|
-
batch_max_size:
|
|
53
|
-
batch_wait_ms:
|
|
42
|
+
resources: api_pb2.Resources | None = None
|
|
43
|
+
retry_policy: api_pb2.FunctionRetryPolicy | None = None
|
|
44
|
+
max_containers: int | None = None
|
|
45
|
+
buffer_containers: int | None = None
|
|
46
|
+
scaledown_window: int | None = None
|
|
47
|
+
timeout_secs: int | None = None
|
|
48
|
+
scheduler_placement: api_pb2.SchedulerPlacement | None = None
|
|
49
|
+
cloud: str | None = None
|
|
50
|
+
max_concurrent_inputs: int | None = None
|
|
51
|
+
target_concurrent_inputs: int | None = None
|
|
52
|
+
batch_max_size: int | None = None
|
|
53
|
+
batch_wait_ms: int | None = None
|
|
54
54
|
|
|
55
55
|
@classmethod
|
|
56
56
|
def new(
|
|
57
57
|
cls,
|
|
58
58
|
*,
|
|
59
|
-
cpu:
|
|
60
|
-
memory:
|
|
61
|
-
gpu:
|
|
62
|
-
env:
|
|
63
|
-
secrets:
|
|
64
|
-
volumes: dict[
|
|
65
|
-
retries:
|
|
66
|
-
max_containers:
|
|
67
|
-
buffer_containers:
|
|
68
|
-
scaledown_window:
|
|
69
|
-
timeout:
|
|
70
|
-
region:
|
|
71
|
-
cloud:
|
|
72
|
-
max_concurrent_inputs:
|
|
73
|
-
target_concurrent_inputs:
|
|
74
|
-
batch_max_size:
|
|
75
|
-
batch_wait_ms:
|
|
59
|
+
cpu: float | tuple[float, float] | None = None,
|
|
60
|
+
memory: int | tuple[int, int] | None = None,
|
|
61
|
+
gpu: str | None = None,
|
|
62
|
+
env: dict[str, str | None] | None = None,
|
|
63
|
+
secrets: Collection[_Secret] | None = None,
|
|
64
|
+
volumes: dict[str | PurePosixPath, _Volume | _CloudBucketMount] = {},
|
|
65
|
+
retries: int | Retries | None = None,
|
|
66
|
+
max_containers: int | None = None,
|
|
67
|
+
buffer_containers: int | None = None,
|
|
68
|
+
scaledown_window: int | None = None,
|
|
69
|
+
timeout: int | None = None,
|
|
70
|
+
region: str | Sequence[str] | None = None,
|
|
71
|
+
cloud: str | None = None,
|
|
72
|
+
max_concurrent_inputs: int | None = None,
|
|
73
|
+
target_concurrent_inputs: int | None = None,
|
|
74
|
+
batch_max_size: int | None = None,
|
|
75
|
+
batch_wait_ms: int | None = None,
|
|
76
76
|
) -> "_FunctionOptions":
|
|
77
77
|
"""Internal constructor that validates and normalizes public parameters."""
|
|
78
78
|
retry_policy = _parse_retries(retries)
|
|
@@ -89,7 +89,7 @@ class _FunctionOptions:
|
|
|
89
89
|
if env:
|
|
90
90
|
secrets = [*secrets, _Secret.from_dict(env)]
|
|
91
91
|
|
|
92
|
-
scheduler_placement:
|
|
92
|
+
scheduler_placement: api_pb2.SchedulerPlacement | None = None
|
|
93
93
|
if region:
|
|
94
94
|
regions = [region] if isinstance(region, str) else list(region)
|
|
95
95
|
scheduler_placement = api_pb2.SchedulerPlacement(regions=regions)
|
|
@@ -187,8 +187,8 @@ class _FunctionOptions:
|
|
|
187
187
|
|
|
188
188
|
def _make_function_variant(
|
|
189
189
|
base_function: "_Function",
|
|
190
|
-
options:
|
|
191
|
-
parameter_schema:
|
|
190
|
+
options: _FunctionOptions | None,
|
|
191
|
+
parameter_schema: Sequence[api_pb2.ClassParameterSpec] | None,
|
|
192
192
|
args: Sized,
|
|
193
193
|
kwargs: dict[str, Any],
|
|
194
194
|
) -> "_Function":
|
|
@@ -198,7 +198,7 @@ def _make_function_variant(
|
|
|
198
198
|
function_variant: "_Function",
|
|
199
199
|
resolver: "Resolver",
|
|
200
200
|
load_context: "LoadContext",
|
|
201
|
-
existing_object_id:
|
|
201
|
+
existing_object_id: str | None,
|
|
202
202
|
):
|
|
203
203
|
if not base_function.is_hydrated:
|
|
204
204
|
await base_function.hydrate(load_context.client)
|