modal 1.6.2.dev11__tar.gz → 1.6.2.dev12__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.6.2.dev11 → modal-1.6.2.dev12}/PKG-INFO +1 -1
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/app.py +1 -1
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/app.pyi +2 -2
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/function.py +38 -13
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/import_refs.py +57 -6
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/run.py +4 -1
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/server.py +29 -11
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/shell.py +4 -1
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/client.pyi +2 -2
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/config.py +4 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/functions.pyi +6 -6
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_version/__init__.py +1 -1
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/LICENSE +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/README.md +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/__main__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_billing.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_cluster.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_cluster.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_container_entrypoint.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_environments.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_function_variants.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_functions.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_grpc_client.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_image.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_ipython.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_load_context.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_location.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_logs.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_logs_manager.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_logs_manager.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_metrics.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_metrics.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_object.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_outbound_policy.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_outbound_policy.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_output/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_output/manager.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_output/pty.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_output/rich.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_output/status.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_partial_function.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_resolver.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_resources.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/asgi.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/execution_context.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/telemetry.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_serialization.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_server.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_server.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_supports_logs.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_traceback.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_tunnel.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_tunnel.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_type_manager.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/app_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/async_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/blob_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/browser_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/curl_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/deprecation.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/display_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/docker_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/function_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/git_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/hash_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/http_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/idle_countdown.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/logger.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/mount_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/name_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/package_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/proxy_support.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/shell_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_utils/time_utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_vendor/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_vendor/tblib.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_vendor/version.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_watcher.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/_workspace.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/billing.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/billing.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/2023.12.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/2024.04.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/2024.10.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/2025.06.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/README.md +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/builder/base-images.json +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/call_graph.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/_download.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/_help.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/_logs.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/_stats.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/_traceback.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/app.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/billing.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/changelog.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/config.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/container.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/curl.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/dashboard.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/dict.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/endpoint.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/entry_point.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/environment.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/image.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/logo.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/network_file_system.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/profile.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/queues.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/secret.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/selector.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/skills.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/token.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/utils.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/volume.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cli/workspace.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/client.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cls.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cls.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cluster.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/cluster.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/container_process.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/container_process.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/dict.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/dict.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/environments.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/environments.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/exception.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/_flash_container_entry.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/flash.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/flash.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/flash_server.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/flash_server.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/experimental/ipython.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/file_pattern_matcher.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/functions.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/image.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/image.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/io_streams.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/io_streams.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/mount.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/mount.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/network_file_system.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/network_file_system.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/object.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/object.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/output.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/parallel_map.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/parallel_map.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/partial_function.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/partial_function.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/proxy.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/proxy.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/py.typed +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/queue.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/queue.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/retries.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/runner.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/runner.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/running_app.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/_common.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/_filesystem.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/_sandbox.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/_sidecar.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/_snapshot.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/_task_command_router_client.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/sandbox.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/sandbox/sandbox.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/schedule.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/scheduler_placement.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/secret.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/secret.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/server.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/server.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/serving.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/serving.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/stream_type.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/token_flow.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/token_flow.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/types.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/volume.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/volume.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/workspace.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal/workspace.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal.egg-info/requires.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal.egg-info/top_level.txt +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/mdmd/types.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_docs/reference_intro.md +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/__init__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/api_grpc.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/api_pb2.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/py.typed +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/modal_version/__main__.py +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/pyproject.toml +0 -0
- {modal-1.6.2.dev11 → modal-1.6.2.dev12}/setup.cfg +0 -0
|
@@ -1358,7 +1358,7 @@ class _App:
|
|
|
1358
1358
|
fractional, e.g. 1.5 to target three concurrent requests per two containers.
|
|
1359
1359
|
max_concurrency:
|
|
1360
1360
|
Maximum number of concurrent requests per container. Requests above this limit
|
|
1361
|
-
receive a
|
|
1361
|
+
receive a 429 response. If set to 0 or unset, request concurrency is unlimited.
|
|
1362
1362
|
min_containers: Minimum number of containers to keep running regardless of demand.
|
|
1363
1363
|
max_containers: Limit on the number of containers that can be concurrently running.
|
|
1364
1364
|
buffer_containers: Extra containers to scale up beyond current demand.
|
|
@@ -799,7 +799,7 @@ class _App:
|
|
|
799
799
|
fractional, e.g. 1.5 to target three concurrent requests per two containers.
|
|
800
800
|
max_concurrency:
|
|
801
801
|
Maximum number of concurrent requests per container. Requests above this limit
|
|
802
|
-
receive a
|
|
802
|
+
receive a 429 response. If set to 0 or unset, request concurrency is unlimited.
|
|
803
803
|
min_containers: Minimum number of containers to keep running regardless of demand.
|
|
804
804
|
max_containers: Limit on the number of containers that can be concurrently running.
|
|
805
805
|
buffer_containers: Extra containers to scale up beyond current demand.
|
|
@@ -1837,7 +1837,7 @@ class App:
|
|
|
1837
1837
|
fractional, e.g. 1.5 to target three concurrent requests per two containers.
|
|
1838
1838
|
max_concurrency:
|
|
1839
1839
|
Maximum number of concurrent requests per container. Requests above this limit
|
|
1840
|
-
receive a
|
|
1840
|
+
receive a 429 response. If set to 0 or unset, request concurrency is unlimited.
|
|
1841
1841
|
min_containers: Minimum number of containers to keep running regardless of demand.
|
|
1842
1842
|
max_containers: Limit on the number of containers that can be concurrently running.
|
|
1843
1843
|
buffer_containers: Extra containers to scale up beyond current demand.
|
|
@@ -7,7 +7,8 @@ from typing import Any, AsyncGenerator, Sequence, cast
|
|
|
7
7
|
|
|
8
8
|
import click
|
|
9
9
|
from click import UsageError
|
|
10
|
-
from rich.box import SIMPLE
|
|
10
|
+
from rich.box import SIMPLE, SIMPLE_HEAD
|
|
11
|
+
from rich.style import Style
|
|
11
12
|
from rich.table import Column, Table
|
|
12
13
|
from rich.text import Text
|
|
13
14
|
|
|
@@ -212,18 +213,20 @@ async def info(
|
|
|
212
213
|
enabled = "Enabled"
|
|
213
214
|
disabled = "Disabled"
|
|
214
215
|
|
|
215
|
-
rows: list[str | Text | tuple[str | Text, str | Text]] = []
|
|
216
|
+
rows: list[str | Text | tuple[str | Text, str | Text] | None] = []
|
|
216
217
|
|
|
217
218
|
if function_proto.is_class:
|
|
218
|
-
rows.append(("Cls Name:", function_proto.function_name))
|
|
219
|
+
rows.append((Text("Cls Name:", style="bold"), function_proto.function_name))
|
|
219
220
|
else:
|
|
220
|
-
rows.append(("Function Name:", function_proto.function_name))
|
|
221
|
+
rows.append((Text("Function Name:", style="bold"), function_proto.function_name))
|
|
221
222
|
|
|
222
|
-
rows.append(
|
|
223
|
-
rows.append(("
|
|
224
|
-
rows.append(("
|
|
223
|
+
rows.append(None)
|
|
224
|
+
rows.append((Text("Object ID:", style="bold"), f.object_id))
|
|
225
|
+
rows.append((Text("App ID:", style="bold"), handle_metadata.app_id))
|
|
226
|
+
rows.append((Text("Image ID:", style="bold"), str(info.image_info.image_id)))
|
|
225
227
|
|
|
226
228
|
# --- Resources ---
|
|
229
|
+
rows.append(None)
|
|
227
230
|
rows.append("Resources:")
|
|
228
231
|
rows.append(
|
|
229
232
|
(
|
|
@@ -261,6 +264,7 @@ async def info(
|
|
|
261
264
|
)
|
|
262
265
|
|
|
263
266
|
# --- Autoscaling ---
|
|
267
|
+
rows.append(None)
|
|
264
268
|
rows.append("Autoscaling:")
|
|
265
269
|
rows.append(
|
|
266
270
|
(
|
|
@@ -289,6 +293,7 @@ async def info(
|
|
|
289
293
|
)
|
|
290
294
|
)
|
|
291
295
|
|
|
296
|
+
rows.append(None)
|
|
292
297
|
rows.append("Execution:")
|
|
293
298
|
if info.startup_timeout:
|
|
294
299
|
rows.append((" Startup Timeout:", f"{info.startup_timeout} seconds"))
|
|
@@ -297,6 +302,7 @@ async def info(
|
|
|
297
302
|
rows.append((" Max Retries:", not_configured if info.max_retries is None else str(info.max_retries)))
|
|
298
303
|
|
|
299
304
|
if info.concurrency_info:
|
|
305
|
+
rows.append(None)
|
|
300
306
|
rows.append("Concurrency:")
|
|
301
307
|
rows.append((" Max Inputs:", str(info.concurrency_info.max_inputs)))
|
|
302
308
|
rows.append(
|
|
@@ -309,11 +315,13 @@ async def info(
|
|
|
309
315
|
)
|
|
310
316
|
|
|
311
317
|
if info.batching_info:
|
|
318
|
+
rows.append(None)
|
|
312
319
|
rows.append("Batching:")
|
|
313
320
|
rows.append((" Max Batch Size:", str(info.batching_info.max_batch_size)))
|
|
314
321
|
rows.append((" Wait Time:", f"{info.batching_info.wait_ms} milliseconds"))
|
|
315
322
|
|
|
316
323
|
# --- Scheduling ---
|
|
324
|
+
rows.append(None)
|
|
317
325
|
rows.append("Scheduling:")
|
|
318
326
|
rows.append((" Compute Region(s):", not_configured if not info.regions else " | ".join(info.regions)))
|
|
319
327
|
rows.append((" Nonpreemptible Capacity:", not_configured if not info.nonpreemptible else enabled))
|
|
@@ -322,6 +330,7 @@ async def info(
|
|
|
322
330
|
rows.append((" Routing Region:", not_configured if not info.routing_region else info.routing_region))
|
|
323
331
|
|
|
324
332
|
if info.cluster_info:
|
|
333
|
+
rows.append(None)
|
|
325
334
|
rows.append("Clustering:")
|
|
326
335
|
rows.append((" Cluster Size:", str(info.cluster_info.size)))
|
|
327
336
|
rows.append((" RDMA:", enabled if info.cluster_info.rdma else disabled))
|
|
@@ -329,8 +338,10 @@ async def info(
|
|
|
329
338
|
rows.append((" Fabric Size:", str(info.cluster_info.fabric_size)))
|
|
330
339
|
|
|
331
340
|
if info.schedule is not None:
|
|
341
|
+
rows.append(None)
|
|
332
342
|
rows.append(("Schedule:", info.schedule))
|
|
333
343
|
|
|
344
|
+
rows.append(None)
|
|
334
345
|
rows.append("Security:")
|
|
335
346
|
rows.append((" Outbound Networking:", disabled if info.block_network else enabled))
|
|
336
347
|
rows.append((" Modal API Access:", disabled if info.restrict_modal_access else enabled))
|
|
@@ -338,6 +349,7 @@ async def info(
|
|
|
338
349
|
|
|
339
350
|
# --- Web Functions ---
|
|
340
351
|
if info.web_info is not None:
|
|
352
|
+
rows.append(None)
|
|
341
353
|
rows.append("Web Info:")
|
|
342
354
|
|
|
343
355
|
if info.web_info.web_url:
|
|
@@ -345,7 +357,9 @@ async def info(
|
|
|
345
357
|
if info.web_info.method:
|
|
346
358
|
url_str = f" URL ({info.web_info.method}):"
|
|
347
359
|
|
|
348
|
-
|
|
360
|
+
url_text = Text(info.web_info.web_url, overflow="fold")
|
|
361
|
+
url_text.stylize(style=Style(link=info.web_info.web_url), end=len(info.web_info.web_url))
|
|
362
|
+
rows.append((url_str, url_text))
|
|
349
363
|
|
|
350
364
|
rows.append((" Authentication:", disabled if info.web_info.unauthenticated else enabled))
|
|
351
365
|
|
|
@@ -353,6 +367,7 @@ async def info(
|
|
|
353
367
|
if info.method_names is not None:
|
|
354
368
|
assert info.method_details is not None
|
|
355
369
|
|
|
370
|
+
rows.append(None)
|
|
356
371
|
rows.append("Methods:")
|
|
357
372
|
|
|
358
373
|
for method_name in info.method_names:
|
|
@@ -368,10 +383,14 @@ async def info(
|
|
|
368
383
|
if web_info.method:
|
|
369
384
|
url_str = f" URL ({web_info.method}):"
|
|
370
385
|
|
|
371
|
-
|
|
386
|
+
url_text = Text(web_info.web_url, overflow="fold")
|
|
387
|
+
url_text.stylize(style=Style(link=web_info.web_url), end=len(web_info.web_url))
|
|
388
|
+
|
|
389
|
+
rows.append((url_str, url_text))
|
|
372
390
|
|
|
373
391
|
# --- Mounts ---
|
|
374
392
|
if info.volumes:
|
|
393
|
+
rows.append(None)
|
|
375
394
|
rows.append("Volume Mounts:")
|
|
376
395
|
for mount_path, volume in info.volumes.items():
|
|
377
396
|
assert volume.volume_id is not None
|
|
@@ -390,6 +409,7 @@ async def info(
|
|
|
390
409
|
rows.append((f" {mount_path}", volume_text))
|
|
391
410
|
|
|
392
411
|
if info.cloud_bucket_mounts:
|
|
412
|
+
rows.append(None)
|
|
393
413
|
rows.append("Cloud Bucket Mounts:")
|
|
394
414
|
for mount_path, cbm in info.cloud_bucket_mounts.items():
|
|
395
415
|
extra = []
|
|
@@ -407,6 +427,7 @@ async def info(
|
|
|
407
427
|
|
|
408
428
|
# --- Secrets ---
|
|
409
429
|
if info.secrets:
|
|
430
|
+
rows.append(None)
|
|
410
431
|
rows.append("Secrets:")
|
|
411
432
|
|
|
412
433
|
async def _hydrate(secret_id: str) -> tuple[str, _Secret | None]:
|
|
@@ -446,18 +467,20 @@ async def info(
|
|
|
446
467
|
|
|
447
468
|
rows.append((f" {secret_identifier}", ", ".join(display_keys)))
|
|
448
469
|
|
|
470
|
+
t = Table(box=SIMPLE_HEAD, show_header=False)
|
|
449
471
|
for row in rows:
|
|
450
|
-
|
|
472
|
+
if row is None:
|
|
473
|
+
t.add_row()
|
|
474
|
+
continue
|
|
451
475
|
|
|
452
476
|
if not isinstance(row, tuple):
|
|
453
477
|
if isinstance(row, str):
|
|
454
|
-
row = Text(row)
|
|
478
|
+
row = Text(row, style="bold")
|
|
455
479
|
|
|
456
480
|
if not tty:
|
|
457
481
|
output_manager.print(row)
|
|
458
482
|
else:
|
|
459
483
|
t.add_row(row)
|
|
460
|
-
output_manager.print(t)
|
|
461
484
|
|
|
462
485
|
continue
|
|
463
486
|
|
|
@@ -470,9 +493,11 @@ async def info(
|
|
|
470
493
|
if isinstance(left, str):
|
|
471
494
|
left = Text(left, overflow="fold")
|
|
472
495
|
if isinstance(right, str):
|
|
473
|
-
right = Text(right, overflow="fold"
|
|
496
|
+
right = Text(right, overflow="fold")
|
|
474
497
|
|
|
475
498
|
t.add_row(left, right)
|
|
499
|
+
|
|
500
|
+
if tty:
|
|
476
501
|
output_manager.print(t)
|
|
477
502
|
|
|
478
503
|
|
|
@@ -15,6 +15,7 @@ import inspect
|
|
|
15
15
|
import shutil
|
|
16
16
|
import sys
|
|
17
17
|
import tempfile
|
|
18
|
+
import types
|
|
18
19
|
import typing
|
|
19
20
|
from collections import defaultdict
|
|
20
21
|
from dataclasses import dataclass
|
|
@@ -177,6 +178,41 @@ class AutoRunPriority:
|
|
|
177
178
|
APP_FUNCTION = 3
|
|
178
179
|
|
|
179
180
|
|
|
181
|
+
_LazyImportType = getattr(types, "LazyImportType", None) # Python 3.15+ (PEP 810)
|
|
182
|
+
|
|
183
|
+
_MAX_LISTED_LAZY_IMPORTS = 10
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def _is_lazy_import(module: types.ModuleType, name: str) -> bool:
|
|
187
|
+
return _LazyImportType is not None and isinstance(vars(module).get(name), _LazyImportType)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _check_not_lazy_import(module: types.ModuleType, name: str, import_ref: ImportRef) -> None:
|
|
191
|
+
if _is_lazy_import(module, name):
|
|
192
|
+
raise InvalidError(
|
|
193
|
+
f"'{name}' is imported lazily in '{import_ref.file_or_module}'. Modal Apps, Functions, and Classes "
|
|
194
|
+
"can't be imported lazily; change it to a regular import."
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _get_module_members(module: types.ModuleType) -> tuple[dict[str, typing.Any], list[str]]:
|
|
199
|
+
"""Like `dict(inspect.getmembers(module))`, but skips lazy imports instead of resolving them.
|
|
200
|
+
|
|
201
|
+
Returns the members and the names of the skipped lazy imports.
|
|
202
|
+
"""
|
|
203
|
+
members = {}
|
|
204
|
+
lazy_imports = []
|
|
205
|
+
for name in dir(module):
|
|
206
|
+
if _is_lazy_import(module, name):
|
|
207
|
+
lazy_imports.append(name)
|
|
208
|
+
continue
|
|
209
|
+
try:
|
|
210
|
+
members[name] = getattr(module, name)
|
|
211
|
+
except AttributeError:
|
|
212
|
+
continue # matches inspect.getmembers
|
|
213
|
+
return members, lazy_imports
|
|
214
|
+
|
|
215
|
+
|
|
180
216
|
def list_cli_commands(
|
|
181
217
|
module_members: dict[str, typing.Any],
|
|
182
218
|
include_service_functions: bool = False,
|
|
@@ -308,6 +344,7 @@ def import_app_from_ref(import_ref: ImportRef, base_cmd: str = "") -> App:
|
|
|
308
344
|
if "." in object_path:
|
|
309
345
|
raise click.UsageError(f"{object_path} is not a Modal App")
|
|
310
346
|
|
|
347
|
+
_check_not_lazy_import(module, object_path, import_ref)
|
|
311
348
|
app = getattr(module, object_path)
|
|
312
349
|
|
|
313
350
|
if app is None:
|
|
@@ -385,9 +422,9 @@ def import_and_filter(
|
|
|
385
422
|
accept_webhook=False,
|
|
386
423
|
accept_service_functions=False,
|
|
387
424
|
allow_stdin=False,
|
|
388
|
-
) -> tuple[Runnable | None, list[CLICommand]]:
|
|
389
|
-
"""Takes a function ref string and returns a single determined "runnable" to use,
|
|
390
|
-
runnables.
|
|
425
|
+
) -> tuple[Runnable | None, list[CLICommand], list[str]]:
|
|
426
|
+
"""Takes a function ref string and returns a single determined "runnable" to use, a list of all available
|
|
427
|
+
runnables, and the names of the lazy imports that were not searched for runnables.
|
|
391
428
|
|
|
392
429
|
The function ref can leave out partial information (apart from the file name/module)
|
|
393
430
|
as long as the runnable is uniquely identifiable by the provided information.
|
|
@@ -401,8 +438,10 @@ def import_and_filter(
|
|
|
401
438
|
"""
|
|
402
439
|
# all commands:
|
|
403
440
|
module = import_file_or_module(import_ref, base_cmd, allow_stdin=allow_stdin)
|
|
441
|
+
_check_not_lazy_import(module, import_ref.object_path.split(".", 1)[0], import_ref)
|
|
442
|
+
module_members, lazy_imports = _get_module_members(module)
|
|
404
443
|
cli_commands = list_cli_commands(
|
|
405
|
-
|
|
444
|
+
module_members,
|
|
406
445
|
include_service_functions=accept_service_functions,
|
|
407
446
|
)
|
|
408
447
|
|
|
@@ -413,10 +452,22 @@ def import_and_filter(
|
|
|
413
452
|
|
|
414
453
|
if inferred_runnable:
|
|
415
454
|
# if there is a single command with "highest run prio" - use that
|
|
416
|
-
return inferred_runnable, all_usable_commands
|
|
455
|
+
return inferred_runnable, all_usable_commands, lazy_imports
|
|
417
456
|
|
|
418
457
|
# otherwise, just return the list of all commands
|
|
419
|
-
return None, all_usable_commands
|
|
458
|
+
return None, all_usable_commands, lazy_imports
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
def format_lazy_imports_note(lazy_imports: list[str], found_commands: bool) -> str:
|
|
462
|
+
if found_commands or not lazy_imports:
|
|
463
|
+
return ""
|
|
464
|
+
details = "\n".join(f" {name}" for name in lazy_imports[:_MAX_LISTED_LAZY_IMPORTS])
|
|
465
|
+
if len(lazy_imports) > _MAX_LISTED_LAZY_IMPORTS:
|
|
466
|
+
details += f"\n ... and {len(lazy_imports) - _MAX_LISTED_LAZY_IMPORTS} more"
|
|
467
|
+
return (
|
|
468
|
+
"\n\nNote: Modal does not look inside lazy imports, and Modal Apps, Functions, and Classes can't be "
|
|
469
|
+
f"imported lazily. If one of these is a Modal object, change it to a regular import:\n{details}"
|
|
470
|
+
)
|
|
420
471
|
|
|
421
472
|
|
|
422
473
|
def infer_runnable(
|
|
@@ -31,6 +31,7 @@ from .import_refs import (
|
|
|
31
31
|
CLICommand,
|
|
32
32
|
MethodReference,
|
|
33
33
|
_get_runnable_app,
|
|
34
|
+
format_lazy_imports_note,
|
|
34
35
|
import_and_filter,
|
|
35
36
|
import_app_from_ref,
|
|
36
37
|
parse_import_ref,
|
|
@@ -472,7 +473,7 @@ class RunGroup(ModalGroup):
|
|
|
472
473
|
from_stdin = import_ref.file_or_module == STDIN_REF
|
|
473
474
|
if from_stdin and ctx.params["interactive"]:
|
|
474
475
|
raise ClickException("Interactive mode can't be used when reading a script from stdin.")
|
|
475
|
-
runnable, all_usable_commands = import_and_filter(
|
|
476
|
+
runnable, all_usable_commands, lazy_imports = import_and_filter(
|
|
476
477
|
import_ref, base_cmd="modal run", accept_local_entrypoint=True, accept_webhook=False, allow_stdin=True
|
|
477
478
|
)
|
|
478
479
|
if not runnable and from_stdin:
|
|
@@ -498,6 +499,8 @@ class RunGroup(ModalGroup):
|
|
|
498
499
|
else:
|
|
499
500
|
help_footer = f"'{import_ref.file_or_module}' has no functions or local entrypoints."
|
|
500
501
|
|
|
502
|
+
help_footer += format_lazy_imports_note(lazy_imports, found_commands=bool(all_usable_commands))
|
|
503
|
+
|
|
501
504
|
raise ClickException(f"{help_header}\n\n{help_footer}")
|
|
502
505
|
|
|
503
506
|
app = _get_runnable_app(runnable)
|
|
@@ -9,7 +9,8 @@ from typing import AsyncGenerator, Sequence, cast
|
|
|
9
9
|
|
|
10
10
|
import click
|
|
11
11
|
from click import UsageError
|
|
12
|
-
from rich.box import SIMPLE
|
|
12
|
+
from rich.box import SIMPLE, SIMPLE_HEAD
|
|
13
|
+
from rich.style import Style
|
|
13
14
|
from rich.table import Column, Table
|
|
14
15
|
from rich.text import Text
|
|
15
16
|
|
|
@@ -174,16 +175,22 @@ async def info(
|
|
|
174
175
|
enabled = "Enabled"
|
|
175
176
|
disabled = "Disabled"
|
|
176
177
|
|
|
177
|
-
rows: list[str | Text | tuple[str | Text, str | Text]] = []
|
|
178
|
+
rows: list[str | Text | tuple[str | Text, str | Text] | None] = []
|
|
178
179
|
|
|
179
|
-
rows.append(("Server Name:", handle_metadata.function_name))
|
|
180
|
-
rows.append(
|
|
181
|
-
rows.append(("
|
|
182
|
-
rows.append(("
|
|
180
|
+
rows.append((Text("Server Name:", style="bold"), handle_metadata.function_name))
|
|
181
|
+
rows.append(None)
|
|
182
|
+
rows.append((Text("Object ID:", style="bold"), server_id))
|
|
183
|
+
rows.append((Text("App ID:", style="bold"), handle_metadata.app_id))
|
|
184
|
+
rows.append((Text("Image ID:", style="bold"), str(info.image_info.image_id)))
|
|
183
185
|
|
|
184
186
|
# --- HTTP ---
|
|
187
|
+
rows.append(None)
|
|
185
188
|
rows.append("HTTP Info:")
|
|
186
|
-
|
|
189
|
+
|
|
190
|
+
url = Text(info.server_url, overflow="fold")
|
|
191
|
+
url.stylize(style=Style(link=info.server_url), end=len(info.server_url))
|
|
192
|
+
|
|
193
|
+
rows.append((" URL:", url))
|
|
187
194
|
rows.append((" Port:", not_configured if not info.port else str(info.port)))
|
|
188
195
|
rows.append((" Authentication:", disabled if info.unauthenticated else enabled))
|
|
189
196
|
rows.append((" HTTP/2:", disabled if not info.h2_enabled else enabled))
|
|
@@ -193,6 +200,7 @@ async def info(
|
|
|
193
200
|
rows.append((" Exit Grace Period:", f"{info.exit_grace_period} seconds"))
|
|
194
201
|
|
|
195
202
|
# --- Resources ---
|
|
203
|
+
rows.append(None)
|
|
196
204
|
rows.append("Resources:")
|
|
197
205
|
rows.append(
|
|
198
206
|
(
|
|
@@ -230,6 +238,7 @@ async def info(
|
|
|
230
238
|
)
|
|
231
239
|
|
|
232
240
|
# --- Autoscaling ---
|
|
241
|
+
rows.append(None)
|
|
233
242
|
rows.append("Autoscaling:")
|
|
234
243
|
rows.append(
|
|
235
244
|
(
|
|
@@ -276,6 +285,7 @@ async def info(
|
|
|
276
285
|
)
|
|
277
286
|
|
|
278
287
|
# --- Scheduling ---
|
|
288
|
+
rows.append(None)
|
|
279
289
|
rows.append("Scheduling:")
|
|
280
290
|
rows.append(
|
|
281
291
|
(" Compute Region(s):", not_configured if not info.compute_regions else " | ".join(info.compute_regions))
|
|
@@ -285,6 +295,7 @@ async def info(
|
|
|
285
295
|
rows.append((" Cloud Provider:", info.cloud))
|
|
286
296
|
|
|
287
297
|
if info.cluster_info:
|
|
298
|
+
rows.append(None)
|
|
288
299
|
rows.append("Clustering:")
|
|
289
300
|
rows.append((" Cluster Size:", str(info.cluster_info.size)))
|
|
290
301
|
rows.append((" RDMA:", enabled if info.cluster_info.rdma else disabled))
|
|
@@ -293,6 +304,7 @@ async def info(
|
|
|
293
304
|
|
|
294
305
|
# --- Mounts ---
|
|
295
306
|
if info.volumes:
|
|
307
|
+
rows.append(None)
|
|
296
308
|
rows.append("Volume Mounts:")
|
|
297
309
|
for mount_path, volume in info.volumes.items():
|
|
298
310
|
assert volume.volume_id is not None
|
|
@@ -311,6 +323,7 @@ async def info(
|
|
|
311
323
|
rows.append((f" {mount_path}", volume_text))
|
|
312
324
|
|
|
313
325
|
if info.cloud_bucket_mounts:
|
|
326
|
+
rows.append(None)
|
|
314
327
|
rows.append("Cloud Bucket Mounts:")
|
|
315
328
|
for mount_path, cbm in info.cloud_bucket_mounts.items():
|
|
316
329
|
extra = []
|
|
@@ -328,6 +341,7 @@ async def info(
|
|
|
328
341
|
|
|
329
342
|
# --- Secrets ---
|
|
330
343
|
if info.secrets:
|
|
344
|
+
rows.append(None)
|
|
331
345
|
rows.append("Secrets:")
|
|
332
346
|
|
|
333
347
|
async def _hydrate(secret_id: str) -> tuple[str, _Secret | None]:
|
|
@@ -367,18 +381,20 @@ async def info(
|
|
|
367
381
|
|
|
368
382
|
rows.append((f" {secret_identifier}", ", ".join(display_keys)))
|
|
369
383
|
|
|
384
|
+
t = Table(box=SIMPLE_HEAD, show_header=False)
|
|
370
385
|
for row in rows:
|
|
371
|
-
|
|
386
|
+
if row is None:
|
|
387
|
+
t.add_row()
|
|
388
|
+
continue
|
|
372
389
|
|
|
373
390
|
if not isinstance(row, tuple):
|
|
374
391
|
if isinstance(row, str):
|
|
375
|
-
row = Text(row)
|
|
392
|
+
row = Text(row, style="bold")
|
|
376
393
|
|
|
377
394
|
if not tty:
|
|
378
395
|
output_manager.print(row)
|
|
379
396
|
else:
|
|
380
397
|
t.add_row(row)
|
|
381
|
-
output_manager.print(t)
|
|
382
398
|
|
|
383
399
|
continue
|
|
384
400
|
|
|
@@ -391,9 +407,11 @@ async def info(
|
|
|
391
407
|
if isinstance(left, str):
|
|
392
408
|
left = Text(left, overflow="fold")
|
|
393
409
|
if isinstance(right, str):
|
|
394
|
-
right = Text(right, overflow="fold"
|
|
410
|
+
right = Text(right, overflow="fold")
|
|
395
411
|
|
|
396
412
|
t.add_row(left, right)
|
|
413
|
+
|
|
414
|
+
if tty:
|
|
397
415
|
output_manager.print(t)
|
|
398
416
|
|
|
399
417
|
|
|
@@ -28,6 +28,7 @@ from ..volume import Volume
|
|
|
28
28
|
from ._help import ModalCommand
|
|
29
29
|
from .import_refs import (
|
|
30
30
|
MethodReference,
|
|
31
|
+
format_lazy_imports_note,
|
|
31
32
|
import_and_filter,
|
|
32
33
|
parse_import_ref,
|
|
33
34
|
)
|
|
@@ -162,7 +163,7 @@ def _start_shell_in_running_container(ref: str, cmd: str, pty: bool) -> None:
|
|
|
162
163
|
|
|
163
164
|
def _function_spec_from_ref(ref: str, use_module_mode: bool) -> _FunctionSpec:
|
|
164
165
|
import_ref = parse_import_ref(ref, use_module_mode=use_module_mode, command="modal shell")
|
|
165
|
-
runnable, all_usable_commands = import_and_filter(
|
|
166
|
+
runnable, all_usable_commands, lazy_imports = import_and_filter(
|
|
166
167
|
import_ref,
|
|
167
168
|
base_cmd="modal shell",
|
|
168
169
|
accept_local_entrypoint=False,
|
|
@@ -181,6 +182,8 @@ def _function_spec_from_ref(ref: str, use_module_mode: bool) -> _FunctionSpec:
|
|
|
181
182
|
else:
|
|
182
183
|
help_footer = f"The selected module '{import_ref.file_or_module}' has no Modal functions or classes."
|
|
183
184
|
|
|
185
|
+
help_footer += format_lazy_imports_note(lazy_imports, found_commands=bool(all_usable_commands))
|
|
186
|
+
|
|
184
187
|
raise ClickException(f"{help_header}\n\n{help_footer}")
|
|
185
188
|
|
|
186
189
|
if isinstance(runnable, MethodReference):
|
|
@@ -80,7 +80,7 @@ class _Client:
|
|
|
80
80
|
server_url: str,
|
|
81
81
|
client_type: int,
|
|
82
82
|
credentials: typing.Optional[tuple[str, str]],
|
|
83
|
-
version: str = "1.6.2.
|
|
83
|
+
version: str = "1.6.2.dev12",
|
|
84
84
|
*,
|
|
85
85
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
86
86
|
):
|
|
@@ -290,7 +290,7 @@ class Client:
|
|
|
290
290
|
server_url: str,
|
|
291
291
|
client_type: int,
|
|
292
292
|
credentials: typing.Optional[tuple[str, str]],
|
|
293
|
-
version: str = "1.6.2.
|
|
293
|
+
version: str = "1.6.2.dev12",
|
|
294
294
|
*,
|
|
295
295
|
oauth_credentials: typing.Optional[_OAuthCredentials] = None,
|
|
296
296
|
):
|
|
@@ -141,6 +141,8 @@ def _agent_environment() -> str | None:
|
|
|
141
141
|
_TOOL_SPECIFIC_ENV_VARS: list[tuple[str, str]] = [
|
|
142
142
|
("CLAUDECODE", "claude-code"),
|
|
143
143
|
("CODEX_THREAD_ID", "codex"),
|
|
144
|
+
("CODEX_SESSION_ID", "codex"), # unified exec, always injected
|
|
145
|
+
("CODEX_SANDBOX", "codex"),
|
|
144
146
|
("GEMINI_CLI", "gemini-cli"),
|
|
145
147
|
("CURSOR_AGENT", "cursor"),
|
|
146
148
|
("CLINE_ACTIVE", "cline"),
|
|
@@ -152,6 +154,8 @@ def _agent_environment() -> str | None:
|
|
|
152
154
|
("COPILOT_AGENT_SESSION_ID", "copilot"),
|
|
153
155
|
("ANTIGRAVITY_AGENT", "antigravity"),
|
|
154
156
|
("JUNIE_SHIM_PATH", "junie"),
|
|
157
|
+
("QWEN_CODE", "qwen-code"),
|
|
158
|
+
("MUSE_SESSION_ID", "muse-code"),
|
|
155
159
|
]
|
|
156
160
|
for env_var, agent_name in _TOOL_SPECIFIC_ENV_VARS:
|
|
157
161
|
if os.environ.get(env_var):
|
|
@@ -619,7 +619,7 @@ class Function(
|
|
|
619
619
|
|
|
620
620
|
_call_generator: ___call_generator_spec
|
|
621
621
|
|
|
622
|
-
class __remote_spec(typing_extensions.Protocol[
|
|
622
|
+
class __remote_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
623
623
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
|
624
624
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result.
|
|
625
625
|
|
|
@@ -644,7 +644,7 @@ class Function(
|
|
|
644
644
|
"""
|
|
645
645
|
...
|
|
646
646
|
|
|
647
|
-
remote: __remote_spec[modal._functions.
|
|
647
|
+
remote: __remote_spec[modal._functions.ReturnType, modal._functions.P]
|
|
648
648
|
|
|
649
649
|
class __remote_gen_spec(typing_extensions.Protocol):
|
|
650
650
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
|
@@ -694,7 +694,7 @@ class Function(
|
|
|
694
694
|
"""
|
|
695
695
|
...
|
|
696
696
|
|
|
697
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
|
697
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
698
698
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
699
699
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
|
700
700
|
|
|
@@ -727,7 +727,7 @@ class Function(
|
|
|
727
727
|
"""
|
|
728
728
|
...
|
|
729
729
|
|
|
730
|
-
_experimental_spawn: ___experimental_spawn_spec[modal._functions.
|
|
730
|
+
_experimental_spawn: ___experimental_spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
731
731
|
|
|
732
732
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER]):
|
|
733
733
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> None: ...
|
|
@@ -735,7 +735,7 @@ class Function(
|
|
|
735
735
|
|
|
736
736
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P]
|
|
737
737
|
|
|
738
|
-
class __spawn_spec(typing_extensions.Protocol[
|
|
738
|
+
class __spawn_spec(typing_extensions.Protocol[ReturnType_INNER, P_INNER]):
|
|
739
739
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
|
740
740
|
"""Calls the function with the given arguments, without waiting for the results.
|
|
741
741
|
|
|
@@ -768,7 +768,7 @@ class Function(
|
|
|
768
768
|
"""
|
|
769
769
|
...
|
|
770
770
|
|
|
771
|
-
spawn: __spawn_spec[modal._functions.
|
|
771
|
+
spawn: __spawn_spec[modal._functions.ReturnType, modal._functions.P]
|
|
772
772
|
|
|
773
773
|
@property
|
|
774
774
|
def _raw_f_(self) -> collections.abc.Callable[..., typing.Any]: ...
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|