modal 1.5.5.dev16__tar.gz → 1.5.6.dev0__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.dev16 → modal-1.5.6.dev0}/PKG-INFO +1 -1
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_function_variants.py +1 -1
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_functions.py +50 -19
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_image.py +5 -5
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_object.py +30 -3
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_serialization.py +2 -5
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/deprecation.py +29 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/function_utils.py +9 -9
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/app.py +43 -15
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/app.pyi +6 -6
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/import_refs.py +1 -1
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/launch.py +2 -6
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/run.py +10 -14
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/shell.py +2 -2
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/client.pyi +2 -2
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cls.py +12 -5
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/exception.py +13 -2
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/experimental/__init__.py +0 -1
- modal-1.5.6.dev0/modal/experimental/flash.py +389 -0
- modal-1.5.6.dev0/modal/experimental/flash.pyi +235 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/functions.pyi +12 -12
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/object.pyi +7 -1
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/runner.py +1 -1
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/sandbox.py +0 -10
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/sandbox.pyi +0 -30
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/api_grpc.py +16 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/api_pb2.py +1361 -1305
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/api_pb2.pyi +109 -5
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/api_pb2_grpc.py +33 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/api_pb2_grpc.pyi +10 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/modal_api_grpc.py +1 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/task_command_router_pb2.py +34 -34
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/task_command_router_pb2.pyi +15 -3
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_version/__init__.py +1 -1
- modal-1.5.5.dev16/modal/experimental/flash.py +0 -833
- modal-1.5.5.dev16/modal/experimental/flash.pyi +0 -487
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/LICENSE +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/README.md +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/__main__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_billing.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_clustered_functions.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_clustered_functions.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_container_entrypoint.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_environments.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_grpc_client.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_ipython.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_load_context.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_location.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_logs.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_logs_manager.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_logs_manager.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_output/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_output/manager.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_output/pty.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_output/rich.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_output/status.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_partial_function.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_resolver.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_resources.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/asgi.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/execution_context.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/task_lifecycle_manager.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/task_lifecycle_manager.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/telemetry.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/user_code_event_loop.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_server.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_supports_logs.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_traceback.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_tunnel.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_tunnel.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_type_manager.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/app_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/async_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/blob_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/browser_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/curl_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/display_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/docker_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/git_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/hash_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/http_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/logger.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/mount_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/name_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/package_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/proxy_support.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/sandbox_fs_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/shell_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_utils/time_utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_vendor/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_vendor/tblib.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_vendor/version.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_watcher.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/_workspace.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/billing.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/billing.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/2023.12.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/2024.04.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/2024.10.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/2025.06.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/README.md +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/builder/base-images.json +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/call_graph.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/_download.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/_help.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/_traceback.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/app.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/billing.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/bootstrap.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/changelog.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/cluster.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/config.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/container.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/curl.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/dashboard.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/dict.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/endpoint.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/entry_point.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/environment.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/image.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/logo.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/network_file_system.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/profile.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/programs/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/programs/vscode.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/queues.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/secret.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/selector.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/skills.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/token.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/utils.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/volume.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cli/workspace.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/client.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/cls.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/config.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/container_process.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/container_process.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/dict.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/dict.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/environments.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/environments.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/experimental/ipython.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/file_io.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/file_io.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/file_pattern_matcher.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/functions.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/image.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/image.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/io_streams.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/io_streams.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/mount.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/mount.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/network_file_system.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/network_file_system.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/object.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/output.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/parallel_map.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/parallel_map.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/partial_function.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/partial_function.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/proxy.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/proxy.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/py.typed +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/queue.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/queue.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/retries.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/runner.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/running_app.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/sandbox_fs.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/sandbox_fs.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/schedule.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/scheduler_placement.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/secret.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/secret.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/server.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/server.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/serving.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/serving.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/skills/modal/SKILL.md +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/snapshot.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/snapshot.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/stream_type.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/token_flow.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/token_flow.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/types.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/volume.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/volume.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/workspace.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal/workspace.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal.egg-info/requires.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal.egg-info/top_level.txt +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/gen_cli_docs_main.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/gen_reference_docs_main.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/mdmd/types.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_docs/reference_intro.md +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/__init__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/py.typed +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/modal_version/__main__.py +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/pyproject.toml +0 -0
- {modal-1.5.5.dev16 → modal-1.5.6.dev0}/setup.cfg +0 -0
|
@@ -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._source_info = base_function._source_info
|
|
294
294
|
fun._spec = base_function._spec # TODO (elias): fix - this is incorrect when using with_options
|
|
295
295
|
return fun
|
|
@@ -46,10 +46,11 @@ 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
|
|
49
50
|
from ._utils.function_utils import (
|
|
50
51
|
ATTEMPT_TIMEOUT_GRACE_PERIOD,
|
|
51
52
|
OUTPUTS_TIMEOUT,
|
|
52
|
-
|
|
53
|
+
FunctionSourceInfo,
|
|
53
54
|
_create_input,
|
|
54
55
|
_parse_retries,
|
|
55
56
|
_process_result,
|
|
@@ -603,7 +604,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
603
604
|
"""
|
|
604
605
|
|
|
605
606
|
# TODO: more type annotations
|
|
606
|
-
|
|
607
|
+
_source_info: FunctionSourceInfo | None
|
|
607
608
|
_serve_mounts: frozenset[_Mount] # set at load time, only by loader
|
|
608
609
|
_app: "modal.app._App | None" = None
|
|
609
610
|
# only set for InstanceServiceFunctions and bound instance methods
|
|
@@ -664,7 +665,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
664
665
|
|
|
665
666
|
@staticmethod
|
|
666
667
|
def _from_local(
|
|
667
|
-
info:
|
|
668
|
+
info: FunctionSourceInfo,
|
|
668
669
|
app: "modal.app._App | None", # App here should only be None in case of Image.run_function
|
|
669
670
|
image: _Image,
|
|
670
671
|
env: dict[str, str | None] | None = None,
|
|
@@ -1169,7 +1170,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1169
1170
|
)
|
|
1170
1171
|
|
|
1171
1172
|
obj._raw_f = info.raw_f
|
|
1172
|
-
obj.
|
|
1173
|
+
obj._source_info = info
|
|
1173
1174
|
obj._tag = tag
|
|
1174
1175
|
obj._app = app # needed for CLI right now
|
|
1175
1176
|
obj._obj = None
|
|
@@ -1194,7 +1195,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1194
1195
|
|
|
1195
1196
|
return obj
|
|
1196
1197
|
|
|
1197
|
-
from_local =
|
|
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)
|
|
1198
1202
|
"""mdmd:hidden"""
|
|
1199
1203
|
|
|
1200
1204
|
async def _update_autoscaler(
|
|
@@ -1389,6 +1393,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1389
1393
|
)
|
|
1390
1394
|
|
|
1391
1395
|
@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
|
+
)
|
|
1392
1400
|
def tag(self) -> str:
|
|
1393
1401
|
"""mdmd:hidden"""
|
|
1394
1402
|
return self._tag_
|
|
@@ -1407,22 +1415,34 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1407
1415
|
return self._app
|
|
1408
1416
|
|
|
1409
1417
|
@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
|
+
)
|
|
1410
1422
|
def stub(self) -> "modal.app._App":
|
|
1411
1423
|
"""mdmd:hidden"""
|
|
1412
1424
|
# Deprecated soon, only for backwards compatibility
|
|
1413
1425
|
return self.app
|
|
1414
1426
|
|
|
1415
1427
|
@property
|
|
1416
|
-
|
|
1428
|
+
@with_deprecation_warning(
|
|
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:
|
|
1417
1433
|
"""mdmd:hidden"""
|
|
1418
|
-
return self.
|
|
1434
|
+
return self._source_info_
|
|
1419
1435
|
|
|
1420
1436
|
@property
|
|
1421
|
-
def
|
|
1422
|
-
assert self.
|
|
1423
|
-
return self.
|
|
1437
|
+
def _source_info_(self) -> FunctionSourceInfo:
|
|
1438
|
+
assert self._source_info
|
|
1439
|
+
return self._source_info
|
|
1424
1440
|
|
|
1425
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
|
+
)
|
|
1426
1446
|
def spec(self) -> _FunctionSpec:
|
|
1427
1447
|
"""mdmd:hidden"""
|
|
1428
1448
|
return self._spec_
|
|
@@ -1443,7 +1463,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1443
1463
|
assert hasattr(self, "_raw_f") and hasattr(self, "_build_args") and self._raw_f is not None
|
|
1444
1464
|
return f"{inspect.getsource(self._raw_f)}\n{repr(self._build_args)}"
|
|
1445
1465
|
|
|
1446
|
-
get_build_def =
|
|
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)
|
|
1447
1470
|
"""mdmd:hidden"""
|
|
1448
1471
|
|
|
1449
1472
|
# Live handle methods
|
|
@@ -1454,7 +1477,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1454
1477
|
self._is_generator = None
|
|
1455
1478
|
self._web_url = None
|
|
1456
1479
|
self._function_name = None
|
|
1457
|
-
self.
|
|
1480
|
+
self._source_info = None
|
|
1458
1481
|
self._serve_mounts = frozenset()
|
|
1459
1482
|
self._metadata = None
|
|
1460
1483
|
self._experimental_flash_urls = None
|
|
@@ -1586,7 +1609,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1586
1609
|
new_function._webhook_config = self._webhook_config
|
|
1587
1610
|
|
|
1588
1611
|
# Other fields not necessarily initialized
|
|
1589
|
-
if self.
|
|
1612
|
+
if self._source_info is not None:
|
|
1590
1613
|
new_function._build_args = self._build_args
|
|
1591
1614
|
new_function._is_method = self._is_method
|
|
1592
1615
|
new_function._raw_f = self._raw_f
|
|
@@ -1693,6 +1716,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1693
1716
|
return self._apply_dynamic_config(options, "with_batching")
|
|
1694
1717
|
|
|
1695
1718
|
@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
|
+
)
|
|
1696
1723
|
async def is_generator(self) -> bool:
|
|
1697
1724
|
"""mdmd:hidden"""
|
|
1698
1725
|
return await self._is_generator_
|
|
@@ -1888,12 +1915,12 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1888
1915
|
yield item
|
|
1889
1916
|
|
|
1890
1917
|
def _is_local(self):
|
|
1891
|
-
return self.
|
|
1918
|
+
return self._source_info is not None
|
|
1892
1919
|
|
|
1893
|
-
def
|
|
1894
|
-
if not self.
|
|
1895
|
-
raise ExecutionError("Can't get info for a function that isn't locally defined")
|
|
1896
|
-
return self.
|
|
1920
|
+
def _get_source_info(self) -> FunctionSourceInfo:
|
|
1921
|
+
if not self._source_info:
|
|
1922
|
+
raise ExecutionError("Can't get source info for a function that isn't locally defined")
|
|
1923
|
+
return self._source_info
|
|
1897
1924
|
|
|
1898
1925
|
def _get_obj(self) -> "modal.cls._Obj | None":
|
|
1899
1926
|
if not self._is_method:
|
|
@@ -1928,7 +1955,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
1928
1955
|
)
|
|
1929
1956
|
raise ExecutionError(msg)
|
|
1930
1957
|
|
|
1931
|
-
info = self.
|
|
1958
|
+
info = self._get_source_info()
|
|
1932
1959
|
if not info.raw_f:
|
|
1933
1960
|
# Here if calling .local on a service function itself which should never happen
|
|
1934
1961
|
# TODO: check if we end up here in a container for a serialized function?
|
|
@@ -2032,6 +2059,10 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
|
2032
2059
|
fc._function_id = self.object_id
|
|
2033
2060
|
return fc
|
|
2034
2061
|
|
|
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
|
+
)
|
|
2035
2066
|
def get_raw_f(self) -> Callable[..., Any]:
|
|
2036
2067
|
"""Return the inner Python object wrapped by this Modal Function.
|
|
2037
2068
|
|
|
@@ -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 FunctionSourceInfo, 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_source_info().get_globals()
|
|
685
|
+
attrs = build_function._get_source_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_source_info().function_name}. "
|
|
698
698
|
"Changes to this variable won't invalidate the image."
|
|
699
699
|
)
|
|
700
700
|
continue
|
|
@@ -2754,7 +2754,7 @@ 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 = FunctionSourceInfo(raw_f)
|
|
2758
2758
|
|
|
2759
2759
|
function = _Function._from_local(
|
|
2760
2760
|
info,
|
|
@@ -9,11 +9,11 @@ from typing import ClassVar
|
|
|
9
9
|
from google.protobuf.message import Message
|
|
10
10
|
from typing_extensions import Self
|
|
11
11
|
|
|
12
|
-
from modal._traceback import suppress_tb_frame
|
|
13
|
-
|
|
14
12
|
from ._load_context import LoadContext
|
|
15
13
|
from ._resolver import Resolver
|
|
14
|
+
from ._traceback import suppress_tb_frame
|
|
16
15
|
from ._utils.async_utils import TaskContext, aclosing
|
|
16
|
+
from ._utils.deprecation import deprecation_warning
|
|
17
17
|
from .client import _Client
|
|
18
18
|
from .config import config, logger
|
|
19
19
|
from .exception import ExecutionError, InvalidError
|
|
@@ -91,13 +91,21 @@ class _Object:
|
|
|
91
91
|
# For hydrated objects
|
|
92
92
|
_object_id: str | None
|
|
93
93
|
_client: _Client | None
|
|
94
|
-
|
|
94
|
+
__is_hydrated: bool
|
|
95
95
|
_is_rehydrated: bool
|
|
96
96
|
|
|
97
97
|
# Not all object subclasses have a meaningful "name" concept
|
|
98
98
|
# So whether they expose this is a matter of having a name property
|
|
99
99
|
_name: str | None
|
|
100
100
|
|
|
101
|
+
@property
|
|
102
|
+
def _is_hydrated(self) -> bool:
|
|
103
|
+
return self.__is_hydrated
|
|
104
|
+
|
|
105
|
+
@_is_hydrated.setter
|
|
106
|
+
def _is_hydrated(self, value: bool):
|
|
107
|
+
self.__is_hydrated = value
|
|
108
|
+
|
|
101
109
|
@classmethod
|
|
102
110
|
def __init_subclass__(cls, type_prefix: str | None = None):
|
|
103
111
|
super().__init_subclass__()
|
|
@@ -281,9 +289,18 @@ class _Object:
|
|
|
281
289
|
def __repr__(self):
|
|
282
290
|
return self._rep
|
|
283
291
|
|
|
292
|
+
@property
|
|
293
|
+
def _class_name(self):
|
|
294
|
+
return self.__class__.__name__.removeprefix("_")
|
|
295
|
+
|
|
284
296
|
@property
|
|
285
297
|
def local_uuid(self):
|
|
286
298
|
"""mdmd:hidden"""
|
|
299
|
+
deprecation_warning(
|
|
300
|
+
(2026, 8, 26),
|
|
301
|
+
f"`{self._class_name}.local_uuid` is deprecated and will be removed in `modal` version 1.6.0",
|
|
302
|
+
)
|
|
303
|
+
|
|
287
304
|
return self._local_uuid
|
|
288
305
|
|
|
289
306
|
@property
|
|
@@ -308,11 +325,21 @@ class _Object:
|
|
|
308
325
|
@property
|
|
309
326
|
def is_hydrated(self) -> bool:
|
|
310
327
|
"""mdmd:hidden"""
|
|
328
|
+
deprecation_warning(
|
|
329
|
+
(2026, 8, 26),
|
|
330
|
+
f"`{self._class_name}.is_hydrated` is deprecated and will be removed in `modal` version 1.6.0",
|
|
331
|
+
)
|
|
332
|
+
|
|
311
333
|
return self._is_hydrated
|
|
312
334
|
|
|
313
335
|
@property
|
|
314
336
|
def deps(self) -> Callable[..., Sequence["_Object"]]:
|
|
315
337
|
"""mdmd:hidden"""
|
|
338
|
+
deprecation_warning(
|
|
339
|
+
(2026, 8, 26),
|
|
340
|
+
f"`{self._class_name}.deps` is deprecated and will be removed in `modal` version 1.6.0",
|
|
341
|
+
)
|
|
342
|
+
|
|
316
343
|
return self._deps_
|
|
317
344
|
|
|
318
345
|
@property
|
|
@@ -4,7 +4,7 @@ import io
|
|
|
4
4
|
import pickle
|
|
5
5
|
import typing
|
|
6
6
|
from inspect import Parameter
|
|
7
|
-
from typing import Any
|
|
7
|
+
from typing import Any
|
|
8
8
|
|
|
9
9
|
from modal._traceback import extract_traceback
|
|
10
10
|
from modal.config import config
|
|
@@ -43,11 +43,8 @@ class Pickler(cloudpickle.Pickler):
|
|
|
43
43
|
|
|
44
44
|
if isinstance(obj, _Object):
|
|
45
45
|
flag = "_o"
|
|
46
|
-
is_hydrated = obj._is_hydrated
|
|
47
46
|
elif isinstance(obj, Object):
|
|
48
47
|
flag = "o"
|
|
49
|
-
inner = cast(_Object, synchronizer._translate_in(obj))
|
|
50
|
-
is_hydrated = inner._is_hydrated
|
|
51
48
|
elif isinstance(obj, PartialFunction):
|
|
52
49
|
# Special case for PartialObject since it's a synchronicity wrapped object
|
|
53
50
|
# that's set on serialized classes.
|
|
@@ -70,7 +67,7 @@ class Pickler(cloudpickle.Pickler):
|
|
|
70
67
|
else:
|
|
71
68
|
return
|
|
72
69
|
|
|
73
|
-
if not
|
|
70
|
+
if not obj._is_hydrated:
|
|
74
71
|
raise InvalidError(f"Can't serialize object {obj} which hasn't been hydrated.")
|
|
75
72
|
|
|
76
73
|
return (obj.object_id, flag, obj._get_metadata())
|
|
@@ -118,3 +118,32 @@ def handle_deprecated_parameters(func: Callable[P, R]) -> Callable[P, R]:
|
|
|
118
118
|
return func(*args, **kwargs)
|
|
119
119
|
|
|
120
120
|
return wrapper
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def with_deprecation_warning(
|
|
124
|
+
deprecated_on: tuple[int, int, int], msg: str, *, show_source: bool = True
|
|
125
|
+
) -> Callable[[Callable[P, R]], Callable[P, R]]:
|
|
126
|
+
def decorator(method: Callable[P, R]) -> Callable[P, R]:
|
|
127
|
+
is_static = False
|
|
128
|
+
if isinstance(method, staticmethod):
|
|
129
|
+
is_static = True
|
|
130
|
+
method = method.__wrapped__
|
|
131
|
+
|
|
132
|
+
# Note: despite `wrapped` being synchronous, this also works with async functions, in that if
|
|
133
|
+
# a function returns a coroutine, then this function will also return a coroutine. So, when
|
|
134
|
+
# called from an async context, the return can be awaited without issues. However, code that
|
|
135
|
+
# introspects `wrapped` with, e.g. inspect.iscoroutinefunction(), will not pick up on the
|
|
136
|
+
# fact that it returns a coroutine unless it unwraps `wrapped` and tries to introspect `method`
|
|
137
|
+
# directly. Synchronicity already does this (https://github.com/modal-labs/synchronicity/blob/441085df7dfa953c86304d06da5e0e74cebbe858/src/synchronicity/async_wrap.py#L42-L57),
|
|
138
|
+
# but this is fixable on Python >= 3.12, which adds `inspect.markcoroutinefunction`.
|
|
139
|
+
@functools.wraps(method)
|
|
140
|
+
def wrapped(*args: P.args, **kwargs: P.kwargs) -> R:
|
|
141
|
+
deprecation_warning(deprecated_on, msg, show_source=show_source)
|
|
142
|
+
return method(*args, **kwargs)
|
|
143
|
+
|
|
144
|
+
if is_static:
|
|
145
|
+
return staticmethod(wrapped)
|
|
146
|
+
|
|
147
|
+
return wrapped
|
|
148
|
+
|
|
149
|
+
return decorator
|
|
@@ -48,7 +48,7 @@ if typing.TYPE_CHECKING:
|
|
|
48
48
|
import modal._functions
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
class
|
|
51
|
+
class FunctionSourceInfoType(Enum):
|
|
52
52
|
PACKAGE = "package"
|
|
53
53
|
FILE = "file"
|
|
54
54
|
SERIALIZED = "serialized"
|
|
@@ -162,7 +162,7 @@ def _parse_retries(
|
|
|
162
162
|
raise InvalidError(msg)
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
class
|
|
165
|
+
class FunctionSourceInfo:
|
|
166
166
|
"""Utility that determines serialization/deserialization mechanisms for functions
|
|
167
167
|
|
|
168
168
|
* Stored as file vs serialized
|
|
@@ -178,7 +178,7 @@ class FunctionInfo:
|
|
|
178
178
|
user_cls: type[Any] | None
|
|
179
179
|
module_name: str | None
|
|
180
180
|
|
|
181
|
-
_type:
|
|
181
|
+
_type: FunctionSourceInfoType
|
|
182
182
|
_file: str | None
|
|
183
183
|
_base_dir: str
|
|
184
184
|
_remote_dir: PurePosixPath | None = None
|
|
@@ -245,7 +245,7 @@ class FunctionInfo:
|
|
|
245
245
|
self.module_name = module.__spec__.name
|
|
246
246
|
self._remote_dir = ROOT_DIR / PurePosixPath(module.__package__.split(".")[0])
|
|
247
247
|
self._is_serialized = False
|
|
248
|
-
self._type =
|
|
248
|
+
self._type = FunctionSourceInfoType.PACKAGE
|
|
249
249
|
elif hasattr(module, "__file__") and not serialized:
|
|
250
250
|
# This generally covers the case where it's invoked with
|
|
251
251
|
# python foo/bar/baz.py
|
|
@@ -255,16 +255,16 @@ class FunctionInfo:
|
|
|
255
255
|
self.module_name = inspect.getmodulename(self._file)
|
|
256
256
|
self._base_dir = os.path.dirname(self._file)
|
|
257
257
|
self._is_serialized = False
|
|
258
|
-
self._type =
|
|
258
|
+
self._type = FunctionSourceInfoType.FILE
|
|
259
259
|
else:
|
|
260
260
|
self.module_name = None
|
|
261
261
|
self._base_dir = os.path.abspath("") # get current dir
|
|
262
262
|
self._is_serialized = True # either explicitly, or by being in a notebook
|
|
263
263
|
if serialized: # if explicit
|
|
264
|
-
self._type =
|
|
264
|
+
self._type = FunctionSourceInfoType.SERIALIZED
|
|
265
265
|
else:
|
|
266
266
|
# notebook, or in general any exec() on a function definition
|
|
267
|
-
self._type =
|
|
267
|
+
self._type = FunctionSourceInfoType.NOTEBOOK
|
|
268
268
|
|
|
269
269
|
if not self.is_serialized():
|
|
270
270
|
# Sanity check that this function is defined in global scope
|
|
@@ -372,14 +372,14 @@ class FunctionInfo:
|
|
|
372
372
|
return {}
|
|
373
373
|
|
|
374
374
|
# make sure the function's own entrypoint is included:
|
|
375
|
-
if self._type ==
|
|
375
|
+
if self._type == FunctionSourceInfoType.PACKAGE:
|
|
376
376
|
top_level_package = self.module_name.split(".")[0]
|
|
377
377
|
# TODO: add deprecation warning if the following entrypoint mount
|
|
378
378
|
# includes non-.py files, since we'll want to migrate to .py-only
|
|
379
379
|
# soon to get it consistent with the `add_local_python_source()`
|
|
380
380
|
# defaults.
|
|
381
381
|
return {top_level_package: _Mount._from_local_python_packages(top_level_package)}
|
|
382
|
-
elif self._type ==
|
|
382
|
+
elif self._type == FunctionSourceInfoType.FILE:
|
|
383
383
|
# TODO: inspect if this file is already included as part of
|
|
384
384
|
# a package mount, and skip it + reference that package
|
|
385
385
|
# instead if that's the case. This avoids possible module
|
|
@@ -33,12 +33,9 @@ from ._partial_function import (
|
|
|
33
33
|
from ._server import _Server, validate_http_server_config
|
|
34
34
|
from ._supports_logs import _LogQueryData
|
|
35
35
|
from ._utils.async_utils import synchronize_api
|
|
36
|
-
from ._utils.deprecation import
|
|
37
|
-
deprecation_warning,
|
|
38
|
-
handle_deprecated_parameters,
|
|
39
|
-
)
|
|
36
|
+
from ._utils.deprecation import deprecation_warning, handle_deprecated_parameters, with_deprecation_warning
|
|
40
37
|
from ._utils.function_utils import (
|
|
41
|
-
|
|
38
|
+
FunctionSourceInfo,
|
|
42
39
|
is_flash_object,
|
|
43
40
|
is_global_object,
|
|
44
41
|
is_method_fn,
|
|
@@ -65,10 +62,10 @@ _default_image: _Image = _Image.debian_slim()
|
|
|
65
62
|
|
|
66
63
|
|
|
67
64
|
class _LocalEntrypoint:
|
|
68
|
-
_info:
|
|
65
|
+
_info: FunctionSourceInfo
|
|
69
66
|
_app: "_App"
|
|
70
67
|
|
|
71
|
-
def __init__(self, info:
|
|
68
|
+
def __init__(self, info: FunctionSourceInfo, app: "_App") -> None:
|
|
72
69
|
self._info = info
|
|
73
70
|
self._app = app
|
|
74
71
|
|
|
@@ -76,7 +73,7 @@ class _LocalEntrypoint:
|
|
|
76
73
|
return self._info.raw_f(*args, **kwargs)
|
|
77
74
|
|
|
78
75
|
@property
|
|
79
|
-
def info(self) ->
|
|
76
|
+
def info(self) -> FunctionSourceInfo:
|
|
80
77
|
return self._info
|
|
81
78
|
|
|
82
79
|
@property
|
|
@@ -274,6 +271,10 @@ class _App:
|
|
|
274
271
|
return self._name
|
|
275
272
|
|
|
276
273
|
@property
|
|
274
|
+
@with_deprecation_warning(
|
|
275
|
+
(2026, 8, 26),
|
|
276
|
+
"`App.is_interactive` is deprecated and will be removed in `modal` version 1.6.0",
|
|
277
|
+
)
|
|
277
278
|
def is_interactive(self) -> bool:
|
|
278
279
|
"""mdmd:hidden"""
|
|
279
280
|
return self._is_interactive_
|
|
@@ -383,6 +384,11 @@ class _App:
|
|
|
383
384
|
raise InvalidError("App is not running")
|
|
384
385
|
return f"https://modal.com/id/{self._app_id}"
|
|
385
386
|
|
|
387
|
+
@with_deprecation_warning(
|
|
388
|
+
(2026, 8, 26),
|
|
389
|
+
"`App.set_description` is deprecated and will be removed in `modal` version 1.6.0. "
|
|
390
|
+
"Set `App.description` directly instead",
|
|
391
|
+
)
|
|
386
392
|
def set_description(self, description: str):
|
|
387
393
|
"""mdmd:hidden
|
|
388
394
|
Set the description of the App before it starts running.
|
|
@@ -396,6 +402,10 @@ class _App:
|
|
|
396
402
|
raise InvalidError(f"App attribute `{key}` with value {value!r} is not a valid Modal object")
|
|
397
403
|
|
|
398
404
|
@property
|
|
405
|
+
@with_deprecation_warning(
|
|
406
|
+
(2026, 8, 26),
|
|
407
|
+
"`App.image` is deprecated and will be removed in `modal` version 1.6.0",
|
|
408
|
+
)
|
|
399
409
|
def image(self) -> _Image:
|
|
400
410
|
"""mdmd:hidden
|
|
401
411
|
Retrieve the Image that will be used as the default for any Functions registered to the App.
|
|
@@ -617,8 +627,8 @@ class _App:
|
|
|
617
627
|
logger.warning(
|
|
618
628
|
f"Warning: function name '{function._tag_}' collision!"
|
|
619
629
|
" Overriding existing function "
|
|
620
|
-
f"[{old_function.
|
|
621
|
-
f" with new function [{function.
|
|
630
|
+
f"[{old_function._source_info.module_name}].{old_function._source_info.function_name}"
|
|
631
|
+
f" with new function [{function._source_info.module_name}].{function._source_info.function_name}"
|
|
622
632
|
)
|
|
623
633
|
if function._tag_ in local_state.classes:
|
|
624
634
|
logger.warning(f"Warning: tag {function._tag_} exists but is overridden by function")
|
|
@@ -668,6 +678,10 @@ class _App:
|
|
|
668
678
|
obj._hydrate(object_id, client, handle_metadata)
|
|
669
679
|
|
|
670
680
|
@property
|
|
681
|
+
@with_deprecation_warning(
|
|
682
|
+
(2026, 8, 26),
|
|
683
|
+
"`App.registered_functions` is deprecated and will be removed in `modal` version 1.6.0",
|
|
684
|
+
)
|
|
671
685
|
def registered_functions(self) -> dict[str, _Function]:
|
|
672
686
|
"""mdmd:hidden
|
|
673
687
|
All modal.Function objects registered on the app.
|
|
@@ -680,6 +694,10 @@ class _App:
|
|
|
680
694
|
return self._local_state.functions
|
|
681
695
|
|
|
682
696
|
@property
|
|
697
|
+
@with_deprecation_warning(
|
|
698
|
+
(2026, 8, 26),
|
|
699
|
+
"`App.registered_classes` is deprecated and will be removed in `modal` version 1.6.0",
|
|
700
|
+
)
|
|
683
701
|
def registered_classes(self) -> dict[str, _Cls]:
|
|
684
702
|
"""mdmd:hidden
|
|
685
703
|
All modal.Cls objects registered on the app.
|
|
@@ -692,6 +710,10 @@ class _App:
|
|
|
692
710
|
return self._local_state.classes
|
|
693
711
|
|
|
694
712
|
@property
|
|
713
|
+
@with_deprecation_warning(
|
|
714
|
+
(2026, 8, 26),
|
|
715
|
+
"`App.registered_entrypoints` is deprecated and will be removed in `modal` version 1.6.0",
|
|
716
|
+
)
|
|
695
717
|
def registered_entrypoints(self) -> dict[str, _LocalEntrypoint]:
|
|
696
718
|
"""mdmd:hidden
|
|
697
719
|
All local CLI entrypoints registered on the app.
|
|
@@ -703,6 +725,10 @@ class _App:
|
|
|
703
725
|
return self._local_state.local_entrypoints
|
|
704
726
|
|
|
705
727
|
@property
|
|
728
|
+
@with_deprecation_warning(
|
|
729
|
+
(2026, 8, 26),
|
|
730
|
+
"`App.registered_web_endpoints` is deprecated and will be removed in `modal` version 1.6.0",
|
|
731
|
+
)
|
|
706
732
|
def registered_web_endpoints(self) -> list[str]:
|
|
707
733
|
"""mdmd:hidden
|
|
708
734
|
Names of Web Functions registered on the app.
|
|
@@ -777,7 +803,7 @@ class _App:
|
|
|
777
803
|
raise InvalidError("Invalid value for `name`: Must be string.")
|
|
778
804
|
|
|
779
805
|
def wrapped(raw_f: Callable[..., Any]) -> _LocalEntrypoint:
|
|
780
|
-
info =
|
|
806
|
+
info = FunctionSourceInfo(raw_f)
|
|
781
807
|
tag = name if name is not None else raw_f.__qualname__
|
|
782
808
|
local_state = self._local_state
|
|
783
809
|
if tag in local_state.local_entrypoints:
|
|
@@ -936,7 +962,7 @@ class _App:
|
|
|
936
962
|
rdma = f.params.rdma
|
|
937
963
|
fabric_size = f.params.fabric_size
|
|
938
964
|
|
|
939
|
-
info =
|
|
965
|
+
info = FunctionSourceInfo(f.raw_f, serialized=serialized, name_override=name)
|
|
940
966
|
raw_f = f.raw_f
|
|
941
967
|
webhook_config = f.params.webhook_config
|
|
942
968
|
is_generator = f.params.is_generator
|
|
@@ -979,7 +1005,7 @@ class _App:
|
|
|
979
1005
|
)
|
|
980
1006
|
)
|
|
981
1007
|
|
|
982
|
-
info =
|
|
1008
|
+
info = FunctionSourceInfo(f, serialized=serialized, name_override=name)
|
|
983
1009
|
raw_f = f
|
|
984
1010
|
webhook_config = None
|
|
985
1011
|
batch_max_size = None
|
|
@@ -1228,7 +1254,7 @@ class _App:
|
|
|
1228
1254
|
).values():
|
|
1229
1255
|
raise InvalidError("Callable decorators cannot be combined with web interface decorators.")
|
|
1230
1256
|
|
|
1231
|
-
info =
|
|
1257
|
+
info = FunctionSourceInfo(None, serialized=serialized, user_cls=user_cls)
|
|
1232
1258
|
|
|
1233
1259
|
i6pn_enabled = i6pn or cluster_size is not None
|
|
1234
1260
|
cls_func = _Function._from_local(
|
|
@@ -1440,7 +1466,9 @@ class _App:
|
|
|
1440
1466
|
local_state = self._local_state
|
|
1441
1467
|
|
|
1442
1468
|
# Create the FunctionInfo for the server, note we treat FunctionInfo as a class for servers
|
|
1443
|
-
info =
|
|
1469
|
+
info = FunctionSourceInfo(
|
|
1470
|
+
None, serialized=serialized, user_cls=user_cls, name_override=name or user_cls.__name__
|
|
1471
|
+
)
|
|
1444
1472
|
# Create the service function
|
|
1445
1473
|
service_function = _Function._from_local(
|
|
1446
1474
|
info,
|
|
@@ -27,10 +27,10 @@ import typing
|
|
|
27
27
|
import typing_extensions
|
|
28
28
|
|
|
29
29
|
class _LocalEntrypoint:
|
|
30
|
-
_info: modal._utils.function_utils.
|
|
30
|
+
_info: modal._utils.function_utils.FunctionSourceInfo
|
|
31
31
|
_app: _App
|
|
32
32
|
|
|
33
|
-
def __init__(self, info: modal._utils.function_utils.
|
|
33
|
+
def __init__(self, info: modal._utils.function_utils.FunctionSourceInfo, app: _App) -> None:
|
|
34
34
|
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
35
35
|
...
|
|
36
36
|
|
|
@@ -39,18 +39,18 @@ class _LocalEntrypoint:
|
|
|
39
39
|
...
|
|
40
40
|
|
|
41
41
|
@property
|
|
42
|
-
def info(self) -> modal._utils.function_utils.
|
|
42
|
+
def info(self) -> modal._utils.function_utils.FunctionSourceInfo: ...
|
|
43
43
|
@property
|
|
44
44
|
def app(self) -> _App: ...
|
|
45
45
|
|
|
46
46
|
class LocalEntrypoint:
|
|
47
|
-
_info: modal._utils.function_utils.
|
|
47
|
+
_info: modal._utils.function_utils.FunctionSourceInfo
|
|
48
48
|
_app: App
|
|
49
49
|
|
|
50
|
-
def __init__(self, info: modal._utils.function_utils.
|
|
50
|
+
def __init__(self, info: modal._utils.function_utils.FunctionSourceInfo, app: App) -> None: ...
|
|
51
51
|
def __call__(self, *args: typing.Any, **kwargs: typing.Any) -> typing.Any: ...
|
|
52
52
|
@property
|
|
53
|
-
def info(self) -> modal._utils.function_utils.
|
|
53
|
+
def info(self) -> modal._utils.function_utils.FunctionSourceInfo: ...
|
|
54
54
|
@property
|
|
55
55
|
def app(self) -> App: ...
|
|
56
56
|
|
|
@@ -173,7 +173,7 @@ def list_cli_commands(
|
|
|
173
173
|
priorities[local_entrypoint] = AutoRunPriority.APP_LOCAL_ENTRYPOINT
|
|
174
174
|
for name, inner_function in app._local_state.functions.items():
|
|
175
175
|
function = cast(Function, synchronizer._translate_out(inner_function))
|
|
176
|
-
if function.
|
|
176
|
+
if function._source_info_.is_service_class() and not include_service_functions:
|
|
177
177
|
continue # Skip class and server service functions for all commands except `modal shell`.
|
|
178
178
|
all_runnables[function].append(f"{app_name}.{name}")
|
|
179
179
|
priorities[function] = AutoRunPriority.APP_FUNCTION
|