modal 1.1.2.dev37__tar.gz → 1.1.2.dev41__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.1.2.dev37 → modal-1.1.2.dev41}/PKG-INFO +1 -1
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_container_entrypoint.py +6 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_functions.py +2 -2
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/asgi.py +3 -2
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/container_io_manager.py +9 -4
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/container_io_manager.pyi +32 -9
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/function_utils.py +4 -3
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/app.py +2 -2
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/app.pyi +4 -4
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/client.pyi +2 -2
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/functions.pyi +7 -7
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/image.py +1 -1
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/image.pyi +2 -2
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/sandbox.py +3 -3
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/sandbox.pyi +8 -8
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/volume.py +6 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/volume.pyi +3 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_version/__init__.py +1 -1
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/LICENSE +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/README.md +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/__main__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_clustered_functions.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_clustered_functions.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_ipython.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_location.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_object.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_output.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_partial_function.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_pty.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_resolver.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_resources.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/execution_context.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/telemetry.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_serialization.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_traceback.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_tunnel.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_tunnel.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_type_manager.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/app_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/async_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/blob_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/deprecation.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/docker_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/git_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/hash_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/http_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/logger.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/mount_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/name_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/package_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/shell_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_utils/time_utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_vendor/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_vendor/tblib.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/_watcher.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/2023.12.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/2024.04.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/2024.10.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/2025.06.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/README.md +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/builder/base-images.json +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/call_graph.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/_download.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/_traceback.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/app.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/cluster.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/config.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/container.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/dict.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/entry_point.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/environment.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/import_refs.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/launch.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/network_file_system.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/profile.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/programs/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/programs/vscode.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/queues.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/run.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/secret.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/token.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/utils.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cli/volume.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/client.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cls.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/cls.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/config.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/container_process.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/container_process.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/dict.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/dict.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/environments.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/environments.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/exception.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/experimental/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/experimental/flash.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/experimental/flash.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/experimental/ipython.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/file_io.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/file_io.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/file_pattern_matcher.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/functions.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/gpu.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/io_streams.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/io_streams.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/mount.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/mount.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/network_file_system.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/network_file_system.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/object.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/object.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/output.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/parallel_map.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/parallel_map.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/partial_function.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/partial_function.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/proxy.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/proxy.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/py.typed +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/queue.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/queue.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/retries.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/runner.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/runner.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/running_app.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/schedule.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/scheduler_placement.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/secret.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/secret.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/serving.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/serving.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/snapshot.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/snapshot.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/stream_type.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/token_flow.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal/token_flow.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal.egg-info/requires.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal.egg-info/top_level.txt +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_docs/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/__init__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/api.proto +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/api_grpc.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/api_pb2.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/modal_options_grpc.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/options.proto +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/options_grpc.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/options_pb2.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/options_pb2.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/options_pb2_grpc.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/options_pb2_grpc.pyi +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_proto/py.typed +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/modal_version/__main__.py +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/pyproject.toml +0 -0
- {modal-1.1.2.dev37 → modal-1.1.2.dev41}/setup.cfg +0 -0
@@ -198,9 +198,12 @@ def call_function(
|
|
198
198
|
# Send up to this many outputs at a time.
|
199
199
|
current_function_call_id = execution_context.current_function_call_id()
|
200
200
|
assert current_function_call_id is not None # Set above.
|
201
|
+
current_attempt_token = execution_context.current_attempt_token()
|
202
|
+
assert current_attempt_token is not None # Set above, but can be empty string.
|
201
203
|
generator_queue: asyncio.Queue[Any] = await container_io_manager._queue_create.aio(1024)
|
202
204
|
async with container_io_manager.generator_output_sender(
|
203
205
|
current_function_call_id,
|
206
|
+
current_attempt_token,
|
204
207
|
io_context.finalized_function.data_format,
|
205
208
|
generator_queue,
|
206
209
|
):
|
@@ -247,9 +250,12 @@ def call_function(
|
|
247
250
|
# Send up to this many outputs at a time.
|
248
251
|
current_function_call_id = execution_context.current_function_call_id()
|
249
252
|
assert current_function_call_id is not None # Set above.
|
253
|
+
current_attempt_token = execution_context.current_attempt_token()
|
254
|
+
assert current_attempt_token is not None # Set above, but can be empty string.
|
250
255
|
generator_queue: asyncio.Queue[Any] = container_io_manager._queue_create(1024)
|
251
256
|
with container_io_manager.generator_output_sender(
|
252
257
|
current_function_call_id,
|
258
|
+
current_attempt_token,
|
253
259
|
io_context.finalized_function.data_format,
|
254
260
|
generator_queue,
|
255
261
|
):
|
@@ -473,7 +473,7 @@ class _InputPlaneInvocation:
|
|
473
473
|
_stream_function_call_data(
|
474
474
|
self.client,
|
475
475
|
self.stub,
|
476
|
-
|
476
|
+
function_call_id=None,
|
477
477
|
variant="data_out",
|
478
478
|
attempt_token=self.attempt_token,
|
479
479
|
),
|
@@ -614,7 +614,7 @@ class _Function(typing.Generic[P, ReturnType, OriginalReturnType], _Object, type
|
|
614
614
|
memory: Optional[Union[int, tuple[int, int]]] = None,
|
615
615
|
proxy: Optional[_Proxy] = None,
|
616
616
|
retries: Optional[Union[int, Retries]] = None,
|
617
|
-
timeout:
|
617
|
+
timeout: int = 300,
|
618
618
|
min_containers: Optional[int] = None,
|
619
619
|
max_containers: Optional[int] = None,
|
620
620
|
buffer_containers: Optional[int] = None,
|
@@ -16,7 +16,7 @@ from modal.config import logger
|
|
16
16
|
from modal.exception import ExecutionError, InvalidError
|
17
17
|
from modal.experimental import stop_fetching_inputs
|
18
18
|
|
19
|
-
from .execution_context import current_function_call_id
|
19
|
+
from .execution_context import current_attempt_token, current_function_call_id
|
20
20
|
|
21
21
|
FIRST_MESSAGE_TIMEOUT_SECONDS = 5.0
|
22
22
|
|
@@ -106,6 +106,7 @@ def asgi_app_wrapper(asgi_app, container_io_manager) -> tuple[Callable[..., Asyn
|
|
106
106
|
raise ExecutionError("Unpexected state in ASGI scope")
|
107
107
|
scope["state"] = state
|
108
108
|
function_call_id = current_function_call_id()
|
109
|
+
attempt_token = current_attempt_token()
|
109
110
|
assert function_call_id, "internal error: function_call_id not set in asgi_app() scope"
|
110
111
|
|
111
112
|
messages_from_app: asyncio.Queue[dict[str, Any]] = asyncio.Queue(1)
|
@@ -142,7 +143,7 @@ def asgi_app_wrapper(asgi_app, container_io_manager) -> tuple[Callable[..., Asyn
|
|
142
143
|
# This initial message, "http.request" or "websocket.connect", should be sent
|
143
144
|
# immediately after starting the ASGI app's function call. If it is not received, that
|
144
145
|
# indicates a request cancellation or other abnormal circumstance.
|
145
|
-
message_gen = container_io_manager.get_data_in.aio(function_call_id)
|
146
|
+
message_gen = container_io_manager.get_data_in.aio(function_call_id, attempt_token)
|
146
147
|
first_message_task = asyncio.create_task(message_gen.__anext__())
|
147
148
|
|
148
149
|
try:
|
@@ -483,18 +483,21 @@ class _ContainerIOManager:
|
|
483
483
|
else {"data": data}
|
484
484
|
)
|
485
485
|
|
486
|
-
async def get_data_in(self, function_call_id: str) -> AsyncIterator[Any]:
|
486
|
+
async def get_data_in(self, function_call_id: str, attempt_token: Optional[str]) -> AsyncIterator[Any]:
|
487
487
|
"""Read from the `data_in` stream of a function call."""
|
488
488
|
stub = self._client.stub
|
489
489
|
if self.input_plane_server_url:
|
490
490
|
stub = await self._client.get_stub(self.input_plane_server_url)
|
491
491
|
|
492
|
-
async for data in _stream_function_call_data(
|
492
|
+
async for data in _stream_function_call_data(
|
493
|
+
self._client, stub, function_call_id, variant="data_in", attempt_token=attempt_token
|
494
|
+
):
|
493
495
|
yield data
|
494
496
|
|
495
497
|
async def put_data_out(
|
496
498
|
self,
|
497
499
|
function_call_id: str,
|
500
|
+
attempt_token: str,
|
498
501
|
start_index: int,
|
499
502
|
data_format: int,
|
500
503
|
serialized_messages: list[Any],
|
@@ -515,6 +518,8 @@ class _ContainerIOManager:
|
|
515
518
|
data_chunks.append(chunk)
|
516
519
|
|
517
520
|
req = api_pb2.FunctionCallPutDataRequest(function_call_id=function_call_id, data_chunks=data_chunks)
|
521
|
+
if attempt_token:
|
522
|
+
req.attempt_token = attempt_token # oneof clears function_call_id.
|
518
523
|
|
519
524
|
if self.input_plane_server_url:
|
520
525
|
stub = await self._client.get_stub(self.input_plane_server_url)
|
@@ -524,7 +529,7 @@ class _ContainerIOManager:
|
|
524
529
|
|
525
530
|
@asynccontextmanager
|
526
531
|
async def generator_output_sender(
|
527
|
-
self, function_call_id: str, data_format: int, message_rx: asyncio.Queue
|
532
|
+
self, function_call_id: str, attempt_token: str, data_format: int, message_rx: asyncio.Queue
|
528
533
|
) -> AsyncGenerator[None, None]:
|
529
534
|
"""Runs background task that feeds generator outputs into a function call's `data_out` stream."""
|
530
535
|
GENERATOR_STOP_SENTINEL = Sentinel()
|
@@ -553,7 +558,7 @@ class _ContainerIOManager:
|
|
553
558
|
else:
|
554
559
|
serialized_messages.append(serialize_data_format(message, data_format))
|
555
560
|
total_size += len(serialized_messages[-1]) + 512 # 512 bytes for estimated framing overhead
|
556
|
-
await self.put_data_out(function_call_id, index, data_format, serialized_messages)
|
561
|
+
await self.put_data_out(function_call_id, attempt_token, index, data_format, serialized_messages)
|
557
562
|
index += len(serialized_messages)
|
558
563
|
|
559
564
|
task = asyncio.create_task(generator_output_task())
|
@@ -135,12 +135,19 @@ class _ContainerIOManager:
|
|
135
135
|
async def _dynamic_concurrency_loop(self): ...
|
136
136
|
def serialize_data_format(self, obj: typing.Any, data_format: int) -> bytes: ...
|
137
137
|
async def format_blob_data(self, data: bytes) -> dict[str, typing.Any]: ...
|
138
|
-
def get_data_in(
|
138
|
+
def get_data_in(
|
139
|
+
self, function_call_id: str, attempt_token: typing.Optional[str]
|
140
|
+
) -> collections.abc.AsyncIterator[typing.Any]:
|
139
141
|
"""Read from the `data_in` stream of a function call."""
|
140
142
|
...
|
141
143
|
|
142
144
|
async def put_data_out(
|
143
|
-
self,
|
145
|
+
self,
|
146
|
+
function_call_id: str,
|
147
|
+
attempt_token: str,
|
148
|
+
start_index: int,
|
149
|
+
data_format: int,
|
150
|
+
serialized_messages: list[typing.Any],
|
144
151
|
) -> None:
|
145
152
|
"""Put data onto the `data_out` stream of a function call.
|
146
153
|
|
@@ -151,7 +158,7 @@ class _ContainerIOManager:
|
|
151
158
|
...
|
152
159
|
|
153
160
|
def generator_output_sender(
|
154
|
-
self, function_call_id: str, data_format: int, message_rx: asyncio.queues.Queue
|
161
|
+
self, function_call_id: str, attempt_token: str, data_format: int, message_rx: asyncio.queues.Queue
|
155
162
|
) -> typing.AsyncContextManager[None]:
|
156
163
|
"""Runs background task that feeds generator outputs into a function call's `data_out` stream."""
|
157
164
|
...
|
@@ -334,11 +341,15 @@ class ContainerIOManager:
|
|
334
341
|
format_blob_data: __format_blob_data_spec[typing_extensions.Self]
|
335
342
|
|
336
343
|
class __get_data_in_spec(typing_extensions.Protocol[SUPERSELF]):
|
337
|
-
def __call__(
|
344
|
+
def __call__(
|
345
|
+
self, /, function_call_id: str, attempt_token: typing.Optional[str]
|
346
|
+
) -> typing.Iterator[typing.Any]:
|
338
347
|
"""Read from the `data_in` stream of a function call."""
|
339
348
|
...
|
340
349
|
|
341
|
-
def aio(
|
350
|
+
def aio(
|
351
|
+
self, /, function_call_id: str, attempt_token: typing.Optional[str]
|
352
|
+
) -> collections.abc.AsyncIterator[typing.Any]:
|
342
353
|
"""Read from the `data_in` stream of a function call."""
|
343
354
|
...
|
344
355
|
|
@@ -346,7 +357,13 @@ class ContainerIOManager:
|
|
346
357
|
|
347
358
|
class __put_data_out_spec(typing_extensions.Protocol[SUPERSELF]):
|
348
359
|
def __call__(
|
349
|
-
self,
|
360
|
+
self,
|
361
|
+
/,
|
362
|
+
function_call_id: str,
|
363
|
+
attempt_token: str,
|
364
|
+
start_index: int,
|
365
|
+
data_format: int,
|
366
|
+
serialized_messages: list[typing.Any],
|
350
367
|
) -> None:
|
351
368
|
"""Put data onto the `data_out` stream of a function call.
|
352
369
|
|
@@ -357,7 +374,13 @@ class ContainerIOManager:
|
|
357
374
|
...
|
358
375
|
|
359
376
|
async def aio(
|
360
|
-
self,
|
377
|
+
self,
|
378
|
+
/,
|
379
|
+
function_call_id: str,
|
380
|
+
attempt_token: str,
|
381
|
+
start_index: int,
|
382
|
+
data_format: int,
|
383
|
+
serialized_messages: list[typing.Any],
|
361
384
|
) -> None:
|
362
385
|
"""Put data onto the `data_out` stream of a function call.
|
363
386
|
|
@@ -371,13 +394,13 @@ class ContainerIOManager:
|
|
371
394
|
|
372
395
|
class __generator_output_sender_spec(typing_extensions.Protocol[SUPERSELF]):
|
373
396
|
def __call__(
|
374
|
-
self, /, function_call_id: str, data_format: int, message_rx: asyncio.queues.Queue
|
397
|
+
self, /, function_call_id: str, attempt_token: str, data_format: int, message_rx: asyncio.queues.Queue
|
375
398
|
) -> synchronicity.combined_types.AsyncAndBlockingContextManager[None]:
|
376
399
|
"""Runs background task that feeds generator outputs into a function call's `data_out` stream."""
|
377
400
|
...
|
378
401
|
|
379
402
|
def aio(
|
380
|
-
self, /, function_call_id: str, data_format: int, message_rx: asyncio.queues.Queue
|
403
|
+
self, /, function_call_id: str, attempt_token: str, data_format: int, message_rx: asyncio.queues.Queue
|
381
404
|
) -> typing.AsyncContextManager[None]:
|
382
405
|
"""Runs background task that feeds generator outputs into a function call's `data_out` stream."""
|
383
406
|
...
|
@@ -392,8 +392,8 @@ async def _stream_function_call_data(
|
|
392
392
|
attempt_token: Optional[str] = None,
|
393
393
|
) -> AsyncGenerator[Any, None]:
|
394
394
|
"""Read from the `data_in` or `data_out` stream of a function call."""
|
395
|
-
if function_call_id
|
396
|
-
raise ValueError("function_call_id or attempt_token is required
|
395
|
+
if not function_call_id and not attempt_token:
|
396
|
+
raise ValueError("function_call_id or attempt_token is required to read from a data stream")
|
397
397
|
|
398
398
|
if stub is None:
|
399
399
|
stub = client.stub
|
@@ -415,8 +415,9 @@ async def _stream_function_call_data(
|
|
415
415
|
req = api_pb2.FunctionCallGetDataRequest(
|
416
416
|
function_call_id=function_call_id,
|
417
417
|
last_index=last_index,
|
418
|
-
attempt_token=attempt_token,
|
419
418
|
)
|
419
|
+
if attempt_token:
|
420
|
+
req.attempt_token = attempt_token # oneof clears function_call_id.
|
420
421
|
try:
|
421
422
|
async for chunk in stub_fn.unary_stream(req):
|
422
423
|
if chunk.index <= last_index:
|
@@ -641,7 +641,7 @@ class _App:
|
|
641
641
|
scaledown_window: Optional[int] = None, # Max time (in seconds) a container can remain idle while scaling down.
|
642
642
|
proxy: Optional[_Proxy] = None, # Reference to a Modal Proxy to use in front of this function.
|
643
643
|
retries: Optional[Union[int, Retries]] = None, # Number of times to retry each input in case of failure.
|
644
|
-
timeout:
|
644
|
+
timeout: int = 300, # Maximum execution time of the function in seconds.
|
645
645
|
name: Optional[str] = None, # Sets the Modal name of the function within the app
|
646
646
|
is_generator: Optional[
|
647
647
|
bool
|
@@ -869,7 +869,7 @@ class _App:
|
|
869
869
|
scaledown_window: Optional[int] = None, # Max time (in seconds) a container can remain idle while scaling down.
|
870
870
|
proxy: Optional[_Proxy] = None, # Reference to a Modal Proxy to use in front of this function.
|
871
871
|
retries: Optional[Union[int, Retries]] = None, # Number of times to retry each input in case of failure.
|
872
|
-
timeout:
|
872
|
+
timeout: int = 300, # Maximum execution time of the function in seconds.
|
873
873
|
cloud: Optional[str] = None, # Cloud provider to run the function on. Possible values are aws, gcp, oci, auto.
|
874
874
|
region: Optional[Union[str, Sequence[str]]] = None, # Region or regions to run the function on.
|
875
875
|
enable_memory_snapshot: bool = False, # Enable memory checkpointing for faster cold starts.
|
@@ -410,7 +410,7 @@ class _App:
|
|
410
410
|
scaledown_window: typing.Optional[int] = None,
|
411
411
|
proxy: typing.Optional[modal.proxy._Proxy] = None,
|
412
412
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
413
|
-
timeout:
|
413
|
+
timeout: int = 300,
|
414
414
|
name: typing.Optional[str] = None,
|
415
415
|
is_generator: typing.Optional[bool] = None,
|
416
416
|
cloud: typing.Optional[str] = None,
|
@@ -463,7 +463,7 @@ class _App:
|
|
463
463
|
scaledown_window: typing.Optional[int] = None,
|
464
464
|
proxy: typing.Optional[modal.proxy._Proxy] = None,
|
465
465
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
466
|
-
timeout:
|
466
|
+
timeout: int = 300,
|
467
467
|
cloud: typing.Optional[str] = None,
|
468
468
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
469
469
|
enable_memory_snapshot: bool = False,
|
@@ -1013,7 +1013,7 @@ class App:
|
|
1013
1013
|
scaledown_window: typing.Optional[int] = None,
|
1014
1014
|
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
1015
1015
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
1016
|
-
timeout:
|
1016
|
+
timeout: int = 300,
|
1017
1017
|
name: typing.Optional[str] = None,
|
1018
1018
|
is_generator: typing.Optional[bool] = None,
|
1019
1019
|
cloud: typing.Optional[str] = None,
|
@@ -1066,7 +1066,7 @@ class App:
|
|
1066
1066
|
scaledown_window: typing.Optional[int] = None,
|
1067
1067
|
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
1068
1068
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
1069
|
-
timeout:
|
1069
|
+
timeout: int = 300,
|
1070
1070
|
cloud: typing.Optional[str] = None,
|
1071
1071
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
1072
1072
|
enable_memory_snapshot: bool = False,
|
@@ -33,7 +33,7 @@ class _Client:
|
|
33
33
|
server_url: str,
|
34
34
|
client_type: int,
|
35
35
|
credentials: typing.Optional[tuple[str, str]],
|
36
|
-
version: str = "1.1.2.
|
36
|
+
version: str = "1.1.2.dev41",
|
37
37
|
):
|
38
38
|
"""mdmd:hidden
|
39
39
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -164,7 +164,7 @@ class Client:
|
|
164
164
|
server_url: str,
|
165
165
|
client_type: int,
|
166
166
|
credentials: typing.Optional[tuple[str, str]],
|
167
|
-
version: str = "1.1.2.
|
167
|
+
version: str = "1.1.2.dev41",
|
168
168
|
):
|
169
169
|
"""mdmd:hidden
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
@@ -84,7 +84,7 @@ class Function(
|
|
84
84
|
memory: typing.Union[int, tuple[int, int], None] = None,
|
85
85
|
proxy: typing.Optional[modal.proxy.Proxy] = None,
|
86
86
|
retries: typing.Union[int, modal.retries.Retries, None] = None,
|
87
|
-
timeout:
|
87
|
+
timeout: int = 300,
|
88
88
|
min_containers: typing.Optional[int] = None,
|
89
89
|
max_containers: typing.Optional[int] = None,
|
90
90
|
buffer_containers: typing.Optional[int] = None,
|
@@ -433,7 +433,7 @@ class Function(
|
|
433
433
|
|
434
434
|
_call_generator: ___call_generator_spec[typing_extensions.Self]
|
435
435
|
|
436
|
-
class __remote_spec(typing_extensions.Protocol[
|
436
|
+
class __remote_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
|
437
437
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> ReturnType_INNER:
|
438
438
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
439
439
|
...
|
@@ -442,7 +442,7 @@ class Function(
|
|
442
442
|
"""Calls the function remotely, executing it with the given arguments and returning the execution's result."""
|
443
443
|
...
|
444
444
|
|
445
|
-
remote: __remote_spec[modal._functions.
|
445
|
+
remote: __remote_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
|
446
446
|
|
447
447
|
class __remote_gen_spec(typing_extensions.Protocol[SUPERSELF]):
|
448
448
|
def __call__(self, /, *args, **kwargs) -> typing.Generator[typing.Any, None, None]:
|
@@ -469,7 +469,7 @@ class Function(
|
|
469
469
|
"""
|
470
470
|
...
|
471
471
|
|
472
|
-
class ___experimental_spawn_spec(typing_extensions.Protocol[
|
472
|
+
class ___experimental_spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
|
473
473
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
474
474
|
"""[Experimental] Calls the function with the given arguments, without waiting for the results.
|
475
475
|
|
@@ -493,7 +493,7 @@ class Function(
|
|
493
493
|
...
|
494
494
|
|
495
495
|
_experimental_spawn: ___experimental_spawn_spec[
|
496
|
-
modal._functions.
|
496
|
+
modal._functions.P, modal._functions.ReturnType, typing_extensions.Self
|
497
497
|
]
|
498
498
|
|
499
499
|
class ___spawn_map_inner_spec(typing_extensions.Protocol[P_INNER, SUPERSELF]):
|
@@ -502,7 +502,7 @@ class Function(
|
|
502
502
|
|
503
503
|
_spawn_map_inner: ___spawn_map_inner_spec[modal._functions.P, typing_extensions.Self]
|
504
504
|
|
505
|
-
class __spawn_spec(typing_extensions.Protocol[
|
505
|
+
class __spawn_spec(typing_extensions.Protocol[P_INNER, ReturnType_INNER, SUPERSELF]):
|
506
506
|
def __call__(self, /, *args: P_INNER.args, **kwargs: P_INNER.kwargs) -> FunctionCall[ReturnType_INNER]:
|
507
507
|
"""Calls the function with the given arguments, without waiting for the results.
|
508
508
|
|
@@ -523,7 +523,7 @@ class Function(
|
|
523
523
|
"""
|
524
524
|
...
|
525
525
|
|
526
|
-
spawn: __spawn_spec[modal._functions.
|
526
|
+
spawn: __spawn_spec[modal._functions.P, modal._functions.ReturnType, typing_extensions.Self]
|
527
527
|
|
528
528
|
def get_raw_f(self) -> collections.abc.Callable[..., typing.Any]:
|
529
529
|
"""Return the inner Python object wrapped by this Modal Function."""
|
@@ -2114,7 +2114,7 @@ class _Image(_Object, type_prefix="im"):
|
|
2114
2114
|
gpu: Union[GPU_T, list[GPU_T]] = None, # Requested GPU or or list of acceptable GPUs( e.g. ["A10", "A100"])
|
2115
2115
|
cpu: Optional[float] = None, # How many CPU cores to request. This is a soft limit.
|
2116
2116
|
memory: Optional[int] = None, # How much memory to request, in MiB. This is a soft limit.
|
2117
|
-
timeout:
|
2117
|
+
timeout: int = 60 * 60, # Maximum execution time of the function in seconds.
|
2118
2118
|
cloud: Optional[str] = None, # Cloud provider to run the function on. Possible values are aws, gcp, oci, auto.
|
2119
2119
|
region: Optional[Union[str, Sequence[str]]] = None, # Region or regions to run the function on.
|
2120
2120
|
force_build: bool = False, # Ignore cached builds, similar to 'docker build --no-cache'
|
@@ -845,7 +845,7 @@ class _Image(modal._object._Object):
|
|
845
845
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
|
846
846
|
cpu: typing.Optional[float] = None,
|
847
847
|
memory: typing.Optional[int] = None,
|
848
|
-
timeout:
|
848
|
+
timeout: int = 3600,
|
849
849
|
cloud: typing.Optional[str] = None,
|
850
850
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
851
851
|
force_build: bool = False,
|
@@ -1689,7 +1689,7 @@ class Image(modal.object.Object):
|
|
1689
1689
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig, list[typing.Union[None, str, modal.gpu._GPUConfig]]] = None,
|
1690
1690
|
cpu: typing.Optional[float] = None,
|
1691
1691
|
memory: typing.Optional[int] = None,
|
1692
|
-
timeout:
|
1692
|
+
timeout: int = 3600,
|
1693
1693
|
cloud: typing.Optional[str] = None,
|
1694
1694
|
region: typing.Union[str, collections.abc.Sequence[str], None] = None,
|
1695
1695
|
force_build: bool = False,
|
@@ -108,7 +108,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
108
108
|
image: _Image,
|
109
109
|
secrets: Sequence[_Secret],
|
110
110
|
name: Optional[str] = None,
|
111
|
-
timeout:
|
111
|
+
timeout: int = 300,
|
112
112
|
workdir: Optional[str] = None,
|
113
113
|
gpu: GPU_T = None,
|
114
114
|
cloud: Optional[str] = None,
|
@@ -257,7 +257,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
257
257
|
image: Optional[_Image] = None, # The image to run as the container for the sandbox.
|
258
258
|
secrets: Sequence[_Secret] = (), # Environment variables to inject into the sandbox.
|
259
259
|
network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
|
260
|
-
timeout:
|
260
|
+
timeout: int = 300, # Maximum execution time of the sandbox in seconds.
|
261
261
|
workdir: Optional[str] = None, # Working directory of the sandbox.
|
262
262
|
gpu: GPU_T = None,
|
263
263
|
cloud: Optional[str] = None,
|
@@ -355,7 +355,7 @@ class _Sandbox(_Object, type_prefix="sb"):
|
|
355
355
|
secrets: Sequence[_Secret] = (), # Environment variables to inject into the sandbox.
|
356
356
|
mounts: Sequence[_Mount] = (),
|
357
357
|
network_file_systems: dict[Union[str, os.PathLike], _NetworkFileSystem] = {},
|
358
|
-
timeout:
|
358
|
+
timeout: int = 300, # Maximum execution time of the sandbox in seconds.
|
359
359
|
workdir: Optional[str] = None, # Working directory of the sandbox.
|
360
360
|
gpu: GPU_T = None,
|
361
361
|
cloud: Optional[str] = None,
|
@@ -59,7 +59,7 @@ class _Sandbox(modal._object._Object):
|
|
59
59
|
image: modal.image._Image,
|
60
60
|
secrets: collections.abc.Sequence[modal.secret._Secret],
|
61
61
|
name: typing.Optional[str] = None,
|
62
|
-
timeout:
|
62
|
+
timeout: int = 300,
|
63
63
|
workdir: typing.Optional[str] = None,
|
64
64
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
65
65
|
cloud: typing.Optional[str] = None,
|
@@ -95,7 +95,7 @@ class _Sandbox(modal._object._Object):
|
|
95
95
|
image: typing.Optional[modal.image._Image] = None,
|
96
96
|
secrets: collections.abc.Sequence[modal.secret._Secret] = (),
|
97
97
|
network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
|
98
|
-
timeout:
|
98
|
+
timeout: int = 300,
|
99
99
|
workdir: typing.Optional[str] = None,
|
100
100
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
101
101
|
cloud: typing.Optional[str] = None,
|
@@ -144,7 +144,7 @@ class _Sandbox(modal._object._Object):
|
|
144
144
|
secrets: collections.abc.Sequence[modal.secret._Secret] = (),
|
145
145
|
mounts: collections.abc.Sequence[modal.mount._Mount] = (),
|
146
146
|
network_file_systems: dict[typing.Union[str, os.PathLike], modal.network_file_system._NetworkFileSystem] = {},
|
147
|
-
timeout:
|
147
|
+
timeout: int = 300,
|
148
148
|
workdir: typing.Optional[str] = None,
|
149
149
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
150
150
|
cloud: typing.Optional[str] = None,
|
@@ -369,7 +369,7 @@ class Sandbox(modal.object.Object):
|
|
369
369
|
image: modal.image.Image,
|
370
370
|
secrets: collections.abc.Sequence[modal.secret.Secret],
|
371
371
|
name: typing.Optional[str] = None,
|
372
|
-
timeout:
|
372
|
+
timeout: int = 300,
|
373
373
|
workdir: typing.Optional[str] = None,
|
374
374
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
375
375
|
cloud: typing.Optional[str] = None,
|
@@ -408,7 +408,7 @@ class Sandbox(modal.object.Object):
|
|
408
408
|
network_file_systems: dict[
|
409
409
|
typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
|
410
410
|
] = {},
|
411
|
-
timeout:
|
411
|
+
timeout: int = 300,
|
412
412
|
workdir: typing.Optional[str] = None,
|
413
413
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
414
414
|
cloud: typing.Optional[str] = None,
|
@@ -459,7 +459,7 @@ class Sandbox(modal.object.Object):
|
|
459
459
|
network_file_systems: dict[
|
460
460
|
typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
|
461
461
|
] = {},
|
462
|
-
timeout:
|
462
|
+
timeout: int = 300,
|
463
463
|
workdir: typing.Optional[str] = None,
|
464
464
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
465
465
|
cloud: typing.Optional[str] = None,
|
@@ -514,7 +514,7 @@ class Sandbox(modal.object.Object):
|
|
514
514
|
network_file_systems: dict[
|
515
515
|
typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
|
516
516
|
] = {},
|
517
|
-
timeout:
|
517
|
+
timeout: int = 300,
|
518
518
|
workdir: typing.Optional[str] = None,
|
519
519
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
520
520
|
cloud: typing.Optional[str] = None,
|
@@ -550,7 +550,7 @@ class Sandbox(modal.object.Object):
|
|
550
550
|
network_file_systems: dict[
|
551
551
|
typing.Union[str, os.PathLike], modal.network_file_system.NetworkFileSystem
|
552
552
|
] = {},
|
553
|
-
timeout:
|
553
|
+
timeout: int = 300,
|
554
554
|
workdir: typing.Optional[str] = None,
|
555
555
|
gpu: typing.Union[None, str, modal.gpu._GPUConfig] = None,
|
556
556
|
cloud: typing.Optional[str] = None,
|
@@ -120,6 +120,7 @@ class _VolumeManager:
|
|
120
120
|
async def create(
|
121
121
|
name: str, # Name to use for the new Volume
|
122
122
|
*,
|
123
|
+
version: Optional[int] = None, # Experimental: Configure the backend VolumeFS version
|
123
124
|
allow_existing: bool = False, # If True, no-op when the Volume already exists
|
124
125
|
environment_name: Optional[str] = None, # Uses active environment if not specified
|
125
126
|
client: Optional[_Client] = None, # Optional client with Modal credentials
|
@@ -154,10 +155,15 @@ class _VolumeManager:
|
|
154
155
|
if allow_existing
|
155
156
|
else api_pb2.OBJECT_CREATION_TYPE_CREATE_FAIL_IF_EXISTS
|
156
157
|
)
|
158
|
+
|
159
|
+
if version is not None and version not in {1, 2}:
|
160
|
+
raise InvalidError("VolumeFS version must be either 1 or 2")
|
161
|
+
|
157
162
|
req = api_pb2.VolumeGetOrCreateRequest(
|
158
163
|
deployment_name=name,
|
159
164
|
environment_name=_get_environment_name(environment_name),
|
160
165
|
object_creation_type=object_creation_type,
|
166
|
+
version=version,
|
161
167
|
)
|
162
168
|
try:
|
163
169
|
await retry_transient_errors(client.stub.VolumeGetOrCreate, req)
|
@@ -86,6 +86,7 @@ class _VolumeManager:
|
|
86
86
|
async def create(
|
87
87
|
name: str,
|
88
88
|
*,
|
89
|
+
version: typing.Optional[int] = None,
|
89
90
|
allow_existing: bool = False,
|
90
91
|
environment_name: typing.Optional[str] = None,
|
91
92
|
client: typing.Optional[modal.client._Client] = None,
|
@@ -186,6 +187,7 @@ class VolumeManager:
|
|
186
187
|
/,
|
187
188
|
name: str,
|
188
189
|
*,
|
190
|
+
version: typing.Optional[int] = None,
|
189
191
|
allow_existing: bool = False,
|
190
192
|
environment_name: typing.Optional[str] = None,
|
191
193
|
client: typing.Optional[modal.client.Client] = None,
|
@@ -220,6 +222,7 @@ class VolumeManager:
|
|
220
222
|
/,
|
221
223
|
name: str,
|
222
224
|
*,
|
225
|
+
version: typing.Optional[int] = None,
|
223
226
|
allow_existing: bool = False,
|
224
227
|
environment_name: typing.Optional[str] = None,
|
225
228
|
client: typing.Optional[modal.client.Client] = None,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|