modal 1.2.1.dev12__tar.gz → 1.2.1.dev13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of modal might be problematic. Click here for more details.
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/PKG-INFO +1 -1
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/client.pyi +2 -2
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/io_streams.py +124 -34
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/io_streams.pyi +59 -3
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal.egg-info/PKG-INFO +1 -1
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_version/__init__.py +1 -1
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/LICENSE +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/README.md +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/__main__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_billing.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_clustered_functions.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_clustered_functions.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_container_entrypoint.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_functions.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_ipython.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_location.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_object.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_output.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_partial_function.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_pty.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_resolver.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_resources.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/asgi.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/container_io_manager.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/container_io_manager.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/execution_context.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/execution_context.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/gpu_memory_snapshot.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/telemetry.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_runtime/user_code_imports.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_serialization.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_traceback.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_tunnel.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_tunnel.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_type_manager.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/app_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/async_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/auth_token_manager.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/blob_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/bytes_io_segment_payload.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/deprecation.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/docker_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/function_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/git_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/grpc_testing.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/grpc_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/hash_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/http_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/jwt_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/logger.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/mount_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/name_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/package_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/pattern_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/rand_pb_testing.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/shell_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/task_command_router_client.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_utils/time_utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_vendor/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_vendor/a2wsgi_wsgi.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_vendor/cloudpickle.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_vendor/tblib.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/_watcher.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/app.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/app.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/billing.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/2023.12.312.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/2023.12.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/2024.04.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/2024.10.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/2025.06.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/PREVIEW.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/README.md +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/builder/base-images.json +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/call_graph.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/_download.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/_traceback.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/app.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/cluster.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/config.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/container.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/dict.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/entry_point.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/environment.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/import_refs.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/launch.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/network_file_system.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/profile.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/programs/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/programs/launch_instance_ssh.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/programs/run_jupyter.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/programs/run_marimo.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/programs/vscode.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/queues.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/run.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/secret.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/token.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/utils.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cli/volume.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/client.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cloud_bucket_mount.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cloud_bucket_mount.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cls.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/cls.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/config.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/container_process.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/container_process.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/dict.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/dict.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/environments.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/environments.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/exception.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/experimental/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/experimental/flash.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/experimental/flash.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/experimental/ipython.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/file_io.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/file_io.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/file_pattern_matcher.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/functions.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/functions.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/gpu.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/image.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/image.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/mount.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/mount.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/network_file_system.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/network_file_system.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/object.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/object.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/output.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/parallel_map.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/parallel_map.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/partial_function.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/partial_function.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/proxy.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/proxy.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/py.typed +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/queue.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/queue.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/retries.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/runner.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/runner.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/running_app.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/sandbox.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/sandbox.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/schedule.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/scheduler_placement.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/secret.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/secret.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/serving.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/serving.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/snapshot.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/snapshot.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/stream_type.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/token_flow.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/token_flow.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/volume.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal/volume.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal.egg-info/SOURCES.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal.egg-info/dependency_links.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal.egg-info/entry_points.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal.egg-info/requires.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal.egg-info/top_level.txt +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_docs/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_docs/gen_cli_docs.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_docs/gen_reference_docs.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_docs/mdmd/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_docs/mdmd/mdmd.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_docs/mdmd/signatures.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/__init__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/api.proto +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/api_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/api_pb2.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/api_pb2.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/api_pb2_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/api_pb2_grpc.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/modal_api_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/py.typed +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/sandbox_router.proto +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/sandbox_router_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/sandbox_router_pb2.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/sandbox_router_pb2.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/sandbox_router_pb2_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/sandbox_router_pb2_grpc.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/task_command_router.proto +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/task_command_router_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/task_command_router_pb2.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/task_command_router_pb2.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/task_command_router_pb2_grpc.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_proto/task_command_router_pb2_grpc.pyi +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/modal_version/__main__.py +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/pyproject.toml +0 -0
- {modal-1.2.1.dev12 → modal-1.2.1.dev13}/setup.cfg +0 -0
|
@@ -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.2.1.
|
|
36
|
+
version: str = "1.2.1.dev13",
|
|
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.2.1.
|
|
167
|
+
version: str = "1.2.1.dev13",
|
|
168
168
|
):
|
|
169
169
|
"""mdmd:hidden
|
|
170
170
|
The Modal client object is not intended to be instantiated directly by users.
|
|
@@ -605,7 +605,7 @@ class _StreamReader(Generic[T]):
|
|
|
605
605
|
MAX_BUFFER_SIZE = 2 * 1024 * 1024
|
|
606
606
|
|
|
607
607
|
|
|
608
|
-
class
|
|
608
|
+
class _StreamWriterThroughServer:
|
|
609
609
|
"""Provides an interface to buffer and write logs to a sandbox or container process stream (`stdin`)."""
|
|
610
610
|
|
|
611
611
|
def __init__(self, object_id: str, object_type: Literal["sandbox", "container_process"], client: _Client) -> None:
|
|
@@ -627,25 +627,6 @@ class _StreamWriter:
|
|
|
627
627
|
|
|
628
628
|
This is non-blocking and queues the data to an internal buffer. Must be
|
|
629
629
|
used along with the `drain()` method, which flushes the buffer.
|
|
630
|
-
|
|
631
|
-
**Usage**
|
|
632
|
-
|
|
633
|
-
```python fixture:running_app
|
|
634
|
-
from modal import Sandbox
|
|
635
|
-
|
|
636
|
-
sandbox = Sandbox.create(
|
|
637
|
-
"bash",
|
|
638
|
-
"-c",
|
|
639
|
-
"while read line; do echo $line; done",
|
|
640
|
-
app=running_app,
|
|
641
|
-
)
|
|
642
|
-
sandbox.stdin.write(b"foo\\n")
|
|
643
|
-
sandbox.stdin.write(b"bar\\n")
|
|
644
|
-
sandbox.stdin.write_eof()
|
|
645
|
-
|
|
646
|
-
sandbox.stdin.drain()
|
|
647
|
-
sandbox.wait()
|
|
648
|
-
```
|
|
649
630
|
"""
|
|
650
631
|
if self._is_closed:
|
|
651
632
|
raise ValueError("Stdin is closed. Cannot write to it.")
|
|
@@ -653,7 +634,7 @@ class _StreamWriter:
|
|
|
653
634
|
if isinstance(data, str):
|
|
654
635
|
data = data.encode("utf-8")
|
|
655
636
|
if len(self._buffer) + len(data) > MAX_BUFFER_SIZE:
|
|
656
|
-
raise BufferError("Buffer size exceed limit. Call drain to
|
|
637
|
+
raise BufferError("Buffer size exceed limit. Call drain to flush the buffer.")
|
|
657
638
|
self._buffer.extend(data)
|
|
658
639
|
else:
|
|
659
640
|
raise TypeError(f"data argument must be a bytes-like object, not {type(data).__name__}")
|
|
@@ -672,19 +653,6 @@ class _StreamWriter:
|
|
|
672
653
|
|
|
673
654
|
This is a flow control method that blocks until data is sent. It returns
|
|
674
655
|
when it is appropriate to continue writing data to the stream.
|
|
675
|
-
|
|
676
|
-
**Usage**
|
|
677
|
-
|
|
678
|
-
```python notest
|
|
679
|
-
writer.write(data)
|
|
680
|
-
writer.drain()
|
|
681
|
-
```
|
|
682
|
-
|
|
683
|
-
Async usage:
|
|
684
|
-
```python notest
|
|
685
|
-
writer.write(data) # not a blocking operation
|
|
686
|
-
await writer.drain.aio()
|
|
687
|
-
```
|
|
688
656
|
"""
|
|
689
657
|
data = bytes(self._buffer)
|
|
690
658
|
self._buffer.clear()
|
|
@@ -713,5 +681,127 @@ class _StreamWriter:
|
|
|
713
681
|
raise exc
|
|
714
682
|
|
|
715
683
|
|
|
684
|
+
class _StreamWriterThroughCommandRouter:
|
|
685
|
+
def __init__(
|
|
686
|
+
self,
|
|
687
|
+
object_id: str,
|
|
688
|
+
command_router_client: TaskCommandRouterClient,
|
|
689
|
+
task_id: str,
|
|
690
|
+
) -> None:
|
|
691
|
+
self._object_id = object_id
|
|
692
|
+
self._command_router_client = command_router_client
|
|
693
|
+
self._task_id = task_id
|
|
694
|
+
self._is_closed = False
|
|
695
|
+
self._buffer = bytearray()
|
|
696
|
+
self._offset = 0
|
|
697
|
+
|
|
698
|
+
def write(self, data: Union[bytes, bytearray, memoryview, str]) -> None:
|
|
699
|
+
if self._is_closed:
|
|
700
|
+
raise ValueError("Stdin is closed. Cannot write to it.")
|
|
701
|
+
if isinstance(data, (bytes, bytearray, memoryview, str)):
|
|
702
|
+
if isinstance(data, str):
|
|
703
|
+
data = data.encode("utf-8")
|
|
704
|
+
if len(self._buffer) + len(data) > MAX_BUFFER_SIZE:
|
|
705
|
+
raise BufferError("Buffer size exceed limit. Call drain to flush the buffer.")
|
|
706
|
+
self._buffer.extend(data)
|
|
707
|
+
else:
|
|
708
|
+
raise TypeError(f"data argument must be a bytes-like object, not {type(data).__name__}")
|
|
709
|
+
|
|
710
|
+
def write_eof(self) -> None:
|
|
711
|
+
self._is_closed = True
|
|
712
|
+
|
|
713
|
+
async def drain(self) -> None:
|
|
714
|
+
eof = self._is_closed
|
|
715
|
+
# NB: There's no need to prevent writing eof twice, because the command router will ignore the second EOF.
|
|
716
|
+
if self._buffer or eof:
|
|
717
|
+
data = bytes(self._buffer)
|
|
718
|
+
await self._command_router_client.exec_stdin_write(
|
|
719
|
+
task_id=self._task_id, exec_id=self._object_id, offset=self._offset, data=data, eof=eof
|
|
720
|
+
)
|
|
721
|
+
# Only clear the buffer after writing the data to the command router is successful.
|
|
722
|
+
# This allows the client to retry drain() in the event of an exception (though
|
|
723
|
+
# exec_stdin_write already retries on transient errors, so most users will probably
|
|
724
|
+
# not do this).
|
|
725
|
+
self._buffer.clear()
|
|
726
|
+
self._offset += len(data)
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
class _StreamWriter:
|
|
730
|
+
"""Provides an interface to buffer and write logs to a sandbox or container process stream (`stdin`)."""
|
|
731
|
+
|
|
732
|
+
def __init__(
|
|
733
|
+
self,
|
|
734
|
+
object_id: str,
|
|
735
|
+
object_type: Literal["sandbox", "container_process"],
|
|
736
|
+
client: _Client,
|
|
737
|
+
command_router_client: Optional[TaskCommandRouterClient] = None,
|
|
738
|
+
task_id: Optional[str] = None,
|
|
739
|
+
) -> None:
|
|
740
|
+
"""mdmd:hidden"""
|
|
741
|
+
if command_router_client is None:
|
|
742
|
+
self._impl = _StreamWriterThroughServer(object_id, object_type, client)
|
|
743
|
+
else:
|
|
744
|
+
assert task_id is not None
|
|
745
|
+
assert object_type == "container_process"
|
|
746
|
+
self._impl = _StreamWriterThroughCommandRouter(object_id, command_router_client, task_id=task_id)
|
|
747
|
+
|
|
748
|
+
def write(self, data: Union[bytes, bytearray, memoryview, str]) -> None:
|
|
749
|
+
"""Write data to the stream but does not send it immediately.
|
|
750
|
+
|
|
751
|
+
This is non-blocking and queues the data to an internal buffer. Must be
|
|
752
|
+
used along with the `drain()` method, which flushes the buffer.
|
|
753
|
+
|
|
754
|
+
**Usage**
|
|
755
|
+
|
|
756
|
+
```python fixture:running_app
|
|
757
|
+
from modal import Sandbox
|
|
758
|
+
|
|
759
|
+
sandbox = Sandbox.create(
|
|
760
|
+
"bash",
|
|
761
|
+
"-c",
|
|
762
|
+
"while read line; do echo $line; done",
|
|
763
|
+
app=running_app,
|
|
764
|
+
)
|
|
765
|
+
sandbox.stdin.write(b"foo\\n")
|
|
766
|
+
sandbox.stdin.write(b"bar\\n")
|
|
767
|
+
sandbox.stdin.write_eof()
|
|
768
|
+
|
|
769
|
+
sandbox.stdin.drain()
|
|
770
|
+
sandbox.wait()
|
|
771
|
+
```
|
|
772
|
+
"""
|
|
773
|
+
self._impl.write(data)
|
|
774
|
+
|
|
775
|
+
def write_eof(self) -> None:
|
|
776
|
+
"""Close the write end of the stream after the buffered data is drained.
|
|
777
|
+
|
|
778
|
+
If the process was blocked on input, it will become unblocked after
|
|
779
|
+
`write_eof()`. This method needs to be used along with the `drain()`
|
|
780
|
+
method, which flushes the EOF to the process.
|
|
781
|
+
"""
|
|
782
|
+
self._impl.write_eof()
|
|
783
|
+
|
|
784
|
+
async def drain(self) -> None:
|
|
785
|
+
"""Flush the write buffer and send data to the running process.
|
|
786
|
+
|
|
787
|
+
This is a flow control method that blocks until data is sent. It returns
|
|
788
|
+
when it is appropriate to continue writing data to the stream.
|
|
789
|
+
|
|
790
|
+
**Usage**
|
|
791
|
+
|
|
792
|
+
```python notest
|
|
793
|
+
writer.write(data)
|
|
794
|
+
writer.drain()
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
Async usage:
|
|
798
|
+
```python notest
|
|
799
|
+
writer.write(data) # not a blocking operation
|
|
800
|
+
await writer.drain.aio()
|
|
801
|
+
```
|
|
802
|
+
"""
|
|
803
|
+
await self._impl.drain()
|
|
804
|
+
|
|
805
|
+
|
|
716
806
|
StreamReader = synchronize_api(_StreamReader)
|
|
717
807
|
StreamWriter = synchronize_api(_StreamWriter)
|
|
@@ -249,7 +249,7 @@ class _StreamReader(typing.Generic[T]):
|
|
|
249
249
|
"""mdmd:hidden"""
|
|
250
250
|
...
|
|
251
251
|
|
|
252
|
-
class
|
|
252
|
+
class _StreamWriterThroughServer:
|
|
253
253
|
"""Provides an interface to buffer and write logs to a sandbox or container process stream (`stdin`)."""
|
|
254
254
|
def __init__(
|
|
255
255
|
self, object_id: str, object_type: typing.Literal["sandbox", "container_process"], client: modal.client._Client
|
|
@@ -258,6 +258,58 @@ class _StreamWriter:
|
|
|
258
258
|
...
|
|
259
259
|
|
|
260
260
|
def _get_next_index(self) -> int: ...
|
|
261
|
+
def write(self, data: typing.Union[bytes, bytearray, memoryview, str]) -> None:
|
|
262
|
+
"""Write data to the stream but does not send it immediately.
|
|
263
|
+
|
|
264
|
+
This is non-blocking and queues the data to an internal buffer. Must be
|
|
265
|
+
used along with the `drain()` method, which flushes the buffer.
|
|
266
|
+
"""
|
|
267
|
+
...
|
|
268
|
+
|
|
269
|
+
def write_eof(self) -> None:
|
|
270
|
+
"""Close the write end of the stream after the buffered data is drained.
|
|
271
|
+
|
|
272
|
+
If the process was blocked on input, it will become unblocked after
|
|
273
|
+
`write_eof()`. This method needs to be used along with the `drain()`
|
|
274
|
+
method, which flushes the EOF to the process.
|
|
275
|
+
"""
|
|
276
|
+
...
|
|
277
|
+
|
|
278
|
+
async def drain(self) -> None:
|
|
279
|
+
"""Flush the write buffer and send data to the running process.
|
|
280
|
+
|
|
281
|
+
This is a flow control method that blocks until data is sent. It returns
|
|
282
|
+
when it is appropriate to continue writing data to the stream.
|
|
283
|
+
"""
|
|
284
|
+
...
|
|
285
|
+
|
|
286
|
+
class _StreamWriterThroughCommandRouter:
|
|
287
|
+
def __init__(
|
|
288
|
+
self,
|
|
289
|
+
object_id: str,
|
|
290
|
+
command_router_client: modal._utils.task_command_router_client.TaskCommandRouterClient,
|
|
291
|
+
task_id: str,
|
|
292
|
+
) -> None:
|
|
293
|
+
"""Initialize self. See help(type(self)) for accurate signature."""
|
|
294
|
+
...
|
|
295
|
+
|
|
296
|
+
def write(self, data: typing.Union[bytes, bytearray, memoryview, str]) -> None: ...
|
|
297
|
+
def write_eof(self) -> None: ...
|
|
298
|
+
async def drain(self) -> None: ...
|
|
299
|
+
|
|
300
|
+
class _StreamWriter:
|
|
301
|
+
"""Provides an interface to buffer and write logs to a sandbox or container process stream (`stdin`)."""
|
|
302
|
+
def __init__(
|
|
303
|
+
self,
|
|
304
|
+
object_id: str,
|
|
305
|
+
object_type: typing.Literal["sandbox", "container_process"],
|
|
306
|
+
client: modal.client._Client,
|
|
307
|
+
command_router_client: typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient] = None,
|
|
308
|
+
task_id: typing.Optional[str] = None,
|
|
309
|
+
) -> None:
|
|
310
|
+
"""mdmd:hidden"""
|
|
311
|
+
...
|
|
312
|
+
|
|
261
313
|
def write(self, data: typing.Union[bytes, bytearray, memoryview, str]) -> None:
|
|
262
314
|
"""Write data to the stream but does not send it immediately.
|
|
263
315
|
|
|
@@ -423,12 +475,16 @@ class StreamReader(typing.Generic[T]):
|
|
|
423
475
|
class StreamWriter:
|
|
424
476
|
"""Provides an interface to buffer and write logs to a sandbox or container process stream (`stdin`)."""
|
|
425
477
|
def __init__(
|
|
426
|
-
self,
|
|
478
|
+
self,
|
|
479
|
+
object_id: str,
|
|
480
|
+
object_type: typing.Literal["sandbox", "container_process"],
|
|
481
|
+
client: modal.client.Client,
|
|
482
|
+
command_router_client: typing.Optional[modal._utils.task_command_router_client.TaskCommandRouterClient] = None,
|
|
483
|
+
task_id: typing.Optional[str] = None,
|
|
427
484
|
) -> None:
|
|
428
485
|
"""mdmd:hidden"""
|
|
429
486
|
...
|
|
430
487
|
|
|
431
|
-
def _get_next_index(self) -> int: ...
|
|
432
488
|
def write(self, data: typing.Union[bytes, bytearray, memoryview, str]) -> None:
|
|
433
489
|
"""Write data to the stream but does not send it immediately.
|
|
434
490
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|