modal 1.5.4.dev16__tar.gz → 1.5.4.dev17__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.4.dev16 → modal-1.5.4.dev17}/PKG-INFO +1 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/container.py +52 -21
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/run.py +16 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/workspace.py +23 -14
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/client.pyi +2 -2
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/functions.pyi +6 -6
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/runner.py +7 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/runner.pyi +4 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/api_pb2.py +1289 -1289
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/api_pb2.pyi +23 -5
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_version/__init__.py +1 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/LICENSE +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/README.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/__main__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_billing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_clustered_functions.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_environments.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_function_variants.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_functions.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_grpc_client.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_image.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_ipython.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_load_context.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_location.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_logs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_logs_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_logs_manager.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_object.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_output/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_output/manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_output/pty.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_output/rich.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_output/status.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_partial_function.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_resolver.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_resources.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_serialization.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_server.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_supports_logs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_traceback.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_tunnel.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_tunnel.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_type_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/logger.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_vendor/version.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_watcher.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/_workspace.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/app.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/app.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/billing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/billing.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/README.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/builder/base-images.json +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/call_graph.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/_download.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/_help.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/_traceback.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/app.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/billing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/changelog.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/cluster.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/config.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/curl.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/dashboard.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/dict.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/endpoint.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/entry_point.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/environment.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/image.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/import_refs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/launch.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/logo.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/profile.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/queues.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/secret.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/selector.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/shell.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/skills.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/token.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cli/volume.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/client.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cls.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/cls.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/config.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/container_process.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/container_process.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/dict.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/dict.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/environments.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/environments.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/exception.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/experimental/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/experimental/flash.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/experimental/ipython.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/file_io.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/file_io.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/functions.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/image.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/image.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/io_streams.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/io_streams.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/mount.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/mount.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/network_file_system.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/network_file_system.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/object.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/object.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/output.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/parallel_map.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/parallel_map.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/partial_function.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/partial_function.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/proxy.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/proxy.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/py.typed +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/queue.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/queue.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/retries.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/running_app.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/sandbox.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/sandbox.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/sandbox_fs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/schedule.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/scheduler_placement.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/secret.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/secret.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/server.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/server.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/serving.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/serving.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/snapshot.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/snapshot.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/stream_type.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/token_flow.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/token_flow.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/types.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/volume.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/volume.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/workspace.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal/workspace.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/api_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/py.typed +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/modal_version/__main__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/pyproject.toml +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev17}/setup.cfg +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# Copyright Modal Labs 2022
|
|
2
|
+
import asyncio
|
|
3
|
+
import dataclasses
|
|
2
4
|
import warnings
|
|
3
5
|
from datetime import datetime, timezone
|
|
4
6
|
|
|
@@ -24,14 +26,16 @@ from modal.cli.utils import (
|
|
|
24
26
|
yes_option,
|
|
25
27
|
)
|
|
26
28
|
from modal.client import _Client
|
|
27
|
-
from modal.exception import InvalidError
|
|
28
|
-
from modal.sandbox import _container_exec
|
|
29
|
+
from modal.exception import ConflictError, InvalidError
|
|
30
|
+
from modal.sandbox import SandboxVersion, _container_exec, _get_sandbox_version, _Sandbox
|
|
29
31
|
from modal_proto import api_pb2
|
|
30
32
|
|
|
31
33
|
from ._help import ModalGroup
|
|
32
34
|
|
|
33
35
|
container_cli = ModalGroup(name="container", help="Manage and connect to running containers.")
|
|
34
36
|
|
|
37
|
+
_SANDBOX_TASK_ID_WAIT_SECS = 55.0
|
|
38
|
+
|
|
35
39
|
|
|
36
40
|
@container_cli.command("list")
|
|
37
41
|
@click.option("--app-id", default="", help="List containers running for a specific App.")
|
|
@@ -149,6 +153,13 @@ async def logs(
|
|
|
149
153
|
else:
|
|
150
154
|
raise InvalidError(f"Invalid container ID: {container_id}")
|
|
151
155
|
|
|
156
|
+
is_v2_sandbox = sandbox_id is not None and _get_sandbox_version(sandbox_id) == SandboxVersion.V2
|
|
157
|
+
|
|
158
|
+
if follow and is_v2_sandbox:
|
|
159
|
+
raise UsageError(
|
|
160
|
+
"Following logs (-f/--follow) is not supported for this Sandbox. Re-run without -f to fetch its logs."
|
|
161
|
+
)
|
|
162
|
+
|
|
152
163
|
if follow and (since or until or tail):
|
|
153
164
|
raise UsageError("--follow cannot be combined with --since, --until, or --tail.")
|
|
154
165
|
|
|
@@ -190,32 +201,52 @@ async def logs(
|
|
|
190
201
|
# Resolve the app_id for the container.
|
|
191
202
|
client = await _Client.from_env()
|
|
192
203
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
204
|
+
enqueued_dt: datetime | None = None
|
|
205
|
+
finished_dt: datetime | None = None
|
|
206
|
+
|
|
207
|
+
if is_v2_sandbox:
|
|
208
|
+
assert sandbox_id is not None
|
|
209
|
+
sandbox = await _Sandbox.from_id(sandbox_id, client)
|
|
210
|
+
app_id = sandbox._app_id or ""
|
|
211
|
+
try:
|
|
212
|
+
task_id = await asyncio.wait_for(
|
|
213
|
+
sandbox._get_task_id(raise_if_task_complete=True),
|
|
214
|
+
timeout=_SANDBOX_TASK_ID_WAIT_SECS,
|
|
215
|
+
)
|
|
216
|
+
except (asyncio.TimeoutError, ConflictError):
|
|
217
|
+
# No container ran (still queued, or finished before starting), so there are no
|
|
218
|
+
# logs. Returning empty is consistent with other no-logs-yet cases (e.g. logs not
|
|
219
|
+
# yet flushed to ClickHouse), so we don't warn.
|
|
220
|
+
return
|
|
221
|
+
log_filters = dataclasses.replace(log_filters, sandbox_id="", task_id=task_id)
|
|
222
|
+
else:
|
|
223
|
+
if sandbox_id:
|
|
224
|
+
sb_resp = await client.stub.SandboxGetTaskId(api_pb2.SandboxGetTaskIdRequest(sandbox_id=sandbox_id))
|
|
225
|
+
task_id = sb_resp.task_id
|
|
196
226
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
227
|
+
assert task_id
|
|
228
|
+
task_info_resp = await client.stub.TaskGetInfo(api_pb2.TaskGetInfoRequest(task_id=task_id))
|
|
229
|
+
app_id = task_info_resp.app_id
|
|
200
230
|
|
|
201
|
-
|
|
202
|
-
|
|
231
|
+
if not task_info_resp.info.enqueued_at:
|
|
232
|
+
return
|
|
203
233
|
|
|
204
|
-
|
|
234
|
+
enqueued_dt = datetime.fromtimestamp(task_info_resp.info.enqueued_at, timezone.utc)
|
|
235
|
+
if task_info_resp.info.finished_at:
|
|
236
|
+
finished_dt = datetime.fromtimestamp(task_info_resp.info.finished_at, timezone.utc)
|
|
205
237
|
|
|
206
238
|
now = datetime.now(timezone.utc)
|
|
239
|
+
# V2 Sandboxes don't expose task enqueue/finish times to the client, so fall back to the
|
|
240
|
+
# widest single-query window. This can miss logs older than _MAX_FETCH_RANGE for workspaces
|
|
241
|
+
# whose custom log retention window exceeds it.
|
|
242
|
+
default_since_dt = enqueued_dt or (now - _MAX_FETCH_RANGE)
|
|
243
|
+
default_until_dt = finished_dt or now
|
|
244
|
+
|
|
207
245
|
if all_logs:
|
|
208
|
-
since_dt =
|
|
209
|
-
|
|
210
|
-
until_dt = datetime.fromtimestamp(task_info_resp.info.finished_at, timezone.utc)
|
|
211
|
-
else:
|
|
212
|
-
until_dt = now
|
|
246
|
+
since_dt = default_since_dt
|
|
247
|
+
until_dt = default_until_dt
|
|
213
248
|
else:
|
|
214
|
-
since_dt = _parse_time_arg(since, default=
|
|
215
|
-
if task_info_resp.info.finished_at:
|
|
216
|
-
default_until_dt = datetime.fromtimestamp(task_info_resp.info.finished_at, timezone.utc)
|
|
217
|
-
else:
|
|
218
|
-
default_until_dt = now
|
|
249
|
+
since_dt = _parse_time_arg(since, default=default_since_dt)
|
|
219
250
|
until_dt = _parse_time_arg(until, default=default_until_dt)
|
|
220
251
|
|
|
221
252
|
if since is not None and until is not None and since_dt >= until_dt:
|
|
@@ -539,6 +539,13 @@ def run(
|
|
|
539
539
|
help="Deployment strategy",
|
|
540
540
|
type=click.Choice(get_args(DEPLOYMENT_STRATEGY_TYPE)),
|
|
541
541
|
)
|
|
542
|
+
@click.option(
|
|
543
|
+
"--staged",
|
|
544
|
+
"staged",
|
|
545
|
+
is_flag=True,
|
|
546
|
+
default=False,
|
|
547
|
+
hidden=True,
|
|
548
|
+
)
|
|
542
549
|
def deploy(
|
|
543
550
|
app_ref: str,
|
|
544
551
|
name: str = "",
|
|
@@ -548,6 +555,7 @@ def deploy(
|
|
|
548
555
|
use_module_mode: bool = False,
|
|
549
556
|
timestamps: bool = False,
|
|
550
557
|
strategy: str = "rolling",
|
|
558
|
+
staged: bool = False,
|
|
551
559
|
):
|
|
552
560
|
"""Deploy a Modal application.
|
|
553
561
|
|
|
@@ -578,7 +586,14 @@ def deploy(
|
|
|
578
586
|
"modal deploy ... --name=some-name"
|
|
579
587
|
)
|
|
580
588
|
|
|
581
|
-
res = deploy_app(
|
|
589
|
+
res = deploy_app(
|
|
590
|
+
app,
|
|
591
|
+
name=name,
|
|
592
|
+
environment_name=env or "",
|
|
593
|
+
tag=tag,
|
|
594
|
+
deployment_strategy=strategy,
|
|
595
|
+
staged=staged,
|
|
596
|
+
)
|
|
582
597
|
|
|
583
598
|
if stream_logs:
|
|
584
599
|
# stream_app_logs is defined in cli/utils.py, which does not get type stubs
|
|
@@ -3,6 +3,8 @@ import json as json_mod
|
|
|
3
3
|
|
|
4
4
|
import click
|
|
5
5
|
import rich
|
|
6
|
+
import rich.box
|
|
7
|
+
import rich.table
|
|
6
8
|
|
|
7
9
|
from modal._utils.time_utils import timestamp_to_localized_str
|
|
8
10
|
from modal.cli.utils import confirm_or_suggest_yes, display_table, yes_option
|
|
@@ -46,15 +48,26 @@ def members_list(json: bool = False):
|
|
|
46
48
|
|
|
47
49
|
PROXY_TOKENS_HELP_TEXT = """Manage the proxy tokens of the current Workspace.
|
|
48
50
|
|
|
49
|
-
Proxy tokens provide authentication to
|
|
50
|
-
They are passed as request headers (`Modal-Key` and `Modal-Secret`). On Modal Servers and
|
|
51
|
-
Endpoints they can also be joined into a single `Authorization: Bearer
|
|
52
|
-
wk-<id>.ws-<secret>` header, which OpenAI-compatible clients accept as an API key. See
|
|
53
|
-
https://modal.com/docs/guide/webhook-proxy-auth for more information.
|
|
51
|
+
Proxy tokens provide authentication to Modal Endpoints, Servers, and Web Functions.
|
|
54
52
|
|
|
55
53
|
Proxy tokens and secrets have `wk-` and `ws-` prefixes, respectively. They cannot be
|
|
56
54
|
interchanged with API tokens (which use `ak-` and `as-` prefixes).
|
|
57
55
|
|
|
56
|
+
Proxy tokens are passed as request headers, either as a key / secret pair:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
Modal-Key: wk-123
|
|
60
|
+
Modal-Secret: ws-456
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Or as a single Bearer token:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
Authorization: Bearer wk-123.ws-456
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
See https://modal.com/docs/guide/webhook-proxy-auth for more information.
|
|
70
|
+
|
|
58
71
|
On workspaces with RBAC enabled, tokens are scoped to specific environments;
|
|
59
72
|
use the `allow` and `revoke` commands to manage environment associations.
|
|
60
73
|
"""
|
|
@@ -85,13 +98,10 @@ def proxy_tokens_create(*, json: bool = False):
|
|
|
85
98
|
)
|
|
86
99
|
)
|
|
87
100
|
else:
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
"Or as a single header (Endpoints and Servers only):\n"
|
|
93
|
-
f"Authorization: {bearer}"
|
|
94
|
-
)
|
|
101
|
+
table = rich.table.Table(show_header=False, box=rich.box.HORIZONTALS, show_lines=True)
|
|
102
|
+
table.add_row(f"Modal-Key: {token.token_id}\nModal-Secret: {token.token_secret}")
|
|
103
|
+
table.add_row(f"Authorization: {bearer}")
|
|
104
|
+
output_manager.print(table)
|
|
95
105
|
|
|
96
106
|
|
|
97
107
|
@proxy_tokens_cli.command("list", help="List the proxy tokens of the current Workspace.")
|
|
@@ -138,8 +148,7 @@ def proxy_tokens_revoke(token_id: str, environment_name: str):
|
|
|
138
148
|
def proxy_tokens_delete(token_id: str, yes: bool = False):
|
|
139
149
|
if not yes:
|
|
140
150
|
message = (
|
|
141
|
-
f"Are you sure you want to delete proxy token {token_id!r}? "
|
|
142
|
-
"Any web endpoints relying on it will no longer accept it."
|
|
151
|
+
f"Are you sure you want to delete proxy token {token_id!r}? Requests using this token will be rejected."
|
|
143
152
|
)
|
|
144
153
|
confirm_or_suggest_yes(message)
|
|
145
154
|
Workspace.from_context().proxy_tokens.delete(token_id)
|
|
@@ -37,7 +37,7 @@ class _Client:
|
|
|
37
37
|
server_url: str,
|
|
38
38
|
client_type: int,
|
|
39
39
|
credentials: typing.Optional[tuple[str, str]],
|
|
40
|
-
version: str = "1.5.4.
|
|
40
|
+
version: str = "1.5.4.dev17",
|
|
41
41
|
):
|
|
42
42
|
"""mdmd:hidden
|
|
43
43
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -207,7 +207,7 @@ class Client:
|
|
|
207
207
|
server_url: str,
|
|
208
208
|
client_type: int,
|
|
209
209
|
credentials: typing.Optional[tuple[str, str]],
|
|
210
|
-
version: str = "1.5.4.
|
|
210
|
+
version: str = "1.5.4.dev17",
|
|
211
211
|
):
|
|
212
212
|
"""mdmd:hidden
|
|
213
213
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -546,7 +546,7 @@ class Function(
|
|
|
546
546
|
|
|
547
547
|
_call_generator: ___call_generator_spec
|
|
548
548
|
|
|
549
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
549
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
550
550
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
551
551
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
552
552
|
|
|
@@ -571,7 +571,7 @@ class Function(
|
|
|
571
571
|
"""
|
|
572
572
|
...
|
|
573
573
|
|
|
574
|
-
remote: __remote_spec[modal._functions.
|
|
574
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
|
|
575
575
|
|
|
576
576
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
577
577
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -621,7 +621,7 @@ class Function(
|
|
|
621
621
|
"""
|
|
622
622
|
...
|
|
623
623
|
|
|
624
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
624
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
625
625
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
626
626
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
627
627
|
|
|
@@ -654,7 +654,7 @@ class Function(
|
|
|
654
654
|
"""
|
|
655
655
|
...
|
|
656
656
|
|
|
657
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
657
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
658
658
|
|
|
659
659
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
660
660
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -662,7 +662,7 @@ class Function(
|
|
|
662
662
|
|
|
663
663
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
664
664
|
|
|
665
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
665
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
666
666
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
667
667
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
668
668
|
|
|
@@ -695,7 +695,7 @@ class Function(
|
|
|
695
695
|
"""
|
|
696
696
|
...
|
|
697
697
|
|
|
698
|
-
spawn: __spawn_spec[modal._functions.
|
|
698
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
699
699
|
|
|
700
700
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
|
701
701
|
"""Return the inner Python object wrapped by this Modal Function.
|
|
@@ -280,10 +280,14 @@ async def _publish_app(
|
|
|
280
280
|
commit_info: api_pb2.CommitInfo | None = None, # Git commit information
|
|
281
281
|
deployment_strategy: str = "rolling",
|
|
282
282
|
environment_name: str | None = None,
|
|
283
|
+
staged: bool = False,
|
|
283
284
|
) -> tuple[str, list[api_pb2.Warning], float]:
|
|
284
285
|
"""Wrapper for AppPublish RPC."""
|
|
285
286
|
deployment_strategy = _validate_deployment_strategy(deployment_strategy)
|
|
286
287
|
|
|
288
|
+
if staged and deployment_strategy == "recreate":
|
|
289
|
+
raise InvalidError("Cannot use `recreate` deployment strategy with a staged deployment")
|
|
290
|
+
|
|
287
291
|
functions = app_local_state.functions
|
|
288
292
|
definition_ids = {obj.object_id: obj._get_metadata().definition_id for obj in functions.values()} # type: ignore
|
|
289
293
|
|
|
@@ -297,6 +301,7 @@ async def _publish_app(
|
|
|
297
301
|
function_ids=running_app.function_ids,
|
|
298
302
|
class_ids=running_app.class_ids,
|
|
299
303
|
definition_ids=definition_ids,
|
|
304
|
+
staged=staged,
|
|
300
305
|
)
|
|
301
306
|
response = await client.stub.AppPublish(request)
|
|
302
307
|
print_server_warnings(response.server_warnings)
|
|
@@ -590,6 +595,7 @@ async def _deploy_app(
|
|
|
590
595
|
tag: str = "",
|
|
591
596
|
deployment_strategy: str = "rolling",
|
|
592
597
|
client: _Client | None = None,
|
|
598
|
+
staged: bool = False,
|
|
593
599
|
) -> DeployResult:
|
|
594
600
|
"""Internal function for deploying an App.
|
|
595
601
|
|
|
@@ -665,6 +671,7 @@ async def _deploy_app(
|
|
|
665
671
|
commit_info=commit_info,
|
|
666
672
|
environment_name=root_load_context.environment_name,
|
|
667
673
|
deployment_strategy=deployment_strategy,
|
|
674
|
+
staged=staged,
|
|
668
675
|
)
|
|
669
676
|
except Exception as e:
|
|
670
677
|
# Note that AppClientDisconnect only stops the app if it's still initializing, and is a no-op otherwise.
|
|
@@ -53,6 +53,7 @@ async def _publish_app(
|
|
|
53
53
|
commit_info: typing.Optional[modal_proto.api_pb2.CommitInfo] = None,
|
|
54
54
|
deployment_strategy: str = "rolling",
|
|
55
55
|
environment_name: typing.Optional[str] = None,
|
|
56
|
+
staged: bool = False,
|
|
56
57
|
) -> tuple[str, list[modal_proto.api_pb2.Warning], float]:
|
|
57
58
|
"""Wrapper for AppPublish RPC."""
|
|
58
59
|
...
|
|
@@ -131,6 +132,7 @@ async def _deploy_app(
|
|
|
131
132
|
tag: str = "",
|
|
132
133
|
deployment_strategy: str = "rolling",
|
|
133
134
|
client: typing.Optional[modal.client._Client] = None,
|
|
135
|
+
staged: bool = False,
|
|
134
136
|
) -> DeployResult:
|
|
135
137
|
"""Internal function for deploying an App.
|
|
136
138
|
|
|
@@ -238,6 +240,7 @@ class __deploy_app_spec(typing_extensions.Protocol):
|
|
|
238
240
|
tag: str = "",
|
|
239
241
|
deployment_strategy: str = "rolling",
|
|
240
242
|
client: typing.Optional[modal.client.Client] = None,
|
|
243
|
+
staged: bool = False,
|
|
241
244
|
) -> DeployResult:
|
|
242
245
|
"""Internal function for deploying an App.
|
|
243
246
|
|
|
@@ -255,6 +258,7 @@ class __deploy_app_spec(typing_extensions.Protocol):
|
|
|
255
258
|
tag: str = "",
|
|
256
259
|
deployment_strategy: str = "rolling",
|
|
257
260
|
client: typing.Optional[modal.client.Client] = None,
|
|
261
|
+
staged: bool = False,
|
|
258
262
|
) -> DeployResult:
|
|
259
263
|
"""Internal function for deploying an App.
|
|
260
264
|
|