modAL 1.3.3.dev0__tar.gz → 1.3.5__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.3.3.dev0 → modal-1.3.5}/PKG-INFO +1 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/__init__.py +2 -2
- modal-1.3.5/modal/__main__.py +49 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_billing.py +15 -5
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_functions.py +9 -9
- modal-1.3.5/modal/_output/__init__.py +1 -0
- modal-1.3.5/modal/_output/manager.py +542 -0
- modal-1.3.5/modal/_output/pty.py +200 -0
- modal-1.3.3.dev0/modal/_output.py → modal-1.3.5/modal/_output/rich.py +326 -266
- modal-1.3.5/modal/_output/status.py +101 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_resolver.py +1 -62
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/asgi.py +2 -2
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_server.py +3 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/async_utils.py +71 -67
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/browser_utils.py +8 -7
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/function_utils.py +0 -87
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/grpc_utils.py +17 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/shell_utils.py +48 -2
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/task_command_router_client.py +3 -1
- modal-1.3.5/modal/_utils/time_utils.py +204 -0
- modal-1.3.5/modal/_vendor/version.py +844 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_watcher.py +2 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/app.py +5 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/app.pyi +10 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/billing.py +2 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/_traceback.py +3 -36
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/app.py +1 -4
- modal-1.3.5/modal/cli/billing.py +158 -0
- modal-1.3.5/modal/cli/changelog.py +157 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/cluster.py +4 -5
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/config.py +2 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/container.py +8 -2
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/dashboard.py +1 -4
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/dict.py +2 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/entry_point.py +17 -10
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/import_refs.py +15 -10
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/launch.py +12 -15
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/network_file_system.py +21 -29
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/profile.py +6 -6
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/queues.py +4 -5
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/run.py +46 -45
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/secret.py +7 -6
- modal-1.3.5/modal/cli/selector.py +124 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/token.py +11 -12
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/utils.py +28 -9
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/volume.py +19 -24
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/client.pyi +2 -10
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cloud_bucket_mount.py +3 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cloud_bucket_mount.pyi +3 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/container_process.py +6 -8
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/dict.py +42 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/dict.pyi +52 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/experimental/flash.py +10 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/experimental/flash.pyi +3 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/functions.pyi +6 -6
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/gpu.py +3 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/image.py +15 -8
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/image.pyi +7 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/io_streams.py +4 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/mount.py +4 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/network_file_system.py +1 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/network_file_system.pyi +3 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/object.pyi +57 -13
- modal-1.3.5/modal/output.py +47 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/partial_function.pyi +2 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/queue.py +45 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/queue.pyi +59 -7
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/retries.py +0 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/runner.py +49 -56
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/sandbox.py +149 -19
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/sandbox.pyi +203 -29
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/secret.py +18 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/secret.pyi +27 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/serving.py +10 -13
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/token_flow.py +18 -19
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/volume.py +71 -1
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/volume.pyi +56 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal.egg-info/PKG-INFO +1 -3
- {modal-1.3.3.dev0 → modal-1.3.5}/modal.egg-info/SOURCES.txt +9 -5
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_docs/gen_reference_docs.py +1 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_docs/mdmd/mdmd.py +51 -2
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/api_grpc.py +64 -0
- modal-1.3.5/modal_proto/api_pb2.py +5331 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/api_pb2.pyi +147 -2
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/api_pb2_grpc.py +132 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/api_pb2_grpc.pyi +40 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/modal_api_grpc.py +4 -0
- modal-1.3.5/modal_proto/task_command_router_pb2.py +180 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_version/__init__.py +1 -1
- modal-1.3.3.dev0/LICENSE +0 -176
- modal-1.3.3.dev0/modal/__main__.py +0 -53
- modal-1.3.3.dev0/modal/_pty.py +0 -57
- modal-1.3.3.dev0/modal/_utils/time_utils.py +0 -43
- modal-1.3.3.dev0/modal/output.py +0 -64
- modal-1.3.3.dev0/modal_proto/api.proto +0 -3938
- modal-1.3.3.dev0/modal_proto/api_pb2.py +0 -1139
- modal-1.3.3.dev0/modal_proto/task_command_router.proto +0 -164
- modal-1.3.3.dev0/modal_proto/task_command_router_pb2.py +0 -60
- {modal-1.3.3.dev0 → modal-1.3.5}/README.md +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_clustered_functions.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_clustered_functions.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_container_entrypoint.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_grpc_client.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_ipython.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_load_context.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_location.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_object.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_partial_function.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_resources.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/execution_context.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/telemetry.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_serialization.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_traceback.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_tunnel.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_tunnel.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_type_manager.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/app_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/blob_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/deprecation.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/docker_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/git_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/hash_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/http_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/logger.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/mount_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/name_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/package_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_vendor/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/_vendor/tblib.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/2023.12.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/2024.04.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/2024.10.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/2025.06.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/README.md +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/builder/base-images.json +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/call_graph.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/_download.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/environment.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/programs/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/programs/vscode.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cli/shell.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/client.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cls.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/cls.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/config.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/container_process.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/environments.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/environments.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/exception.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/experimental/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/experimental/ipython.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/file_io.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/file_io.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/file_pattern_matcher.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/functions.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/io_streams.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/mount.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/object.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/parallel_map.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/parallel_map.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/partial_function.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/proxy.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/proxy.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/py.typed +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/runner.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/running_app.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/schedule.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/scheduler_placement.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/server.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/server.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/serving.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/snapshot.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/snapshot.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/stream_type.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal/token_flow.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal.egg-info/requires.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal.egg-info/top_level.txt +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_docs/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/__init__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/py.typed +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/modal_version/__main__.py +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/pyproject.toml +0 -0
- {modal-1.3.3.dev0 → modal-1.3.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: modal
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.5
|
|
4
4
|
Summary: Python client library for Modal
|
|
5
5
|
Author-email: Modal Labs <support@modal.com>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -15,7 +15,6 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
15
15
|
Classifier: Programming Language :: Python :: 3
|
|
16
16
|
Requires-Python: <3.15,>=3.10
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
|
-
License-File: LICENSE
|
|
19
18
|
Requires-Dist: aiohttp
|
|
20
19
|
Requires-Dist: cbor2
|
|
21
20
|
Requires-Dist: certifi
|
|
@@ -31,7 +30,6 @@ Requires-Dist: types-certifi
|
|
|
31
30
|
Requires-Dist: types-toml
|
|
32
31
|
Requires-Dist: watchfiles
|
|
33
32
|
Requires-Dist: typing_extensions~=4.6
|
|
34
|
-
Dynamic: license-file
|
|
35
33
|
|
|
36
34
|
# Modal Python SDK
|
|
37
35
|
|
|
@@ -9,6 +9,7 @@ if sys.version_info[:2] >= (3, 15):
|
|
|
9
9
|
from modal_version import __version__
|
|
10
10
|
|
|
11
11
|
try:
|
|
12
|
+
from . import billing
|
|
12
13
|
from ._runtime.execution_context import current_function_call_id, current_input_id, interact, is_local
|
|
13
14
|
from ._tunnel import Tunnel, forward
|
|
14
15
|
from .app import App
|
|
@@ -41,7 +42,6 @@ try:
|
|
|
41
42
|
from .schedule import Cron, Period
|
|
42
43
|
from .scheduler_placement import SchedulerPlacement
|
|
43
44
|
from .secret import Secret
|
|
44
|
-
from .server import Server
|
|
45
45
|
from .snapshot import SandboxSnapshot
|
|
46
46
|
from .volume import Volume
|
|
47
47
|
except Exception:
|
|
@@ -76,11 +76,11 @@ __all__ = [
|
|
|
76
76
|
"SandboxSnapshot",
|
|
77
77
|
"SchedulerPlacement",
|
|
78
78
|
"Secret",
|
|
79
|
-
"Server",
|
|
80
79
|
"Tunnel",
|
|
81
80
|
"Volume",
|
|
82
81
|
"asgi_app",
|
|
83
82
|
"batched",
|
|
83
|
+
"billing",
|
|
84
84
|
"concurrent",
|
|
85
85
|
"current_function_call_id",
|
|
86
86
|
"current_input_id",
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Copyright Modal Labs 2022
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from ._traceback import reduce_traceback_to_user_code
|
|
5
|
+
from .cli._traceback import highlight_modal_warnings, setup_rich_traceback
|
|
6
|
+
from .cli.entry_point import entrypoint_cli
|
|
7
|
+
from .cli.import_refs import _CliUserExecutionError
|
|
8
|
+
from .config import config
|
|
9
|
+
from .output import OutputManager, enable_output
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def main():
|
|
13
|
+
# Setup rich tracebacks, but only on user's end, when using the Modal CLI.
|
|
14
|
+
setup_rich_traceback()
|
|
15
|
+
highlight_modal_warnings()
|
|
16
|
+
|
|
17
|
+
# Enable rich output for the entire CLI session
|
|
18
|
+
with enable_output():
|
|
19
|
+
try:
|
|
20
|
+
entrypoint_cli()
|
|
21
|
+
|
|
22
|
+
except _CliUserExecutionError as exc:
|
|
23
|
+
if config.get("traceback"):
|
|
24
|
+
raise
|
|
25
|
+
|
|
26
|
+
assert exc.__cause__ # We should always raise this class from another error
|
|
27
|
+
tb = reduce_traceback_to_user_code(exc.__cause__.__traceback__, exc.user_source)
|
|
28
|
+
sys.excepthook(type(exc.__cause__), exc.__cause__, tb)
|
|
29
|
+
sys.exit(1)
|
|
30
|
+
|
|
31
|
+
except Exception as exc:
|
|
32
|
+
if (
|
|
33
|
+
# User has asked to alway see full tracebacks
|
|
34
|
+
config.get("traceback")
|
|
35
|
+
# The exception message is empty, so we need to provide _some_ actionable information
|
|
36
|
+
or not str(exc)
|
|
37
|
+
):
|
|
38
|
+
raise
|
|
39
|
+
|
|
40
|
+
content = str(exc)
|
|
41
|
+
if notes := getattr(exc, "__notes__", []):
|
|
42
|
+
content = f"{content}\n\nNote: {' '.join(notes)}"
|
|
43
|
+
|
|
44
|
+
OutputManager.get().print_error(content)
|
|
45
|
+
sys.exit(1)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
if __name__ == "__main__":
|
|
49
|
+
main()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Copyright Modal Labs 2025
|
|
2
2
|
from datetime import datetime, timezone
|
|
3
3
|
from decimal import Decimal
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Optional, TypedDict
|
|
5
5
|
|
|
6
6
|
from modal_proto import api_pb2
|
|
7
7
|
|
|
@@ -25,7 +25,7 @@ async def _workspace_billing_report(
|
|
|
25
25
|
resolution: str = "d", # Resolution, e.g. "d" for daily or "h" for hourly
|
|
26
26
|
tag_names: Optional[list[str]] = None, # Optional additional metadata to include
|
|
27
27
|
client: Optional[_Client] = None,
|
|
28
|
-
) -> list[
|
|
28
|
+
) -> list[WorkspaceBillingReportItem]:
|
|
29
29
|
"""Generate a tabular report of workspace usage by object and time.
|
|
30
30
|
|
|
31
31
|
The result will be a list of dictionaries for each interval (determined by `resolution`)
|
|
@@ -40,8 +40,18 @@ async def _workspace_billing_report(
|
|
|
40
40
|
partial `end` intervals will be excluded.
|
|
41
41
|
|
|
42
42
|
Additional user-provided metadata can be included in the report if the objects have tags
|
|
43
|
-
and `tag_names` (i.e., keys) are specified in the request.
|
|
44
|
-
to
|
|
43
|
+
and `tag_names` (i.e., keys) are specified in the request. Alternatively, pass `tag_names=["*"]`
|
|
44
|
+
to include all tags in the report. Note that tags will be attributed to the entire interval even
|
|
45
|
+
if they were added or removed at some point within it. If the tag name was not in use during an
|
|
46
|
+
interval, it will be absent from the tags dictionary in that output row.
|
|
47
|
+
|
|
48
|
+
In most cases, billing data will be available in the database that this API queries within
|
|
49
|
+
minutes, although there may be collection delays. If completeness is important for your use
|
|
50
|
+
case, we recommend leaving a buffer after the end of the query interval.
|
|
51
|
+
|
|
52
|
+
It's also possible to generate reports using the
|
|
53
|
+
[`modal billing report`](https://modal.com/docs/reference/cli/billing) CLI command. The CLI
|
|
54
|
+
has a few convenience features for generating reports across relative time ranges.
|
|
45
55
|
|
|
46
56
|
"""
|
|
47
57
|
if client is None:
|
|
@@ -71,7 +81,7 @@ async def _workspace_billing_report(
|
|
|
71
81
|
|
|
72
82
|
rows = []
|
|
73
83
|
async for pb_item in client.stub.WorkspaceBillingReport.unary_stream(request):
|
|
74
|
-
item = {
|
|
84
|
+
item: WorkspaceBillingReportItem = {
|
|
75
85
|
"object_id": pb_item.object_id,
|
|
76
86
|
"description": pb_item.description,
|
|
77
87
|
"environment_name": pb_item.environment_name,
|
|
@@ -21,7 +21,8 @@ from modal_proto.modal_api_grpc import ModalClientModal
|
|
|
21
21
|
|
|
22
22
|
from ._load_context import LoadContext
|
|
23
23
|
from ._object import _Object, live_method, live_method_gen
|
|
24
|
-
from .
|
|
24
|
+
from ._output.pty import get_pty_info
|
|
25
|
+
from ._output.status import FunctionCreationStatus
|
|
25
26
|
from ._resolver import Resolver
|
|
26
27
|
from ._resources import convert_fn_config_to_resources_config
|
|
27
28
|
from ._runtime.execution_context import current_input_id, is_local
|
|
@@ -47,7 +48,6 @@ from ._utils.deprecation import deprecation_warning, warn_if_passing_namespace
|
|
|
47
48
|
from ._utils.function_utils import (
|
|
48
49
|
ATTEMPT_TIMEOUT_GRACE_PERIOD,
|
|
49
50
|
OUTPUTS_TIMEOUT,
|
|
50
|
-
FunctionCreationStatus,
|
|
51
51
|
FunctionInfo,
|
|
52
52
|
_create_input,
|
|
53
53
|
_process_result,
|
|
@@ -71,7 +71,7 @@ from .gpu import GPU_T, parse_gpu_config
|
|
|
71
71
|
from .image import _Image
|
|
72
72
|
from .mount import _get_client_mount, _Mount
|
|
73
73
|
from .network_file_system import _NetworkFileSystem, network_file_system_mount_protos
|
|
74
|
-
from .output import
|
|
74
|
+
from .output import OutputManager
|
|
75
75
|
from .parallel_map import (
|
|
76
76
|
_experimental_spawn_map_async,
|
|
77
77
|
_experimental_spawn_map_sync,
|
|
@@ -550,6 +550,7 @@ class FunctionStats:
|
|
|
550
550
|
|
|
551
551
|
backlog: int
|
|
552
552
|
num_total_runners: int
|
|
553
|
+
num_running_inputs: int
|
|
553
554
|
|
|
554
555
|
|
|
555
556
|
def _parse_retries(
|
|
@@ -922,7 +923,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
922
923
|
async def _load(
|
|
923
924
|
self: _Function, resolver: Resolver, load_context: LoadContext, existing_object_id: Optional[str]
|
|
924
925
|
):
|
|
925
|
-
with FunctionCreationStatus(
|
|
926
|
+
with FunctionCreationStatus(tag) as function_creation_status:
|
|
926
927
|
timeout_secs = timeout
|
|
927
928
|
|
|
928
929
|
if app and app.is_interactive and not is_builder_function:
|
|
@@ -1639,10 +1640,7 @@ Use the `Function.get_web_url()` method instead.
|
|
|
1639
1640
|
raise InvalidError("A generator function cannot be called with `.map(...)`.")
|
|
1640
1641
|
|
|
1641
1642
|
assert self._function_name
|
|
1642
|
-
|
|
1643
|
-
count_update_callback = output_mgr.function_progress_callback(self._function_name, total=None)
|
|
1644
|
-
else:
|
|
1645
|
-
count_update_callback = None
|
|
1643
|
+
count_update_callback = OutputManager.get().function_progress_callback(self._function_name, total=None)
|
|
1646
1644
|
|
|
1647
1645
|
if self._input_plane_url:
|
|
1648
1646
|
async with aclosing(
|
|
@@ -1920,7 +1918,9 @@ Use the `Function.get_web_url()` method instead.
|
|
|
1920
1918
|
api_pb2.FunctionGetCurrentStatsRequest(function_id=self.object_id),
|
|
1921
1919
|
retry=Retry(total_timeout=10.0),
|
|
1922
1920
|
)
|
|
1923
|
-
return FunctionStats(
|
|
1921
|
+
return FunctionStats(
|
|
1922
|
+
backlog=resp.backlog, num_total_runners=resp.num_total_tasks, num_running_inputs=resp.num_running_inputs
|
|
1923
|
+
)
|
|
1924
1924
|
|
|
1925
1925
|
@live_method
|
|
1926
1926
|
async def _get_schema(self) -> api_pb2.FunctionSchema:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Copyright Modal Labs 2025
|