modal 1.5.4.dev16__tar.gz → 1.5.4.dev18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/PKG-INFO +1 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/container.py +52 -21
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/run.py +16 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/workspace.py +23 -14
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/client.pyi +2 -2
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/runner.py +7 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/runner.pyi +4 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/api_grpc.py +32 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/api_pb2.py +1355 -1292
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/api_pb2.pyi +131 -6
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/api_pb2_grpc.py +67 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/api_pb2_grpc.pyi +23 -3
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/modal_api_grpc.py +2 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_version/__init__.py +1 -1
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/LICENSE +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/README.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/__main__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_billing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_clustered_functions.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_environments.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_function_variants.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_functions.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_grpc_client.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_image.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_ipython.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_load_context.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_location.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_logs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_logs_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_logs_manager.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_object.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_output/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_output/manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_output/pty.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_output/rich.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_output/status.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_partial_function.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_resolver.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_resources.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_serialization.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_server.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_supports_logs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_traceback.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_tunnel.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_tunnel.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_type_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/logger.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_vendor/version.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_watcher.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/_workspace.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/app.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/app.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/billing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/billing.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/README.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/builder/base-images.json +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/call_graph.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/_download.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/_help.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/_traceback.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/app.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/billing.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/changelog.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/cluster.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/config.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/curl.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/dashboard.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/dict.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/endpoint.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/entry_point.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/environment.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/image.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/import_refs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/launch.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/logo.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/profile.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/queues.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/secret.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/selector.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/shell.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/skills.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/token.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/utils.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cli/volume.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/client.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cls.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/cls.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/config.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/container_process.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/container_process.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/dict.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/dict.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/environments.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/environments.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/exception.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/experimental/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/experimental/flash.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/experimental/ipython.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/file_io.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/file_io.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/functions.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/functions.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/image.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/image.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/io_streams.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/io_streams.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/mount.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/mount.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/network_file_system.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/network_file_system.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/object.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/object.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/output.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/parallel_map.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/parallel_map.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/partial_function.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/partial_function.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/proxy.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/proxy.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/py.typed +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/queue.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/queue.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/retries.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/running_app.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/sandbox.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/sandbox.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/sandbox_fs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/schedule.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/scheduler_placement.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/secret.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/secret.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/server.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/server.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/serving.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/serving.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/snapshot.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/snapshot.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/stream_type.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/token_flow.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/token_flow.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/types.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/volume.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/volume.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/workspace.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal/workspace.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/__init__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/py.typed +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/modal_version/__main__.py +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/pyproject.toml +0 -0
- {modal-1.5.4.dev16 → modal-1.5.4.dev18}/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.dev18",
|
|
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.dev18",
|
|
211
211
|
):
|
|
212
212
|
"""mdmd:hidden
|
|
213
213
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -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
|
|
|
@@ -83,6 +83,10 @@ class ModalClientBase(abc.ABC):
|
|
|
83
83
|
async def AppLookup(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.AppLookupRequest, modal_proto.api_pb2.AppLookupResponse]') -> None:
|
|
84
84
|
pass
|
|
85
85
|
|
|
86
|
+
@abc.abstractmethod
|
|
87
|
+
async def AppPromote(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.AppPromoteRequest, modal_proto.api_pb2.AppPromoteResponse]') -> None:
|
|
88
|
+
pass
|
|
89
|
+
|
|
86
90
|
@abc.abstractmethod
|
|
87
91
|
async def AppPublish(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.AppPublishRequest, modal_proto.api_pb2.AppPublishResponse]') -> None:
|
|
88
92
|
pass
|
|
@@ -931,6 +935,10 @@ class ModalClientBase(abc.ABC):
|
|
|
931
935
|
async def WebhookTokenListForEnvironment(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.WebhookTokenListForEnvironmentRequest, modal_proto.api_pb2.WebhookTokenListResponse]') -> None:
|
|
932
936
|
pass
|
|
933
937
|
|
|
938
|
+
@abc.abstractmethod
|
|
939
|
+
async def WorkspaceBillingRates(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.WorkspaceBillingRatesRequest, modal_proto.api_pb2.WorkspaceBillingRatesResponse]') -> None:
|
|
940
|
+
pass
|
|
941
|
+
|
|
934
942
|
@abc.abstractmethod
|
|
935
943
|
async def WorkspaceBillingReport(self, stream: 'grpclib.server.Stream[modal_proto.api_pb2.WorkspaceBillingReportRequest, modal_proto.api_pb2.WorkspaceBillingReportItem]') -> None:
|
|
936
944
|
pass
|
|
@@ -1061,6 +1069,12 @@ class ModalClientBase(abc.ABC):
|
|
|
1061
1069
|
modal_proto.api_pb2.AppLookupRequest,
|
|
1062
1070
|
modal_proto.api_pb2.AppLookupResponse,
|
|
1063
1071
|
),
|
|
1072
|
+
'/modal.client.ModalClient/AppPromote': grpclib.const.Handler(
|
|
1073
|
+
self.AppPromote,
|
|
1074
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
1075
|
+
modal_proto.api_pb2.AppPromoteRequest,
|
|
1076
|
+
modal_proto.api_pb2.AppPromoteResponse,
|
|
1077
|
+
),
|
|
1064
1078
|
'/modal.client.ModalClient/AppPublish': grpclib.const.Handler(
|
|
1065
1079
|
self.AppPublish,
|
|
1066
1080
|
grpclib.const.Cardinality.UNARY_UNARY,
|
|
@@ -2333,6 +2347,12 @@ class ModalClientBase(abc.ABC):
|
|
|
2333
2347
|
modal_proto.api_pb2.WebhookTokenListForEnvironmentRequest,
|
|
2334
2348
|
modal_proto.api_pb2.WebhookTokenListResponse,
|
|
2335
2349
|
),
|
|
2350
|
+
'/modal.client.ModalClient/WorkspaceBillingRates': grpclib.const.Handler(
|
|
2351
|
+
self.WorkspaceBillingRates,
|
|
2352
|
+
grpclib.const.Cardinality.UNARY_UNARY,
|
|
2353
|
+
modal_proto.api_pb2.WorkspaceBillingRatesRequest,
|
|
2354
|
+
modal_proto.api_pb2.WorkspaceBillingRatesResponse,
|
|
2355
|
+
),
|
|
2336
2356
|
'/modal.client.ModalClient/WorkspaceBillingReport': grpclib.const.Handler(
|
|
2337
2357
|
self.WorkspaceBillingReport,
|
|
2338
2358
|
grpclib.const.Cardinality.UNARY_STREAM,
|
|
@@ -2483,6 +2503,12 @@ class ModalClientStub:
|
|
|
2483
2503
|
modal_proto.api_pb2.AppLookupRequest,
|
|
2484
2504
|
modal_proto.api_pb2.AppLookupResponse,
|
|
2485
2505
|
)
|
|
2506
|
+
self.AppPromote = grpclib.client.UnaryUnaryMethod(
|
|
2507
|
+
channel,
|
|
2508
|
+
'/modal.client.ModalClient/AppPromote',
|
|
2509
|
+
modal_proto.api_pb2.AppPromoteRequest,
|
|
2510
|
+
modal_proto.api_pb2.AppPromoteResponse,
|
|
2511
|
+
)
|
|
2486
2512
|
self.AppPublish = grpclib.client.UnaryUnaryMethod(
|
|
2487
2513
|
channel,
|
|
2488
2514
|
'/modal.client.ModalClient/AppPublish',
|
|
@@ -3755,6 +3781,12 @@ class ModalClientStub:
|
|
|
3755
3781
|
modal_proto.api_pb2.WebhookTokenListForEnvironmentRequest,
|
|
3756
3782
|
modal_proto.api_pb2.WebhookTokenListResponse,
|
|
3757
3783
|
)
|
|
3784
|
+
self.WorkspaceBillingRates = grpclib.client.UnaryUnaryMethod(
|
|
3785
|
+
channel,
|
|
3786
|
+
'/modal.client.ModalClient/WorkspaceBillingRates',
|
|
3787
|
+
modal_proto.api_pb2.WorkspaceBillingRatesRequest,
|
|
3788
|
+
modal_proto.api_pb2.WorkspaceBillingRatesResponse,
|
|
3789
|
+
)
|
|
3758
3790
|
self.WorkspaceBillingReport = grpclib.client.UnaryStreamMethod(
|
|
3759
3791
|
channel,
|
|
3760
3792
|
'/modal.client.ModalClient/WorkspaceBillingReport',
|