modAL 1.5.5__tar.gz → 1.5.5.dev1__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.5 → modal-1.5.5.dev1}/PKG-INFO +1 -1
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_container_entrypoint.py +2 -4
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_environments.py +5 -14
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_function_variants.py +3 -3
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_functions.py +20 -80
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_image.py +9 -9
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_logs_manager.py +0 -67
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_logs_manager.pyi +0 -167
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_object.py +4 -34
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_resolver.py +5 -5
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/container_io_manager.py +23 -44
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/container_io_manager.pyi +5 -10
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/user_code_imports.py +5 -5
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_serialization.py +1 -3
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/deprecation.py +0 -29
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/function_utils.py +9 -9
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/grpc_utils.py +0 -9
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/mount_utils.py +1 -1
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_workspace.py +6 -6
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/app.py +57 -68
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/app.pyi +32 -26
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/_help.py +4 -143
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/app.py +0 -51
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/changelog.py +1 -1
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/config.py +3 -8
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/entry_point.py +4 -9
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/environment.py +7 -29
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/import_refs.py +4 -9
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/launch.py +1 -1
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/profile.py +4 -4
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/run.py +8 -35
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/shell.py +2 -2
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/token.py +11 -3
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/client.py +15 -140
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/client.pyi +3 -124
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cls.py +18 -31
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cls.pyi +0 -20
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/config.py +7 -22
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/environments.pyi +2 -14
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/exception.py +2 -13
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/experimental/__init__.py +1 -2
- modal-1.5.5.dev1/modal/experimental/flash.py +814 -0
- modal-1.5.5.dev1/modal/experimental/flash.pyi +481 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/functions.pyi +4 -80
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/object.pyi +31 -18
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/runner.py +6 -6
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/sandbox.py +9 -123
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/sandbox.pyi +15 -99
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/skills/modal/SKILL.md +2 -2
- {modal-1.5.5 → modal-1.5.5.dev1}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/api_grpc.py +0 -32
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/api_pb2.py +905 -935
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/api_pb2.pyi +9 -156
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/api_pb2_grpc.py +0 -66
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/api_pb2_grpc.pyi +0 -20
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/modal_api_grpc.py +0 -2
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/task_command_router_pb2.py +34 -34
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/task_command_router_pb2.pyi +4 -20
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_version/__init__.py +1 -1
- {modal-1.5.5 → modal-1.5.5.dev1}/pyproject.toml +2 -2
- modal-1.5.5/modal/experimental/flash.py +0 -389
- modal-1.5.5/modal/experimental/flash.pyi +0 -235
- {modal-1.5.5 → modal-1.5.5.dev1}/LICENSE +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/README.md +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/__main__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_billing.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_clustered_functions.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_grpc_client.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_ipython.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_load_context.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_location.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_logs.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_output/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_output/manager.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_output/pty.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_output/rich.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_output/status.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_partial_function.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_resources.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_server.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_supports_logs.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_traceback.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_tunnel.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_tunnel.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_type_manager.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/logger.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_vendor/version.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/_watcher.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/billing.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/billing.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/README.md +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/builder/base-images.json +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/call_graph.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/_download.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/_traceback.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/billing.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/cluster.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/container.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/curl.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/dashboard.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/dict.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/endpoint.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/image.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/logo.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/queues.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/secret.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/selector.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/skills.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/utils.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/volume.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cli/workspace.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/container_process.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/container_process.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/dict.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/dict.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/environments.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/experimental/ipython.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/file_io.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/file_io.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/functions.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/image.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/image.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/io_streams.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/io_streams.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/mount.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/mount.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/network_file_system.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/network_file_system.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/object.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/output.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/parallel_map.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/parallel_map.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/partial_function.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/partial_function.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/proxy.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/proxy.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/py.typed +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/queue.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/queue.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/retries.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/runner.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/running_app.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/sandbox_fs.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/schedule.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/scheduler_placement.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/secret.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/secret.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/server.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/server.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/serving.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/serving.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/snapshot.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/snapshot.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/stream_type.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/token_flow.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/token_flow.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/types.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/volume.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/volume.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/workspace.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal/workspace.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/__init__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/py.typed +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/modal_version/__main__.py +0 -0
- {modal-1.5.5 → modal-1.5.5.dev1}/setup.cfg +0 -0
|
@@ -145,7 +145,7 @@ def call_function(
|
|
|
145
145
|
item_count += 1
|
|
146
146
|
|
|
147
147
|
await container_io_manager._send_outputs.aio(
|
|
148
|
-
io_context
|
|
148
|
+
io_context.output_items_generator_done(started_at, item_count)
|
|
149
149
|
)
|
|
150
150
|
else:
|
|
151
151
|
value = await io_context.call_function_async()
|
|
@@ -182,9 +182,7 @@ def call_function(
|
|
|
182
182
|
container_io_manager._queue_put(generator_queue, value)
|
|
183
183
|
item_count += 1
|
|
184
184
|
|
|
185
|
-
container_io_manager._send_outputs(
|
|
186
|
-
io_context, io_context.output_items_generator_done(started_at, item_count)
|
|
187
|
-
)
|
|
185
|
+
container_io_manager._send_outputs(io_context.output_items_generator_done(started_at, item_count))
|
|
188
186
|
else:
|
|
189
187
|
values = io_context.call_function_sync()
|
|
190
188
|
container_io_manager.push_outputs(io_context, started_at, values)
|
|
@@ -39,7 +39,6 @@ class _EnvironmentManager:
|
|
|
39
39
|
name: str, # Name to use for the new Environment
|
|
40
40
|
*,
|
|
41
41
|
restricted: bool = False, # If True, enable RBAC restrictions on the Environment
|
|
42
|
-
default_role: str | None = None, # Default member Role for the Restricted Environment
|
|
43
42
|
experimental_options: dict[str, Any] | None = None, # Experimental options for Environment creation
|
|
44
43
|
client: _Client | None = None, # Optional client with Modal credentials
|
|
45
44
|
) -> None:
|
|
@@ -52,11 +51,8 @@ class _EnvironmentManager:
|
|
|
52
51
|
```
|
|
53
52
|
"""
|
|
54
53
|
check_environment_name(name)
|
|
55
|
-
|
|
56
54
|
client = await _Client.from_env() if client is None else client
|
|
57
55
|
request = api_pb2.EnvironmentCreateRequest(name=name, is_managed=restricted)
|
|
58
|
-
if default_role:
|
|
59
|
-
request.default_member_role_str = default_role
|
|
60
56
|
if (experimental_options or {}).get("is_public", False):
|
|
61
57
|
request.environment_type = api_pb2.ENVIRONMENT_TYPE_PUBLIC
|
|
62
58
|
await client.stub.EnvironmentCreate(request)
|
|
@@ -120,12 +116,9 @@ class _EnvironmentRolesManager:
|
|
|
120
116
|
"""mdmd:hidden"""
|
|
121
117
|
self._environment = environment
|
|
122
118
|
|
|
123
|
-
async def list(self
|
|
119
|
+
async def list(self) -> dict[Literal["users", "service_users"], dict[str, str]]:
|
|
124
120
|
"""Enumerate the Environment Role for each user and service user in the workspace.
|
|
125
121
|
|
|
126
|
-
Args:
|
|
127
|
-
exclude_default: If `True`, only include roles that are directly assigned.
|
|
128
|
-
|
|
129
122
|
**Examples:**
|
|
130
123
|
|
|
131
124
|
```python notest
|
|
@@ -144,8 +137,6 @@ class _EnvironmentRolesManager:
|
|
|
144
137
|
users: dict[str, str] = {}
|
|
145
138
|
service_users: dict[str, str] = {}
|
|
146
139
|
for principal in resp.principal_roles:
|
|
147
|
-
if exclude_default and not principal.has_role_assignment:
|
|
148
|
-
continue
|
|
149
140
|
if principal.user_id:
|
|
150
141
|
users[principal.user_name] = principal.role_str
|
|
151
142
|
elif principal.service_user_id:
|
|
@@ -261,8 +252,8 @@ class _EnvironmentMembersManager:
|
|
|
261
252
|
"""Remove the Environment Role of users and service users, reverting them to the default."""
|
|
262
253
|
deprecation_warning(
|
|
263
254
|
(2026, 7, 23),
|
|
264
|
-
"`Environment.members.remove()` is deprecated
|
|
265
|
-
"`Environment.roles.update()` instead.",
|
|
255
|
+
"`Environment.members.remove()` is deprecated. Environment Roles are now explicit; "
|
|
256
|
+
"set a role (e.g. 'no-access') with `Environment.roles.update()` instead.",
|
|
266
257
|
)
|
|
267
258
|
await self._environment.hydrate()
|
|
268
259
|
users = users or []
|
|
@@ -478,7 +469,7 @@ class _EnvironmentBillingManager:
|
|
|
478
469
|
elif end.tzinfo != timezone.utc:
|
|
479
470
|
raise InvalidError("Timezone-aware 'end' parameter must be in UTC.")
|
|
480
471
|
|
|
481
|
-
if not self._environment.
|
|
472
|
+
if not self._environment.is_hydrated:
|
|
482
473
|
await self._environment.hydrate()
|
|
483
474
|
|
|
484
475
|
request = api_pb2.WorkspaceBillingReportRequest(
|
|
@@ -549,7 +540,7 @@ class _EnvironmentBillingManager:
|
|
|
549
540
|
if cycle > datetime.now(timezone.utc):
|
|
550
541
|
raise InvalidError("Provided 'cycle' parameter cannot be in the future.")
|
|
551
542
|
|
|
552
|
-
if not self._environment.
|
|
543
|
+
if not self._environment.is_hydrated:
|
|
553
544
|
await self._environment.hydrate()
|
|
554
545
|
|
|
555
546
|
request = api_pb2.EnvironmentBillingSummaryRequest(environment_id=self._environment.object_id)
|
|
@@ -157,7 +157,7 @@ class _FunctionOptions:
|
|
|
157
157
|
+ list(self.secrets)
|
|
158
158
|
+ [mount.secret for _, mount in self.cloud_bucket_mounts if mount.secret]
|
|
159
159
|
)
|
|
160
|
-
return [dep for dep in all_deps if not dep.
|
|
160
|
+
return [dep for dep in all_deps if not dep.is_hydrated]
|
|
161
161
|
|
|
162
162
|
def to_proto(self) -> api_pb2.FunctionOptions:
|
|
163
163
|
"""Convert the dataclass to a FunctionOptions protobuf message."""
|
|
@@ -246,7 +246,7 @@ def _make_function_variant(
|
|
|
246
246
|
load_context: "LoadContext",
|
|
247
247
|
existing_object_id: str | None,
|
|
248
248
|
):
|
|
249
|
-
if not base_function.
|
|
249
|
+
if not base_function.is_hydrated:
|
|
250
250
|
await base_function.hydrate(load_context.client)
|
|
251
251
|
assert base_function._client and base_function._client.stub
|
|
252
252
|
|
|
@@ -290,6 +290,6 @@ def _make_function_variant(
|
|
|
290
290
|
deps=_deps,
|
|
291
291
|
load_context_overrides=base_function._load_context_overrides,
|
|
292
292
|
)
|
|
293
|
-
fun.
|
|
293
|
+
fun._info = base_function._info
|
|
294
294
|
fun._spec = base_function._spec # TODO (elias): fix - this is incorrect when using with_options
|
|
295
295
|
return fun
|
|
@@ -46,11 +46,10 @@ from ._utils.async_utils import (
|
|
|
46
46
|
warn_if_generator_is_not_consumed,
|
|
47
47
|
)
|
|
48
48
|
from ._utils.blob_utils import MAX_ASYNC_OBJECT_SIZE_BYTES, MAX_OBJECT_SIZE_BYTES
|
|
49
|
-
from ._utils.deprecation import with_deprecation_warning
|
|
50
49
|
from ._utils.function_utils import (
|
|
51
50
|
ATTEMPT_TIMEOUT_GRACE_PERIOD,
|
|
52
51
|
OUTPUTS_TIMEOUT,
|
|
53
|
-
|
|
52
|
+
FunctionInfo,
|
|
54
53
|
_create_input,
|
|
55
54
|
_parse_retries,
|
|
56
55
|
_process_result,
|
|
@@ -604,7 +603,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
604
603
|
"""
|
|
605
604
|
|
|
606
605
|
# TODO: more type annotations
|
|
607
|
-
|
|
606
|
+
_info: FunctionInfo | None
|
|
608
607
|
_serve_mounts: frozenset[_Mount] # set at load time, only by loader
|
|
609
608
|
_app: "modal.app._App | None" = None
|
|
610
609
|
# only set for InstanceServiceFunctions and bound instance methods
|
|
@@ -664,8 +663,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
664
663
|
return _FunctionLogsManager(self)
|
|
665
664
|
|
|
666
665
|
@staticmethod
|
|
667
|
-
def
|
|
668
|
-
info:
|
|
666
|
+
def from_local(
|
|
667
|
+
info: FunctionInfo,
|
|
669
668
|
app: "modal.app._App | None", # App here should only be None in case of Image.run_function
|
|
670
669
|
image: _Image,
|
|
671
670
|
env: dict[str, str | None] | None = None,
|
|
@@ -938,7 +937,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
938
937
|
with FunctionCreationStatus(tag) as function_creation_status:
|
|
939
938
|
timeout_secs = timeout
|
|
940
939
|
|
|
941
|
-
if app and app.
|
|
940
|
+
if app and app.is_interactive and not is_builder_function:
|
|
942
941
|
pty_info = get_pty_info(shell=False)
|
|
943
942
|
else:
|
|
944
943
|
pty_info = None
|
|
@@ -1111,7 +1110,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1111
1110
|
http_config=http_config,
|
|
1112
1111
|
is_server=function_definition.is_server,
|
|
1113
1112
|
routing_region=function_definition.routing_region,
|
|
1114
|
-
is_sessioned=function_definition.is_sessioned,
|
|
1115
1113
|
)
|
|
1116
1114
|
|
|
1117
1115
|
ranked_functions = []
|
|
@@ -1165,12 +1163,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1165
1163
|
# the only way to infer a LoadContext for an `@app.function`, and the App doesn't
|
|
1166
1164
|
# get its client until *after* the Function is created.
|
|
1167
1165
|
load_context = app._root_load_context if app else LoadContext.empty()
|
|
1168
|
-
obj
|
|
1169
|
-
_load, rep, preload=_preload, deps=_deps, load_context_overrides=load_context
|
|
1170
|
-
)
|
|
1166
|
+
obj = _Function._from_loader(_load, rep, preload=_preload, deps=_deps, load_context_overrides=load_context)
|
|
1171
1167
|
|
|
1172
1168
|
obj._raw_f = info.raw_f
|
|
1173
|
-
obj.
|
|
1169
|
+
obj._info = info
|
|
1174
1170
|
obj._tag = tag
|
|
1175
1171
|
obj._app = app # needed for CLI right now
|
|
1176
1172
|
obj._obj = None
|
|
@@ -1195,12 +1191,6 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1195
1191
|
|
|
1196
1192
|
return obj
|
|
1197
1193
|
|
|
1198
|
-
from_local = with_deprecation_warning(
|
|
1199
|
-
(2026, 8, 26),
|
|
1200
|
-
"`Function.from_local` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1201
|
-
)(_from_local)
|
|
1202
|
-
"""mdmd:hidden"""
|
|
1203
|
-
|
|
1204
1194
|
async def _update_autoscaler(
|
|
1205
1195
|
self,
|
|
1206
1196
|
*,
|
|
@@ -1393,16 +1383,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1393
1383
|
)
|
|
1394
1384
|
|
|
1395
1385
|
@property
|
|
1396
|
-
@with_deprecation_warning(
|
|
1397
|
-
(2026, 8, 26),
|
|
1398
|
-
"`Function.tag` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1399
|
-
)
|
|
1400
1386
|
def tag(self) -> str:
|
|
1401
1387
|
"""mdmd:hidden"""
|
|
1402
|
-
return self._tag_
|
|
1403
|
-
|
|
1404
|
-
@property
|
|
1405
|
-
def _tag_(self) -> str:
|
|
1406
1388
|
assert self._tag
|
|
1407
1389
|
return self._tag
|
|
1408
1390
|
|
|
@@ -1415,40 +1397,20 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1415
1397
|
return self._app
|
|
1416
1398
|
|
|
1417
1399
|
@property
|
|
1418
|
-
@with_deprecation_warning(
|
|
1419
|
-
(2026, 8, 26),
|
|
1420
|
-
"`Function.stub` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1421
|
-
)
|
|
1422
1400
|
def stub(self) -> "modal.app._App":
|
|
1423
1401
|
"""mdmd:hidden"""
|
|
1424
1402
|
# Deprecated soon, only for backwards compatibility
|
|
1425
1403
|
return self.app
|
|
1426
1404
|
|
|
1427
1405
|
@property
|
|
1428
|
-
|
|
1429
|
-
(2026, 8, 26),
|
|
1430
|
-
"`Function.info` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1431
|
-
)
|
|
1432
|
-
def info(self) -> FunctionSourceInfo:
|
|
1406
|
+
def info(self) -> FunctionInfo:
|
|
1433
1407
|
"""mdmd:hidden"""
|
|
1434
|
-
|
|
1408
|
+
assert self._info
|
|
1409
|
+
return self._info
|
|
1435
1410
|
|
|
1436
1411
|
@property
|
|
1437
|
-
def _source_info_(self) -> FunctionSourceInfo:
|
|
1438
|
-
assert self._source_info
|
|
1439
|
-
return self._source_info
|
|
1440
|
-
|
|
1441
|
-
@property
|
|
1442
|
-
@with_deprecation_warning(
|
|
1443
|
-
(2026, 8, 26),
|
|
1444
|
-
"`Function.spec` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1445
|
-
)
|
|
1446
1412
|
def spec(self) -> _FunctionSpec:
|
|
1447
1413
|
"""mdmd:hidden"""
|
|
1448
|
-
return self._spec_
|
|
1449
|
-
|
|
1450
|
-
@property
|
|
1451
|
-
def _spec_(self) -> _FunctionSpec:
|
|
1452
1414
|
assert self._spec
|
|
1453
1415
|
return self._spec
|
|
1454
1416
|
|
|
@@ -1456,19 +1418,13 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1456
1418
|
# only defined in definition scope/locally, and not for class methods at the moment
|
|
1457
1419
|
return bool(self._webhook_config and self._webhook_config.type != api_pb2.WEBHOOK_TYPE_UNSPECIFIED)
|
|
1458
1420
|
|
|
1459
|
-
def
|
|
1421
|
+
def get_build_def(self) -> str:
|
|
1460
1422
|
"""mdmd:hidden"""
|
|
1461
1423
|
# Plaintext source and arg definition for the function, so it's part of the image
|
|
1462
1424
|
# hash. We can't use the cloudpickle hash because it's not very stable.
|
|
1463
1425
|
assert hasattr(self, "_raw_f") and hasattr(self, "_build_args") and self._raw_f is not None
|
|
1464
1426
|
return f"{inspect.getsource(self._raw_f)}\n{repr(self._build_args)}"
|
|
1465
1427
|
|
|
1466
|
-
get_build_def = with_deprecation_warning(
|
|
1467
|
-
(2026, 8, 26),
|
|
1468
|
-
"`Function.get_build_def` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1469
|
-
)(_get_build_def)
|
|
1470
|
-
"""mdmd:hidden"""
|
|
1471
|
-
|
|
1472
1428
|
# Live handle methods
|
|
1473
1429
|
|
|
1474
1430
|
def _initialize_from_empty(self):
|
|
@@ -1477,7 +1433,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1477
1433
|
self._is_generator = None
|
|
1478
1434
|
self._web_url = None
|
|
1479
1435
|
self._function_name = None
|
|
1480
|
-
self.
|
|
1436
|
+
self._info = None
|
|
1481
1437
|
self._serve_mounts = frozenset()
|
|
1482
1438
|
self._metadata = None
|
|
1483
1439
|
self._experimental_flash_urls = None
|
|
@@ -1609,7 +1565,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1609
1565
|
new_function._webhook_config = self._webhook_config
|
|
1610
1566
|
|
|
1611
1567
|
# Other fields not necessarily initialized
|
|
1612
|
-
if self.
|
|
1568
|
+
if self._info is not None:
|
|
1613
1569
|
new_function._build_args = self._build_args
|
|
1614
1570
|
new_function._is_method = self._is_method
|
|
1615
1571
|
new_function._raw_f = self._raw_f
|
|
@@ -1716,16 +1672,8 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1716
1672
|
return self._apply_dynamic_config(options, "with_batching")
|
|
1717
1673
|
|
|
1718
1674
|
@property
|
|
1719
|
-
@with_deprecation_warning(
|
|
1720
|
-
(2026, 8, 26),
|
|
1721
|
-
"`Function.is_generator` is deprecated and will be removed in `modal` version 1.6.0",
|
|
1722
|
-
)
|
|
1723
1675
|
async def is_generator(self) -> bool:
|
|
1724
1676
|
"""mdmd:hidden"""
|
|
1725
|
-
return await self._is_generator_
|
|
1726
|
-
|
|
1727
|
-
@property
|
|
1728
|
-
async def _is_generator_(self) -> bool:
|
|
1729
1677
|
# hacky: kind of like @live_method, but not hydrating if we have the value already from local source
|
|
1730
1678
|
# TODO(michael) use a common / lightweight method for handling unhydrated metadata properties
|
|
1731
1679
|
if self._is_generator is not None:
|
|
@@ -1915,12 +1863,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1915
1863
|
yield item
|
|
1916
1864
|
|
|
1917
1865
|
def _is_local(self):
|
|
1918
|
-
return self.
|
|
1866
|
+
return self._info is not None
|
|
1919
1867
|
|
|
1920
|
-
def
|
|
1921
|
-
if not self.
|
|
1922
|
-
raise ExecutionError("Can't get
|
|
1923
|
-
return self.
|
|
1868
|
+
def _get_info(self) -> FunctionInfo:
|
|
1869
|
+
if not self._info:
|
|
1870
|
+
raise ExecutionError("Can't get info for a function that isn't locally defined")
|
|
1871
|
+
return self._info
|
|
1924
1872
|
|
|
1925
1873
|
def _get_obj(self) -> "modal.cls._Obj | None":
|
|
1926
1874
|
if not self._is_method:
|
|
@@ -1955,13 +1903,13 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1955
1903
|
)
|
|
1956
1904
|
raise ExecutionError(msg)
|
|
1957
1905
|
|
|
1958
|
-
info = self.
|
|
1906
|
+
info = self._get_info()
|
|
1959
1907
|
if not info.raw_f:
|
|
1960
1908
|
# Here if calling .local on a service function itself which should never happen
|
|
1961
1909
|
# TODO: check if we end up here in a container for a serialized function?
|
|
1962
1910
|
raise ExecutionError("Can't call .local on service function")
|
|
1963
1911
|
|
|
1964
|
-
if is_local() and self.
|
|
1912
|
+
if is_local() and self.spec.volumes or self.spec.network_file_systems:
|
|
1965
1913
|
warnings.warn(
|
|
1966
1914
|
f"The {info.function_name} function is executing locally "
|
|
1967
1915
|
+ "and will not have access to the mounted Volume or NetworkFileSystem data"
|
|
@@ -2059,20 +2007,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
2059
2007
|
fc._function_id = self.object_id
|
|
2060
2008
|
return fc
|
|
2061
2009
|
|
|
2062
|
-
@with_deprecation_warning(
|
|
2063
|
-
(2026, 8, 26),
|
|
2064
|
-
"`Function.get_raw_f` is deprecated and will be removed in `modal` version 1.6.0",
|
|
2065
|
-
)
|
|
2066
2010
|
def get_raw_f(self) -> Callable[..., Any]:
|
|
2067
2011
|
"""Return the inner Python object wrapped by this Modal Function.
|
|
2068
2012
|
|
|
2069
2013
|
Returns:
|
|
2070
2014
|
The original function object registered with Modal.
|
|
2071
2015
|
"""
|
|
2072
|
-
return self._raw_f_
|
|
2073
|
-
|
|
2074
|
-
@property
|
|
2075
|
-
def _raw_f_(self) -> Callable[..., Any]:
|
|
2076
2016
|
assert self._raw_f is not None
|
|
2077
2017
|
return self._raw_f
|
|
2078
2018
|
|
|
@@ -41,7 +41,7 @@ from ._utils.docker_utils import (
|
|
|
41
41
|
extract_copy_command_patterns,
|
|
42
42
|
find_dockerignore_file,
|
|
43
43
|
)
|
|
44
|
-
from ._utils.function_utils import
|
|
44
|
+
from ._utils.function_utils import FunctionInfo, parse_gpu_config
|
|
45
45
|
from ._utils.mount_utils import validate_only_modal_volumes, validate_volumes_by_object_id
|
|
46
46
|
from ._utils.name_utils import check_object_name
|
|
47
47
|
from .client import _Client
|
|
@@ -681,8 +681,8 @@ class _Image(_Object, type_prefix="im"):
|
|
|
681
681
|
|
|
682
682
|
if build_function:
|
|
683
683
|
build_function_id = build_function.object_id
|
|
684
|
-
globals = build_function.
|
|
685
|
-
attrs = build_function.
|
|
684
|
+
globals = build_function._get_info().get_globals()
|
|
685
|
+
attrs = build_function._get_info().get_cls_var_attrs()
|
|
686
686
|
globals = {**globals, **attrs}
|
|
687
687
|
filtered_globals = {}
|
|
688
688
|
for k, v in globals.items():
|
|
@@ -694,7 +694,7 @@ class _Image(_Object, type_prefix="im"):
|
|
|
694
694
|
# Skip unserializable values for now.
|
|
695
695
|
logger.warning(
|
|
696
696
|
f"Skipping unserializable global variable {k} for "
|
|
697
|
-
f"{build_function.
|
|
697
|
+
f"{build_function._get_info().function_name}. "
|
|
698
698
|
"Changes to this variable won't invalidate the image."
|
|
699
699
|
)
|
|
700
700
|
continue
|
|
@@ -704,7 +704,7 @@ class _Image(_Object, type_prefix="im"):
|
|
|
704
704
|
# TODO: better way to filter out types that don't have a stable hash?
|
|
705
705
|
build_function_globals = serialize(filtered_globals) if filtered_globals else b""
|
|
706
706
|
_build_function = api_pb2.BuildFunction(
|
|
707
|
-
definition=build_function.
|
|
707
|
+
definition=build_function.get_build_def(),
|
|
708
708
|
globals=build_function_globals,
|
|
709
709
|
input=build_function_input,
|
|
710
710
|
)
|
|
@@ -2754,9 +2754,9 @@ class _Image(_Object, type_prefix="im"):
|
|
|
2754
2754
|
# It may be possible to support lambdas eventually, but for now we don't handle them well, so reject quickly
|
|
2755
2755
|
raise InvalidError("Image.run_function does not support lambda functions.")
|
|
2756
2756
|
|
|
2757
|
-
info =
|
|
2757
|
+
info = FunctionInfo(raw_f)
|
|
2758
2758
|
|
|
2759
|
-
function = _Function.
|
|
2759
|
+
function = _Function.from_local(
|
|
2760
2760
|
info,
|
|
2761
2761
|
app=None,
|
|
2762
2762
|
image=self,
|
|
@@ -2938,7 +2938,7 @@ class _Image(_Object, type_prefix="im"):
|
|
|
2938
2938
|
try:
|
|
2939
2939
|
yield
|
|
2940
2940
|
except Exception as exc:
|
|
2941
|
-
if not self.
|
|
2941
|
+
if not self.is_hydrated:
|
|
2942
2942
|
# Might be hydrated later (if it's the container's used image)
|
|
2943
2943
|
self.inside_exceptions.append(exc)
|
|
2944
2944
|
elif env_image_id == self.object_id:
|
|
@@ -3051,7 +3051,7 @@ class _Image(_Object, type_prefix="im"):
|
|
|
3051
3051
|
"""mdmd:hidden"""
|
|
3052
3052
|
# Image inherits hydrate() from Object but can't be hydrated on demand
|
|
3053
3053
|
# Overriding the method lets us hide it from the docs and raise a better error message
|
|
3054
|
-
if not self.
|
|
3054
|
+
if not self.is_hydrated:
|
|
3055
3055
|
raise ExecutionError(
|
|
3056
3056
|
"Images cannot currently be hydrated on demand; you can build an Image by running an App that uses it."
|
|
3057
3057
|
)
|
|
@@ -93,8 +93,6 @@ def _entry_context_ids(object_id: str, item: api_pb2.TaskLogs, batch: api_pb2.Ta
|
|
|
93
93
|
]
|
|
94
94
|
case "fc":
|
|
95
95
|
context_ids = [item.input_id or batch.input_id, item.container_id or batch.task_id]
|
|
96
|
-
case "sb":
|
|
97
|
-
context_ids = [item.container_id or batch.task_id]
|
|
98
96
|
case _:
|
|
99
97
|
context_ids = []
|
|
100
98
|
# filter for empty strings, can happen for Server which have function_ids but no input/container
|
|
@@ -804,71 +802,6 @@ class _ImageLogsManager:
|
|
|
804
802
|
ImageLogsManager = synchronize_api(_ImageLogsManager, target_module=__name__)
|
|
805
803
|
|
|
806
804
|
|
|
807
|
-
class _SandboxLogsManager:
|
|
808
|
-
"""mdmd:namespace"""
|
|
809
|
-
|
|
810
|
-
def __init__(self, source: _SupportsLogs):
|
|
811
|
-
"""mdmd:hidden"""
|
|
812
|
-
self._manager = _LogsManager(source)
|
|
813
|
-
|
|
814
|
-
async def fetch(
|
|
815
|
-
self,
|
|
816
|
-
*,
|
|
817
|
-
since: datetime,
|
|
818
|
-
until: datetime | None = None,
|
|
819
|
-
source: LogSource | None = None,
|
|
820
|
-
search_text: str = "",
|
|
821
|
-
) -> AsyncGenerator[LogEntry, None]:
|
|
822
|
-
"""Fetch Sandbox logs corresponding to the date range and filters.
|
|
823
|
-
|
|
824
|
-
Args:
|
|
825
|
-
since: Start date to fetch logs from. Must be in UTC or timezone-naive,
|
|
826
|
-
which is interpreted as local time.
|
|
827
|
-
until: Defaults to current date if None. Must be in UTC or timezone-naive, which is interpreted
|
|
828
|
-
as local time.
|
|
829
|
-
source: Filter by source: 'stdout', 'stderr', or 'system'.
|
|
830
|
-
search_text: Filter by search text.
|
|
831
|
-
|
|
832
|
-
Yields:
|
|
833
|
-
`LogEntry` objects in chronological order.
|
|
834
|
-
|
|
835
|
-
Examples:
|
|
836
|
-
|
|
837
|
-
```python notest
|
|
838
|
-
sandbox = modal.Sandbox.from_name("my-app", "sandbox")
|
|
839
|
-
|
|
840
|
-
for entry in sandbox.logs.fetch(
|
|
841
|
-
since=datetime.now() - timedelta(minutes=25),
|
|
842
|
-
source="stdout",
|
|
843
|
-
):
|
|
844
|
-
print(entry.message, end="")
|
|
845
|
-
```
|
|
846
|
-
"""
|
|
847
|
-
async for log_entry in self._manager.fetch(since=since, until=until, source=source, search_text=search_text):
|
|
848
|
-
yield log_entry
|
|
849
|
-
|
|
850
|
-
async def tail(
|
|
851
|
-
self,
|
|
852
|
-
entries: int = 100,
|
|
853
|
-
*,
|
|
854
|
-
source: LogSource | None = None,
|
|
855
|
-
) -> AsyncGenerator[LogEntry, None]:
|
|
856
|
-
"""Fetch the most recent Sandbox logs.
|
|
857
|
-
|
|
858
|
-
Args:
|
|
859
|
-
entries: The number of log entries to return.
|
|
860
|
-
source: Filter by source: 'stdout', 'stderr', or 'system'.
|
|
861
|
-
|
|
862
|
-
Yields:
|
|
863
|
-
`LogEntry` objects in chronological order.
|
|
864
|
-
"""
|
|
865
|
-
async for log_entry in self._manager.tail(entries, source=source):
|
|
866
|
-
yield log_entry
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
SandboxLogsManager = synchronize_api(_SandboxLogsManager, target_module=__name__)
|
|
870
|
-
|
|
871
|
-
|
|
872
805
|
class _AppLogsManager:
|
|
873
806
|
"""mdmd:namespace"""
|
|
874
807
|
|