loopix-sdk 2.30.0__py3-none-any.whl
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.
- loopix/__init__.py +260 -0
- loopix/api/__init__.py +287 -0
- loopix/api/client/__init__.py +8 -0
- loopix/api/client/api/__init__.py +1 -0
- loopix/api/client/api/sandboxes/__init__.py +1 -0
- loopix/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +161 -0
- loopix/api/client/api/sandboxes/get_sandboxes.py +176 -0
- loopix/api/client/api/sandboxes/get_sandboxes_metrics.py +173 -0
- loopix/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +163 -0
- loopix/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +199 -0
- loopix/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +212 -0
- loopix/api/client/api/sandboxes/get_v2_sandboxes.py +230 -0
- loopix/api/client/api/sandboxes/get_v_2_sandboxes_sandbox_id_logs.py +254 -0
- loopix/api/client/api/sandboxes/post_sandboxes.py +172 -0
- loopix/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +193 -0
- loopix/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +187 -0
- loopix/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +181 -0
- loopix/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +189 -0
- loopix/api/client/api/sandboxes/post_sandboxes_sandbox_id_snapshots.py +195 -0
- loopix/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +193 -0
- loopix/api/client/api/sandboxes/put_sandboxes_sandbox_id_network.py +199 -0
- loopix/api/client/api/snapshots/__init__.py +1 -0
- loopix/api/client/api/snapshots/get_snapshots.py +202 -0
- loopix/api/client/api/tags/__init__.py +1 -0
- loopix/api/client/api/tags/delete_templates_tags.py +174 -0
- loopix/api/client/api/tags/get_templates_template_id_tags.py +172 -0
- loopix/api/client/api/tags/post_templates_tags.py +176 -0
- loopix/api/client/api/templates/__init__.py +1 -0
- loopix/api/client/api/templates/delete_templates_template_id.py +157 -0
- loopix/api/client/api/templates/get_templates.py +172 -0
- loopix/api/client/api/templates/get_templates_aliases_alias.py +167 -0
- loopix/api/client/api/templates/get_templates_template_id.py +195 -0
- loopix/api/client/api/templates/get_templates_template_id_builds_build_id_logs.py +272 -0
- loopix/api/client/api/templates/get_templates_template_id_builds_build_id_status.py +232 -0
- loopix/api/client/api/templates/get_templates_template_id_files_hash.py +180 -0
- loopix/api/client/api/templates/patch_templates_template_id.py +183 -0
- loopix/api/client/api/templates/patch_v_2_templates_template_id.py +185 -0
- loopix/api/client/api/templates/post_templates.py +172 -0
- loopix/api/client/api/templates/post_templates_template_id.py +181 -0
- loopix/api/client/api/templates/post_templates_template_id_builds_build_id.py +170 -0
- loopix/api/client/api/templates/post_v2_templates.py +172 -0
- loopix/api/client/api/templates/post_v3_templates.py +176 -0
- loopix/api/client/api/templates/post_v_2_templates_template_id_builds_build_id.py +192 -0
- loopix/api/client/api/volumes/__init__.py +1 -0
- loopix/api/client/api/volumes/delete_volumes_volume_id.py +161 -0
- loopix/api/client/api/volumes/get_volumes.py +140 -0
- loopix/api/client/api/volumes/get_volumes_volume_id.py +163 -0
- loopix/api/client/api/volumes/post_volumes.py +172 -0
- loopix/api/client/client.py +286 -0
- loopix/api/client/errors.py +16 -0
- loopix/api/client/models/__init__.py +185 -0
- loopix/api/client/models/admin_build_cancel_result.py +67 -0
- loopix/api/client/models/admin_sandbox_kill_result.py +67 -0
- loopix/api/client/models/assign_template_tags_request.py +67 -0
- loopix/api/client/models/assigned_template_tags.py +68 -0
- loopix/api/client/models/aws_registry.py +85 -0
- loopix/api/client/models/aws_registry_type.py +8 -0
- loopix/api/client/models/build_log_entry.py +89 -0
- loopix/api/client/models/build_status_reason.py +95 -0
- loopix/api/client/models/connect_sandbox.py +59 -0
- loopix/api/client/models/created_access_token.py +100 -0
- loopix/api/client/models/created_team_api_key.py +166 -0
- loopix/api/client/models/delete_template_tags_request.py +67 -0
- loopix/api/client/models/disk_metrics.py +91 -0
- loopix/api/client/models/error.py +67 -0
- loopix/api/client/models/gcp_registry.py +69 -0
- loopix/api/client/models/gcp_registry_type.py +8 -0
- loopix/api/client/models/general_registry.py +77 -0
- loopix/api/client/models/general_registry_type.py +8 -0
- loopix/api/client/models/identifier_masking_details.py +83 -0
- loopix/api/client/models/listed_sandbox.py +179 -0
- loopix/api/client/models/log_level.py +11 -0
- loopix/api/client/models/logs_direction.py +9 -0
- loopix/api/client/models/logs_source.py +9 -0
- loopix/api/client/models/machine_info.py +83 -0
- loopix/api/client/models/max_team_metric.py +78 -0
- loopix/api/client/models/mcp_type_0.py +44 -0
- loopix/api/client/models/new_access_token.py +59 -0
- loopix/api/client/models/new_sandbox.py +224 -0
- loopix/api/client/models/new_team_api_key.py +59 -0
- loopix/api/client/models/new_volume.py +59 -0
- loopix/api/client/models/node.py +160 -0
- loopix/api/client/models/node_detail.py +160 -0
- loopix/api/client/models/node_metrics.py +122 -0
- loopix/api/client/models/node_status.py +12 -0
- loopix/api/client/models/node_status_change.py +82 -0
- loopix/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +59 -0
- loopix/api/client/models/post_sandboxes_sandbox_id_snapshots_body.py +60 -0
- loopix/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +59 -0
- loopix/api/client/models/resumed_sandbox.py +68 -0
- loopix/api/client/models/sandbox.py +145 -0
- loopix/api/client/models/sandbox_auto_resume_config.py +60 -0
- loopix/api/client/models/sandbox_detail.py +267 -0
- loopix/api/client/models/sandbox_lifecycle.py +70 -0
- loopix/api/client/models/sandbox_log.py +70 -0
- loopix/api/client/models/sandbox_log_entry.py +93 -0
- loopix/api/client/models/sandbox_log_entry_fields.py +44 -0
- loopix/api/client/models/sandbox_logs.py +91 -0
- loopix/api/client/models/sandbox_logs_v2_response.py +73 -0
- loopix/api/client/models/sandbox_metric.py +126 -0
- loopix/api/client/models/sandbox_network_config.py +118 -0
- loopix/api/client/models/sandbox_network_config_rules.py +72 -0
- loopix/api/client/models/sandbox_network_rule.py +74 -0
- loopix/api/client/models/sandbox_network_transform.py +79 -0
- loopix/api/client/models/sandbox_network_transform_headers.py +47 -0
- loopix/api/client/models/sandbox_network_update_config.py +114 -0
- loopix/api/client/models/sandbox_network_update_config_rules.py +71 -0
- loopix/api/client/models/sandbox_on_timeout.py +9 -0
- loopix/api/client/models/sandbox_pause_request.py +62 -0
- loopix/api/client/models/sandbox_state.py +9 -0
- loopix/api/client/models/sandbox_volume_mount.py +67 -0
- loopix/api/client/models/sandboxes_with_metrics.py +59 -0
- loopix/api/client/models/snapshot_info.py +70 -0
- loopix/api/client/models/team.py +83 -0
- loopix/api/client/models/team_api_key.py +158 -0
- loopix/api/client/models/team_metric.py +86 -0
- loopix/api/client/models/team_user.py +75 -0
- loopix/api/client/models/template.py +225 -0
- loopix/api/client/models/template_alias_response.py +67 -0
- loopix/api/client/models/template_build.py +139 -0
- loopix/api/client/models/template_build_file_upload.py +70 -0
- loopix/api/client/models/template_build_info.py +126 -0
- loopix/api/client/models/template_build_logs_response.py +73 -0
- loopix/api/client/models/template_build_request.py +115 -0
- loopix/api/client/models/template_build_request_v2.py +88 -0
- loopix/api/client/models/template_build_request_v3.py +107 -0
- loopix/api/client/models/template_build_start_v2.py +184 -0
- loopix/api/client/models/template_build_status.py +11 -0
- loopix/api/client/models/template_legacy.py +207 -0
- loopix/api/client/models/template_request_response_v3.py +99 -0
- loopix/api/client/models/template_step.py +91 -0
- loopix/api/client/models/template_tag.py +78 -0
- loopix/api/client/models/template_update_request.py +59 -0
- loopix/api/client/models/template_update_response.py +59 -0
- loopix/api/client/models/template_with_builds.py +156 -0
- loopix/api/client/models/update_team_api_key.py +59 -0
- loopix/api/client/models/volume.py +67 -0
- loopix/api/client/models/volume_and_token.py +75 -0
- loopix/api/client/models/volume_token.py +59 -0
- loopix/api/client/py.typed +1 -0
- loopix/api/client/types.py +54 -0
- loopix/api/client_async/__init__.py +74 -0
- loopix/api/client_sync/__init__.py +73 -0
- loopix/api/metadata.py +14 -0
- loopix/connection_config.py +309 -0
- loopix/envd/api.py +170 -0
- loopix/envd/filesystem/filesystem_connect.py +193 -0
- loopix/envd/filesystem/filesystem_pb2.py +80 -0
- loopix/envd/filesystem/filesystem_pb2.pyi +272 -0
- loopix/envd/process/process_connect.py +174 -0
- loopix/envd/process/process_pb2.py +96 -0
- loopix/envd/process/process_pb2.pyi +316 -0
- loopix/envd/rpc.py +139 -0
- loopix/envd/versions.py +11 -0
- loopix/exceptions.py +133 -0
- loopix/io_utils.py +57 -0
- loopix/paginator.py +52 -0
- loopix/py.typed +0 -0
- loopix/sandbox/_git/__init__.py +85 -0
- loopix/sandbox/_git/args.py +363 -0
- loopix/sandbox/_git/auth.py +132 -0
- loopix/sandbox/_git/config.py +32 -0
- loopix/sandbox/_git/parse.py +222 -0
- loopix/sandbox/_git/types.py +149 -0
- loopix/sandbox/commands/command_handle.py +69 -0
- loopix/sandbox/commands/main.py +39 -0
- loopix/sandbox/filesystem/filesystem.py +337 -0
- loopix/sandbox/filesystem/watch_handle.py +70 -0
- loopix/sandbox/main.py +227 -0
- loopix/sandbox/mcp.py +1949 -0
- loopix/sandbox/network.py +8 -0
- loopix/sandbox/sandbox_api.py +624 -0
- loopix/sandbox/signature.py +47 -0
- loopix/sandbox/utils.py +34 -0
- loopix/sandbox_async/commands/command.py +396 -0
- loopix/sandbox_async/commands/command_handle.py +298 -0
- loopix/sandbox_async/commands/pty.py +257 -0
- loopix/sandbox_async/filesystem/filesystem.py +720 -0
- loopix/sandbox_async/filesystem/watch_handle.py +97 -0
- loopix/sandbox_async/git.py +1100 -0
- loopix/sandbox_async/main.py +987 -0
- loopix/sandbox_async/paginator.py +140 -0
- loopix/sandbox_async/sandbox_api.py +504 -0
- loopix/sandbox_async/utils.py +7 -0
- loopix/sandbox_domains.py +5 -0
- loopix/sandbox_sync/commands/command.py +420 -0
- loopix/sandbox_sync/commands/command_handle.py +239 -0
- loopix/sandbox_sync/commands/pty.py +279 -0
- loopix/sandbox_sync/filesystem/filesystem.py +710 -0
- loopix/sandbox_sync/filesystem/watch_handle.py +102 -0
- loopix/sandbox_sync/git.py +1077 -0
- loopix/sandbox_sync/main.py +975 -0
- loopix/sandbox_sync/paginator.py +140 -0
- loopix/sandbox_sync/sandbox_api.py +491 -0
- loopix/template/consts.py +45 -0
- loopix/template/dockerfile_parser.py +286 -0
- loopix/template/logger.py +232 -0
- loopix/template/main.py +1368 -0
- loopix/template/readycmd.py +144 -0
- loopix/template/types.py +194 -0
- loopix/template/utils.py +426 -0
- loopix/template_async/build_api.py +419 -0
- loopix/template_async/main.py +528 -0
- loopix/template_sync/build_api.py +409 -0
- loopix/template_sync/main.py +529 -0
- loopix/volume/client/__init__.py +8 -0
- loopix/volume/client/api/__init__.py +1 -0
- loopix/volume/client/api/volumes/__init__.py +1 -0
- loopix/volume/client/api/volumes/delete_volumecontent_volume_id_path.py +174 -0
- loopix/volume/client/api/volumes/get_volumecontent_volume_id_dir.py +204 -0
- loopix/volume/client/api/volumes/get_volumecontent_volume_id_file.py +179 -0
- loopix/volume/client/api/volumes/get_volumecontent_volume_id_path.py +176 -0
- loopix/volume/client/api/volumes/patch_volumecontent_volume_id_path.py +203 -0
- loopix/volume/client/api/volumes/post_volumecontent_volume_id_dir.py +239 -0
- loopix/volume/client/api/volumes/put_volumecontent_volume_id_file.py +259 -0
- loopix/volume/client/client.py +286 -0
- loopix/volume/client/errors.py +16 -0
- loopix/volume/client/models/__init__.py +13 -0
- loopix/volume/client/models/error.py +67 -0
- loopix/volume/client/models/patch_volumecontent_volume_id_path_body.py +77 -0
- loopix/volume/client/models/volume_entry_stat.py +145 -0
- loopix/volume/client/models/volume_entry_stat_type.py +11 -0
- loopix/volume/client/py.typed +1 -0
- loopix/volume/client/types.py +54 -0
- loopix/volume/client_async/__init__.py +88 -0
- loopix/volume/client_sync/__init__.py +80 -0
- loopix/volume/connection_config.py +145 -0
- loopix/volume/types.py +62 -0
- loopix/volume/utils.py +52 -0
- loopix/volume/volume_async.py +639 -0
- loopix/volume/volume_sync.py +639 -0
- loopix_connect/__init__.py +1 -0
- loopix_connect/client.py +534 -0
- loopix_connect/py.typed +0 -0
- loopix_sdk-2.30.0.dist-info/METADATA +98 -0
- loopix_sdk-2.30.0.dist-info/RECORD +238 -0
- loopix_sdk-2.30.0.dist-info/WHEEL +4 -0
- loopix_sdk-2.30.0.dist-info/licenses/LICENSE +9 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
import loopix_connect
|
|
2
|
+
import httpx
|
|
3
|
+
import threading
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Optional
|
|
6
|
+
|
|
7
|
+
from packaging.version import Version
|
|
8
|
+
from loopix.api import make_logging_event_hooks
|
|
9
|
+
from loopix.api.client_sync import get_envd_transport
|
|
10
|
+
from loopix.envd.process import process_connect, process_pb2
|
|
11
|
+
from loopix.connection_config import (
|
|
12
|
+
Username,
|
|
13
|
+
ConnectionConfig,
|
|
14
|
+
KEEPALIVE_PING_HEADER,
|
|
15
|
+
KEEPALIVE_PING_INTERVAL_SEC,
|
|
16
|
+
)
|
|
17
|
+
from loopix.exceptions import SandboxException
|
|
18
|
+
from loopix.envd.api import check_sandbox_health
|
|
19
|
+
from loopix.envd.rpc import authentication_header, handle_rpc_exception_with_health
|
|
20
|
+
from loopix.sandbox.commands.command_handle import PtySize
|
|
21
|
+
from loopix.sandbox_sync.commands.command_handle import CommandHandle
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Pty:
|
|
25
|
+
"""
|
|
26
|
+
Module for interacting with PTYs (pseudo-terminals) in the sandbox.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(
|
|
30
|
+
self,
|
|
31
|
+
envd_api_url: str,
|
|
32
|
+
connection_config: ConnectionConfig,
|
|
33
|
+
envd_version: Version,
|
|
34
|
+
) -> None:
|
|
35
|
+
self._envd_api_url = envd_api_url
|
|
36
|
+
self._connection_config = connection_config
|
|
37
|
+
self._envd_version = envd_version
|
|
38
|
+
self._thread_local = threading.local()
|
|
39
|
+
|
|
40
|
+
def _create_envd_api(self) -> httpx.Client:
|
|
41
|
+
transport = get_envd_transport(self._connection_config)
|
|
42
|
+
return httpx.Client(
|
|
43
|
+
base_url=self._envd_api_url,
|
|
44
|
+
transport=transport,
|
|
45
|
+
headers=self._connection_config.sandbox_headers,
|
|
46
|
+
event_hooks=make_logging_event_hooks(self._connection_config.logger),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def _create_rpc(self) -> process_connect.ProcessClient:
|
|
50
|
+
transport = get_envd_transport(self._connection_config)
|
|
51
|
+
return process_connect.ProcessClient(
|
|
52
|
+
self._envd_api_url,
|
|
53
|
+
# TODO: Fix and enable compression again — the headers compression is not solved for streaming.
|
|
54
|
+
# compressor=loopix_connect.GzipCompressor,
|
|
55
|
+
pool=transport.pool,
|
|
56
|
+
json=True,
|
|
57
|
+
headers=self._connection_config.sandbox_headers,
|
|
58
|
+
logger=self._connection_config.logger,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def _envd_api(self) -> httpx.Client:
|
|
63
|
+
envd_api = getattr(self._thread_local, "envd_api", None)
|
|
64
|
+
if envd_api is None:
|
|
65
|
+
envd_api = self._create_envd_api()
|
|
66
|
+
self._thread_local.envd_api = envd_api
|
|
67
|
+
return envd_api
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def _rpc(self) -> process_connect.ProcessClient:
|
|
71
|
+
rpc = getattr(self._thread_local, "rpc", None)
|
|
72
|
+
if rpc is None:
|
|
73
|
+
rpc = self._create_rpc()
|
|
74
|
+
self._thread_local.rpc = rpc
|
|
75
|
+
return rpc
|
|
76
|
+
|
|
77
|
+
def _check_health(self) -> Optional[bool]:
|
|
78
|
+
return check_sandbox_health(self._envd_api)
|
|
79
|
+
|
|
80
|
+
def kill(
|
|
81
|
+
self,
|
|
82
|
+
pid: int,
|
|
83
|
+
request_timeout: Optional[float] = None,
|
|
84
|
+
) -> bool:
|
|
85
|
+
"""
|
|
86
|
+
Kill PTY.
|
|
87
|
+
|
|
88
|
+
:param pid: Process ID of the PTY
|
|
89
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
90
|
+
|
|
91
|
+
:return: `true` if the PTY was killed, `false` if the PTY was not found
|
|
92
|
+
"""
|
|
93
|
+
try:
|
|
94
|
+
self._rpc.send_signal(
|
|
95
|
+
process_pb2.SendSignalRequest(
|
|
96
|
+
process=process_pb2.ProcessSelector(pid=pid),
|
|
97
|
+
signal=process_pb2.Signal.SIGNAL_SIGKILL,
|
|
98
|
+
),
|
|
99
|
+
request_timeout=self._connection_config.get_request_timeout(
|
|
100
|
+
request_timeout
|
|
101
|
+
),
|
|
102
|
+
)
|
|
103
|
+
return True
|
|
104
|
+
except Exception as e:
|
|
105
|
+
if isinstance(e, loopix_connect.ConnectException):
|
|
106
|
+
if e.status == loopix_connect.Code.not_found:
|
|
107
|
+
return False
|
|
108
|
+
raise handle_rpc_exception_with_health(e, self._check_health)
|
|
109
|
+
|
|
110
|
+
def send_stdin(
|
|
111
|
+
self,
|
|
112
|
+
pid: int,
|
|
113
|
+
data: bytes,
|
|
114
|
+
request_timeout: Optional[float] = None,
|
|
115
|
+
) -> None:
|
|
116
|
+
"""
|
|
117
|
+
Send input to a PTY.
|
|
118
|
+
|
|
119
|
+
:param pid: Process ID of the PTY
|
|
120
|
+
:param data: Input data to send
|
|
121
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
122
|
+
"""
|
|
123
|
+
try:
|
|
124
|
+
self._rpc.send_input(
|
|
125
|
+
process_pb2.SendInputRequest(
|
|
126
|
+
process=process_pb2.ProcessSelector(pid=pid),
|
|
127
|
+
input=process_pb2.ProcessInput(
|
|
128
|
+
pty=data,
|
|
129
|
+
),
|
|
130
|
+
),
|
|
131
|
+
request_timeout=self._connection_config.get_request_timeout(
|
|
132
|
+
request_timeout
|
|
133
|
+
),
|
|
134
|
+
)
|
|
135
|
+
except Exception as e:
|
|
136
|
+
raise handle_rpc_exception_with_health(e, self._check_health)
|
|
137
|
+
|
|
138
|
+
def create(
|
|
139
|
+
self,
|
|
140
|
+
size: PtySize,
|
|
141
|
+
user: Optional[Username] = None,
|
|
142
|
+
cwd: Optional[str] = None,
|
|
143
|
+
envs: Optional[Dict[str, str]] = None,
|
|
144
|
+
timeout: Optional[float] = 60,
|
|
145
|
+
request_timeout: Optional[float] = None,
|
|
146
|
+
) -> CommandHandle:
|
|
147
|
+
"""
|
|
148
|
+
Start a new PTY (pseudo-terminal).
|
|
149
|
+
|
|
150
|
+
:param size: Size of the PTY
|
|
151
|
+
:param user: User to use for the PTY
|
|
152
|
+
:param cwd: Working directory for the PTY
|
|
153
|
+
:param envs: Environment variables for the PTY
|
|
154
|
+
:param timeout: Timeout for the PTY in **seconds**
|
|
155
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
156
|
+
|
|
157
|
+
:return: Handle to interact with the PTY
|
|
158
|
+
"""
|
|
159
|
+
envs = dict(envs) if envs else {}
|
|
160
|
+
envs.setdefault("TERM", "xterm-256color")
|
|
161
|
+
envs.setdefault("LANG", "C.UTF-8")
|
|
162
|
+
envs.setdefault("LC_ALL", "C.UTF-8")
|
|
163
|
+
events = self._rpc.start(
|
|
164
|
+
process_pb2.StartRequest(
|
|
165
|
+
process=process_pb2.ProcessConfig(
|
|
166
|
+
cmd="/bin/bash",
|
|
167
|
+
envs=envs,
|
|
168
|
+
args=["-i", "-l"],
|
|
169
|
+
cwd=cwd,
|
|
170
|
+
),
|
|
171
|
+
pty=process_pb2.PTY(
|
|
172
|
+
size=process_pb2.PTY.Size(rows=size.rows, cols=size.cols)
|
|
173
|
+
),
|
|
174
|
+
),
|
|
175
|
+
headers={
|
|
176
|
+
**authentication_header(self._envd_version, user),
|
|
177
|
+
KEEPALIVE_PING_HEADER: str(KEEPALIVE_PING_INTERVAL_SEC),
|
|
178
|
+
},
|
|
179
|
+
timeout=timeout,
|
|
180
|
+
request_timeout=self._connection_config.get_request_timeout(
|
|
181
|
+
request_timeout
|
|
182
|
+
),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
try:
|
|
186
|
+
start_event = events.__next__()
|
|
187
|
+
|
|
188
|
+
if not start_event.HasField("event"):
|
|
189
|
+
raise SandboxException(
|
|
190
|
+
f"Failed to start process: expected start event, got {start_event}"
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
return CommandHandle(
|
|
194
|
+
pid=start_event.event.start.pid,
|
|
195
|
+
handle_kill=lambda: self.kill(start_event.event.start.pid),
|
|
196
|
+
events=events,
|
|
197
|
+
check_health=self._check_health,
|
|
198
|
+
)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
try:
|
|
201
|
+
events.close()
|
|
202
|
+
except Exception:
|
|
203
|
+
pass
|
|
204
|
+
raise handle_rpc_exception_with_health(e, self._check_health)
|
|
205
|
+
|
|
206
|
+
def connect(
|
|
207
|
+
self,
|
|
208
|
+
pid: int,
|
|
209
|
+
timeout: Optional[float] = 60,
|
|
210
|
+
request_timeout: Optional[float] = None,
|
|
211
|
+
) -> CommandHandle:
|
|
212
|
+
"""
|
|
213
|
+
Connect to a running PTY.
|
|
214
|
+
|
|
215
|
+
:param pid: Process ID of the PTY to connect to. You can get the list of running PTYs using `sandbox.pty.list()`.
|
|
216
|
+
:param timeout: Timeout for the PTY connection in **seconds**. Using `0` will not limit the connection time
|
|
217
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
218
|
+
|
|
219
|
+
:return: Handle to interact with the PTY
|
|
220
|
+
"""
|
|
221
|
+
events = self._rpc.connect(
|
|
222
|
+
process_pb2.ConnectRequest(
|
|
223
|
+
process=process_pb2.ProcessSelector(pid=pid),
|
|
224
|
+
),
|
|
225
|
+
headers={
|
|
226
|
+
KEEPALIVE_PING_HEADER: str(KEEPALIVE_PING_INTERVAL_SEC),
|
|
227
|
+
},
|
|
228
|
+
timeout=timeout,
|
|
229
|
+
request_timeout=self._connection_config.get_request_timeout(
|
|
230
|
+
request_timeout
|
|
231
|
+
),
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
try:
|
|
235
|
+
start_event = events.__next__()
|
|
236
|
+
|
|
237
|
+
if not start_event.HasField("event"):
|
|
238
|
+
raise SandboxException(
|
|
239
|
+
f"Failed to connect to process: expected start event, got {start_event}"
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
return CommandHandle(
|
|
243
|
+
pid=start_event.event.start.pid,
|
|
244
|
+
handle_kill=lambda: self.kill(start_event.event.start.pid),
|
|
245
|
+
events=events,
|
|
246
|
+
check_health=self._check_health,
|
|
247
|
+
)
|
|
248
|
+
except Exception as e:
|
|
249
|
+
try:
|
|
250
|
+
events.close()
|
|
251
|
+
except Exception:
|
|
252
|
+
pass
|
|
253
|
+
raise handle_rpc_exception_with_health(e, self._check_health)
|
|
254
|
+
|
|
255
|
+
def resize(
|
|
256
|
+
self,
|
|
257
|
+
pid: int,
|
|
258
|
+
size: PtySize,
|
|
259
|
+
request_timeout: Optional[float] = None,
|
|
260
|
+
) -> None:
|
|
261
|
+
"""
|
|
262
|
+
Resize PTY.
|
|
263
|
+
Call this when the terminal window is resized and the number of columns and rows has changed.
|
|
264
|
+
|
|
265
|
+
:param pid: Process ID of the PTY
|
|
266
|
+
:param size: New size of the PTY
|
|
267
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
268
|
+
"""
|
|
269
|
+
self._rpc.update(
|
|
270
|
+
process_pb2.UpdateRequest(
|
|
271
|
+
process=process_pb2.ProcessSelector(pid=pid),
|
|
272
|
+
pty=process_pb2.PTY(
|
|
273
|
+
size=process_pb2.PTY.Size(rows=size.rows, cols=size.cols),
|
|
274
|
+
),
|
|
275
|
+
),
|
|
276
|
+
request_timeout=self._connection_config.get_request_timeout(
|
|
277
|
+
request_timeout
|
|
278
|
+
),
|
|
279
|
+
)
|