modal 1.5.3.dev11__tar.gz → 1.5.3.dev13__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.3.dev11 → modal-1.5.3.dev13}/PKG-INFO +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_environments.py +68 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_functions.py +47 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_grpc_client.py +1 -1
- modal-1.5.3.dev13/modal/_logs_manager.py +674 -0
- modal-1.5.3.dev13/modal/_logs_manager.pyi +1063 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_object.py +5 -4
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_output/rich.py +3 -3
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_resources.py +4 -4
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/user_code_imports.py +2 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_server.py +20 -0
- modal-1.5.3.dev13/modal/_supports_logs.py +32 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_traceback.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/async_utils.py +5 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/blob_utils.py +1 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/bytes_io_segment_payload.py +2 -1
- modal-1.5.3.dev13/modal/_utils/display_utils.py +15 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/pattern_utils.py +2 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/time_utils.py +106 -14
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_workspace.py +66 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/app.py +3 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/app.pyi +4 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/billing.py +120 -16
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/cluster.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/dashboard.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/endpoint.py +23 -3
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/environment.py +103 -4
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/launch.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/network_file_system.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/profile.py +3 -3
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/shell.py +2 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/client.pyi +2 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cloud_bucket_mount.py +3 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/environments.pyi +69 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/experimental/__init__.py +2 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/file_pattern_matcher.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/functions.pyi +44 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/mount.py +89 -31
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/mount.pyi +18 -6
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/secret.py +2 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/server.pyi +23 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/serving.py +3 -3
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/types.py +81 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/workspace.pyi +71 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal.egg-info/SOURCES.txt +4 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2.py +92 -92
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2.pyi +16 -2
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_version/__init__.py +1 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/pyproject.toml +48 -1
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/LICENSE +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/README.md +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/__main__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_billing.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_clustered_functions.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_function_variants.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_image.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_ipython.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_load_context.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_location.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_logs.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_output/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_output/manager.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_output/pty.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_output/status.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_partial_function.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_resolver.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_serialization.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_tunnel.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_tunnel.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_type_manager.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/deprecation.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/function_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/logger.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_vendor/version.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/_watcher.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/billing.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/billing.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/README.md +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/builder/base-images.json +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/call_graph.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/_download.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/_help.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/_traceback.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/app.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/changelog.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/config.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/container.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/curl.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/dict.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/entry_point.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/image.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/import_refs.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/logo.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/queues.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/run.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/secret.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/selector.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/skills.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/token.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/utils.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/volume.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cli/workspace.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/client.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cls.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/cls.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/config.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/container_process.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/container_process.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/dict.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/dict.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/environments.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/exception.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/experimental/flash.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/experimental/flash.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/experimental/ipython.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/file_io.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/file_io.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/functions.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/image.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/image.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/io_streams.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/io_streams.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/network_file_system.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/network_file_system.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/object.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/object.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/output.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/parallel_map.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/parallel_map.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/partial_function.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/partial_function.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/proxy.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/proxy.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/py.typed +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/queue.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/queue.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/retries.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/runner.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/runner.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/running_app.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/sandbox.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/sandbox.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/sandbox_fs.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/schedule.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/scheduler_placement.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/secret.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/server.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/serving.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/snapshot.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/snapshot.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/stream_type.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/token_flow.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/token_flow.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/volume.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/volume.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal/workspace.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/__init__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/api_grpc.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/api_pb2.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/py.typed +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/modal_version/__main__.py +0 -0
- {modal-1.5.3.dev11 → modal-1.5.3.dev13}/setup.cfg +0 -0
|
@@ -17,10 +17,11 @@ from ._load_context import LoadContext
|
|
|
17
17
|
from ._object import _Object
|
|
18
18
|
from ._resolver import Resolver
|
|
19
19
|
from ._utils.name_utils import check_environment_name
|
|
20
|
+
from ._utils.time_utils import is_utc_month_aligned, parse_billing_cycle
|
|
20
21
|
from .client import _Client
|
|
21
22
|
from .config import config, logger
|
|
22
23
|
from .exception import InvalidError, WorkspaceManagementError
|
|
23
|
-
from .types import BillingReportItem
|
|
24
|
+
from .types import BillingReportItem, EnvironmentBillingSummary
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
@dataclass(frozen=True)
|
|
@@ -450,6 +451,71 @@ class _EnvironmentBillingManager:
|
|
|
450
451
|
async for pb_item in self._environment.client.stub.WorkspaceBillingReport.unary_stream(request)
|
|
451
452
|
]
|
|
452
453
|
|
|
454
|
+
async def summary(
|
|
455
|
+
self,
|
|
456
|
+
cycle: str | datetime | None = None, # Start of the summary, inclusive
|
|
457
|
+
) -> EnvironmentBillingSummary:
|
|
458
|
+
"""Return a summary of environment cost over a single billing cycle determined by `cycle`.
|
|
459
|
+
|
|
460
|
+
Unlike the analogous `Workspace.billing.summary()`, this API only emits metered cost
|
|
461
|
+
information. This is because billing adjustments due to credits, free storage, etc. are
|
|
462
|
+
applied at the Workspace level, and thus cannot be attributed to individual Environments.
|
|
463
|
+
|
|
464
|
+
Args:
|
|
465
|
+
cycle: Start of the summary, inclusive. Must be the first of a month, and must be in UTC
|
|
466
|
+
or timezone-naive (interpreted as UTC). If provided as a string, it must either be
|
|
467
|
+
formatted as an ISO 8601 month (YYYY-MM), or must be one of the convenience spellings
|
|
468
|
+
"this month" or "last month". If not provided, `cycle` defaults to the first of the
|
|
469
|
+
current month (in which case a summary is generated for the current billing cycle).
|
|
470
|
+
|
|
471
|
+
Returns:
|
|
472
|
+
A single `EnvironmentBillingSummary` dataclass containing the following fields:
|
|
473
|
+
- `metered_cost` representing cost before any adjustments, and
|
|
474
|
+
- `metered_cost_breakdown` containing a breakdown of that cost by the Modal resources
|
|
475
|
+
that generated it. The exact keys of this are subject to change as Modal's billing
|
|
476
|
+
model evolves.
|
|
477
|
+
|
|
478
|
+
All values are reported as `decimal.Decimal`s.
|
|
479
|
+
|
|
480
|
+
See also:
|
|
481
|
+
- [`modal environment billing summary`](https://modal.com/docs/cli/latest/billing#modal-environment-billing-summary):
|
|
482
|
+
An environment summary CLI that has convenience features around relative time range queries.
|
|
483
|
+
- [`Environment.billing.report()`](https://modal.com/docs/sdk/py/latest/Environment#billingreport):
|
|
484
|
+
An analogous report API that is scoped to a specific Environment.
|
|
485
|
+
"""
|
|
486
|
+
|
|
487
|
+
if cycle is None:
|
|
488
|
+
cycle = datetime.now(timezone.utc).replace(
|
|
489
|
+
day=1,
|
|
490
|
+
hour=0,
|
|
491
|
+
minute=0,
|
|
492
|
+
second=0,
|
|
493
|
+
microsecond=0,
|
|
494
|
+
)
|
|
495
|
+
elif isinstance(cycle, str):
|
|
496
|
+
cycle = parse_billing_cycle(cycle)
|
|
497
|
+
|
|
498
|
+
if cycle.tzinfo is None:
|
|
499
|
+
cycle = cycle.replace(tzinfo=timezone.utc)
|
|
500
|
+
elif cycle.tzinfo != timezone.utc:
|
|
501
|
+
raise InvalidError("Timezone-aware 'cycle' parameter must be in UTC.")
|
|
502
|
+
|
|
503
|
+
if not is_utc_month_aligned(cycle):
|
|
504
|
+
raise InvalidError("Provided 'cycle' parameter must be the first of a month.")
|
|
505
|
+
|
|
506
|
+
if cycle > datetime.now(timezone.utc):
|
|
507
|
+
raise InvalidError("Provided 'cycle' parameter cannot be in the future.")
|
|
508
|
+
|
|
509
|
+
if not self._environment.is_hydrated:
|
|
510
|
+
await self._environment.hydrate()
|
|
511
|
+
|
|
512
|
+
request = api_pb2.EnvironmentBillingSummaryRequest(environment_id=self._environment.object_id)
|
|
513
|
+
request.start_timestamp.FromDatetime(cycle)
|
|
514
|
+
|
|
515
|
+
return EnvironmentBillingSummary._from_proto(
|
|
516
|
+
await self._environment.client.stub.EnvironmentBillingSummary(request)
|
|
517
|
+
)
|
|
518
|
+
|
|
453
519
|
|
|
454
520
|
ENVIRONMENT_CACHE: dict[str, _Environment] = {}
|
|
455
521
|
|
|
@@ -525,4 +591,4 @@ def ensure_env(environment_name: str | None = None) -> str:
|
|
|
525
591
|
if environment_name is not None:
|
|
526
592
|
config.override_locally("environment", environment_name)
|
|
527
593
|
|
|
528
|
-
return config.get("environment")
|
|
594
|
+
return config.get("environment") or ""
|
|
@@ -22,6 +22,8 @@ from modal_proto.modal_api_grpc import ModalClientModal
|
|
|
22
22
|
from ._function_variants import _FunctionOptions, _make_function_variant
|
|
23
23
|
from ._image import _Image
|
|
24
24
|
from ._load_context import LoadContext
|
|
25
|
+
from ._logs import LogsFilters
|
|
26
|
+
from ._logs_manager import _FunctionCallLogsManager, _FunctionLogsManager
|
|
25
27
|
from ._object import _Object, live_method, live_method_gen
|
|
26
28
|
from ._output.pty import get_pty_info
|
|
27
29
|
from ._output.status import FunctionCreationStatus
|
|
@@ -32,6 +34,7 @@ from ._serialization import (
|
|
|
32
34
|
get_callable_schema,
|
|
33
35
|
serialize,
|
|
34
36
|
)
|
|
37
|
+
from ._supports_logs import _LogQueryData
|
|
35
38
|
from ._traceback import print_server_warnings
|
|
36
39
|
from ._utils.async_utils import (
|
|
37
40
|
TaskContext,
|
|
@@ -629,6 +632,27 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
629
632
|
_base_function: "_Function | None" = None
|
|
630
633
|
_app_id: str | None = None
|
|
631
634
|
|
|
635
|
+
async def _get_log_query_data(self) -> _LogQueryData:
|
|
636
|
+
await self.hydrate()
|
|
637
|
+
if not self._app_id:
|
|
638
|
+
raise ExecutionError("app_id should have been set during function hydration")
|
|
639
|
+
return _LogQueryData(self.client, self._app_id, LogsFilters(function_id=self.object_id))
|
|
640
|
+
|
|
641
|
+
@property
|
|
642
|
+
def logs(self) -> _FunctionLogsManager:
|
|
643
|
+
"""Access logs for a `Function`.
|
|
644
|
+
|
|
645
|
+
Use [`fetch()`](#logsfetch)
|
|
646
|
+
to read logs from a UTC time range, [`tail()`](#logstail)
|
|
647
|
+
to read the most recent logs, and [`stream()`](#logsstream)
|
|
648
|
+
to follow new logs as they arrive.
|
|
649
|
+
|
|
650
|
+
See also:
|
|
651
|
+
- [`modal app logs`](https://modal.com/docs/cli/latest/app#modal-app-logs):
|
|
652
|
+
CLI access to logs for an App.
|
|
653
|
+
"""
|
|
654
|
+
return _FunctionLogsManager(self)
|
|
655
|
+
|
|
632
656
|
@staticmethod
|
|
633
657
|
def from_local(
|
|
634
658
|
info: FunctionInfo,
|
|
@@ -2000,6 +2024,29 @@ class _FunctionCall(typing.Generic[ReturnType], _Object, type_prefix="fc"):
|
|
|
2000
2024
|
resp = await self.client.stub.FunctionCallFromId(request)
|
|
2001
2025
|
self._hydrate_metadata(resp)
|
|
2002
2026
|
|
|
2027
|
+
async def _get_log_query_data(self) -> _LogQueryData:
|
|
2028
|
+
await self.hydrate()
|
|
2029
|
+
if not self._app_id:
|
|
2030
|
+
await self._hydrate_from_id_metadata()
|
|
2031
|
+
if not self._app_id:
|
|
2032
|
+
raise ExecutionError("app_id should have been set during function call hydration")
|
|
2033
|
+
return _LogQueryData(self.client, self._app_id, LogsFilters(function_call_id=self.object_id))
|
|
2034
|
+
|
|
2035
|
+
@property
|
|
2036
|
+
def logs(self) -> _FunctionCallLogsManager:
|
|
2037
|
+
"""Access logs for a single `FunctionCall`.
|
|
2038
|
+
|
|
2039
|
+
Use [`fetch()`](#logsfetch)
|
|
2040
|
+
to read logs from a UTC time range, [`tail()`](#logstail)
|
|
2041
|
+
to read the most recent logs, and [`stream()`](#logsstream)
|
|
2042
|
+
to follow new logs as they arrive.
|
|
2043
|
+
|
|
2044
|
+
See also:
|
|
2045
|
+
- [`modal app logs`](https://modal.com/docs/cli/latest/app#modal-app-logs):
|
|
2046
|
+
CLI access to logs for an App.
|
|
2047
|
+
"""
|
|
2048
|
+
return _FunctionCallLogsManager(self)
|
|
2049
|
+
|
|
2003
2050
|
@live_method
|
|
2004
2051
|
async def num_inputs(self) -> int:
|
|
2005
2052
|
"""Get the number of inputs in the function call.
|
|
@@ -54,7 +54,7 @@ class grpc_error_converter:
|
|
|
54
54
|
with suppress_tb_frame():
|
|
55
55
|
if isinstance(exc, GRPCError):
|
|
56
56
|
modal_exc = _STATUS_TO_EXCEPTION[exc.status](exc.message)
|
|
57
|
-
modal_exc._grpc_message = exc.message
|
|
57
|
+
modal_exc._grpc_message = exc.message or ""
|
|
58
58
|
modal_exc._grpc_status = exc.status
|
|
59
59
|
modal_exc._grpc_details = exc.details
|
|
60
60
|
if use_full_traceback:
|