modal 1.5.2.dev18__tar.gz → 1.5.2.dev19__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.dev18 → modal-1.5.2.dev19}/PKG-INFO +1 -1
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/grpc_utils.py +20 -12
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/name_utils.py +8 -2
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/task_command_router_client.py +2 -2
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/app.py +0 -3
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/app.pyi +0 -2
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/client.pyi +2 -2
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/functions.pyi +6 -6
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2.py +106 -119
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2.pyi +1 -21
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_version/__init__.py +1 -1
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/LICENSE +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/README.md +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/__main__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_billing.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_clustered_functions.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_environments.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_function_variants.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_functions.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_grpc_client.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_image.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_ipython.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_load_context.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_location.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_logs.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_object.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/manager.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/pty.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/rich.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_output/status.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_partial_function.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_resolver.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_resources.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_serialization.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_server.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_traceback.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_tunnel.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_tunnel.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_type_manager.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/logger.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_vendor/version.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_watcher.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/_workspace.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/billing.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/billing.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/README.md +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/builder/base-images.json +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/call_graph.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/_download.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/_help.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/_traceback.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/app.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/billing.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/changelog.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/cluster.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/config.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/container.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/curl.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/dashboard.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/dict.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/endpoint.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/entry_point.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/environment.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/image.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/import_refs.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/launch.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/logo.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/profile.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/queues.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/run.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/secret.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/selector.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/shell.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/skills.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/token.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/utils.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/volume.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cli/workspace.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/client.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cls.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/cls.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/config.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/container_process.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/container_process.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/dict.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/dict.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/environments.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/environments.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/exception.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/flash.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/experimental/ipython.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/file_io.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/file_io.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/functions.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/image.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/image.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/io_streams.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/io_streams.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/mount.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/mount.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/network_file_system.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/network_file_system.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/object.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/object.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/output.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/parallel_map.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/parallel_map.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/partial_function.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/partial_function.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/proxy.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/proxy.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/py.typed +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/queue.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/queue.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/retries.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/runner.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/runner.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/running_app.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox_fs.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/schedule.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/scheduler_placement.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/secret.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/secret.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/server.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/server.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/serving.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/serving.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/snapshot.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/snapshot.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/stream_type.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/token_flow.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/token_flow.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/types.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/volume.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/volume.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/workspace.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal/workspace.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/__init__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_grpc.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/py.typed +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/modal_version/__main__.py +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/pyproject.toml +0 -0
- {modal-1.5.2.dev18 → modal-1.5.2.dev19}/setup.cfg +0 -0
|
@@ -163,7 +163,6 @@ RETRYABLE_GRPC_STATUS_CODES = [
|
|
|
163
163
|
Status.UNKNOWN,
|
|
164
164
|
]
|
|
165
165
|
SERVER_RETRY_WARNING_TIME_INTERVAL = 30.0
|
|
166
|
-
# Initial per-attempt timeout for TCP/TLS handshake in connect_channel.
|
|
167
166
|
DEFAULT_MAX_RETRIES = 3
|
|
168
167
|
|
|
169
168
|
|
|
@@ -308,11 +307,6 @@ def create_channel(
|
|
|
308
307
|
|
|
309
308
|
# With 18 attempts, the max delays between calls is: 0.1 + 0.2 + 0.4 + 0.8 + 1.6 + 3.2 + 5*11 ~ 62
|
|
310
309
|
@retry(n_attempts=18, base_delay=0.1, attempt_timeout=10.0, max_delay=5.0, total_timeout=63.0)
|
|
311
|
-
async def connect_channel(channel: grpclib.client.Channel):
|
|
312
|
-
"""Connect to socket and raise exceptions when there is a connection issue."""
|
|
313
|
-
await channel.__connect__()
|
|
314
|
-
|
|
315
|
-
|
|
316
310
|
async def create_channel_with_fallbacks(
|
|
317
311
|
server_url: str,
|
|
318
312
|
metadata: dict[str, str] = {},
|
|
@@ -323,21 +317,35 @@ async def create_channel_with_fallbacks(
|
|
|
323
317
|
`server_url` may be a single URL or a comma-separated list of URLs. The connection attempts
|
|
324
318
|
are raced against each other and the first one to connect wins, which lets the client fail
|
|
325
319
|
over to a secondary endpoint when the primary is unreachable (e.g. a DNS outage on the
|
|
326
|
-
primary's domain).
|
|
327
|
-
|
|
328
|
-
|
|
320
|
+
primary's domain).
|
|
321
|
+
|
|
322
|
+
Attempts are staggered so earlier URLs (e.g. the primary) get a head start and are preferred
|
|
323
|
+
when reachable: the candidate at index `i` waits up to `i * stagger_delay` seconds before
|
|
324
|
+
starting. That wait is cut short as soon as the previous candidate *fails*, so a fast failure
|
|
325
|
+
falls over to the next URL immediately instead of waiting out the full stagger. Losing attempts
|
|
326
|
+
are cancelled and their channels closed.
|
|
329
327
|
"""
|
|
330
328
|
urls = [url.strip() for url in server_url.split(",")]
|
|
331
329
|
|
|
330
|
+
# Set when a candidate's connection attempt fails, letting the next candidate start immediately
|
|
331
|
+
# instead of waiting out its stagger delay.
|
|
332
|
+
failed = [asyncio.Event() for _ in urls]
|
|
333
|
+
|
|
332
334
|
async def connect(index: int, url: str) -> grpclib.client.Channel:
|
|
333
|
-
|
|
334
|
-
|
|
335
|
+
if index > 0:
|
|
336
|
+
# Stagger the start so earlier URLs are preferred, but start early if the previous
|
|
337
|
+
# candidate has already failed.
|
|
338
|
+
try:
|
|
339
|
+
await asyncio.wait_for(failed[index - 1].wait(), timeout=index * stagger_delay)
|
|
340
|
+
except asyncio.TimeoutError:
|
|
341
|
+
pass
|
|
335
342
|
channel = create_channel(url, metadata)
|
|
336
343
|
try:
|
|
337
|
-
await
|
|
344
|
+
await channel.__connect__()
|
|
338
345
|
except BaseException:
|
|
339
346
|
# Close the channel of a losing/cancelled attempt so its socket doesn't leak.
|
|
340
347
|
channel.close()
|
|
348
|
+
failed[index].set()
|
|
341
349
|
raise
|
|
342
350
|
return channel
|
|
343
351
|
|
|
@@ -29,7 +29,13 @@ def is_valid_object_name(name: str) -> bool:
|
|
|
29
29
|
|
|
30
30
|
def is_valid_environment_name(name: str) -> bool:
|
|
31
31
|
# first char is alnum, the rest allows other chars
|
|
32
|
-
|
|
32
|
+
# The "en-" prefix is reserved for environment IDs, so that references
|
|
33
|
+
# to environments can be resolved by either name or ID unambiguously.
|
|
34
|
+
return (
|
|
35
|
+
len(name) <= 64
|
|
36
|
+
and re.match(r"^[a-zA-Z0-9][a-zA-Z0-9-_.]+$", name) is not None
|
|
37
|
+
and not name.lower().startswith("en-")
|
|
38
|
+
)
|
|
33
39
|
|
|
34
40
|
|
|
35
41
|
def is_valid_tag(tag: str, max_length: int = 50) -> bool:
|
|
@@ -66,7 +72,7 @@ def check_environment_name(name: str) -> None:
|
|
|
66
72
|
f"Invalid Environment name: '{name}'."
|
|
67
73
|
"\n\nEnvironment names can only start with alphanumeric characters,"
|
|
68
74
|
" may contain only alphanumeric characters, dashes, periods, and underscores,"
|
|
69
|
-
"
|
|
75
|
+
" must be shorter than 64 characters, and cannot start with 'en-'."
|
|
70
76
|
)
|
|
71
77
|
if not is_valid_environment_name(name):
|
|
72
78
|
raise InvalidError(message)
|
|
@@ -32,8 +32,8 @@ from .grpc_utils import RETRYABLE_GRPC_STATUS_CODES
|
|
|
32
32
|
async def _connect_channel(channel: grpclib.client.Channel):
|
|
33
33
|
"""Connect to the command router channel.
|
|
34
34
|
|
|
35
|
-
Uses a longer retry budget than grpc_utils.
|
|
36
|
-
may take a long time to start on the worker after scheduling.
|
|
35
|
+
Uses a longer retry budget than grpc_utils.create_channel_with_fallbacks. In rare cases the
|
|
36
|
+
sandbox may take a long time to start on the worker after scheduling.
|
|
37
37
|
|
|
38
38
|
Retries with exponential backoff (1, 2, 4, 8, 10, 10, ...) capped at 10s per delay.
|
|
39
39
|
Total sleep between attempts: 1 + 2 + 4 + 8 + 10*29 = 305s (~5 min).
|
|
@@ -728,7 +728,6 @@ class _App:
|
|
|
728
728
|
"""
|
|
729
729
|
...
|
|
730
730
|
|
|
731
|
-
def _experimental_server(self, **kwargs): ...
|
|
732
731
|
def server(
|
|
733
732
|
self,
|
|
734
733
|
_warn_parentheses_missing=None,
|
|
@@ -1733,7 +1732,6 @@ class App:
|
|
|
1733
1732
|
"""
|
|
1734
1733
|
...
|
|
1735
1734
|
|
|
1736
|
-
def _experimental_server(self, **kwargs): ...
|
|
1737
1735
|
def server(
|
|
1738
1736
|
self,
|
|
1739
1737
|
_warn_parentheses_missing=None,
|
|
@@ -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.2.
|
|
38
|
+
version: str = "1.5.2.dev19",
|
|
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.2.
|
|
208
|
+
version: str = "1.5.2.dev19",
|
|
209
209
|
):
|
|
210
210
|
"""mdmd:hidden
|
|
211
211
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -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.
|