scalebox-sdk 0.1.4__py3-none-any.whl → 0.1.25__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.
- scalebox/__init__.py +1 -1
- scalebox/api/__init__.py +128 -128
- scalebox/api/client/__init__.py +8 -8
- scalebox/api/client/api/sandboxes/get_sandboxes.py +5 -3
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +2 -2
- scalebox/api/client/api/sandboxes/post_sandboxes.py +2 -2
- scalebox/api/client/client.py +288 -288
- scalebox/api/client/models/listed_sandbox.py +11 -9
- scalebox/api/client/models/new_sandbox.py +1 -1
- scalebox/api/client/models/sandbox.py +125 -125
- scalebox/api/client/models/sandbox_state.py +1 -0
- scalebox/api/client/types.py +46 -46
- scalebox/code_interpreter/code_interpreter_async.py +370 -369
- scalebox/code_interpreter/code_interpreter_sync.py +318 -317
- scalebox/connection_config.py +92 -92
- scalebox/csx_desktop/main.py +12 -12
- scalebox/generated/api_pb2_connect.py +17 -66
- scalebox/sandbox_async/commands/command.py +307 -307
- scalebox/sandbox_async/commands/command_handle.py +187 -187
- scalebox/sandbox_async/commands/pty.py +187 -187
- scalebox/sandbox_async/filesystem/filesystem.py +557 -557
- scalebox/sandbox_async/filesystem/watch_handle.py +61 -61
- scalebox/sandbox_async/main.py +647 -646
- scalebox/sandbox_async/sandbox_api.py +365 -365
- scalebox/sandbox_async/utils.py +7 -7
- scalebox/sandbox_sync/__init__.py +2 -2
- scalebox/sandbox_sync/commands/command.py +300 -300
- scalebox/sandbox_sync/commands/command_handle.py +150 -150
- scalebox/sandbox_sync/commands/pty.py +181 -181
- scalebox/sandbox_sync/filesystem/filesystem.py +543 -543
- scalebox/sandbox_sync/filesystem/watch_handle.py +66 -66
- scalebox/sandbox_sync/main.py +789 -790
- scalebox/sandbox_sync/sandbox_api.py +356 -356
- scalebox/test/CODE_INTERPRETER_TESTS_READY.md +256 -256
- scalebox/test/README.md +164 -164
- scalebox/test/aclient.py +72 -72
- scalebox/test/code_interpreter_centext.py +21 -21
- scalebox/test/code_interpreter_centext_sync.py +21 -21
- scalebox/test/code_interpreter_test.py +1 -1
- scalebox/test/code_interpreter_test_sync.py +1 -1
- scalebox/test/run_all_validation_tests.py +334 -334
- scalebox/test/test_basic.py +78 -78
- scalebox/test/test_code_interpreter_async_comprehensive.py +2653 -2653
- scalebox/test/{test_code_interpreter_e2bsync_comprehensive.py → test_code_interpreter_execcode.py} +328 -392
- scalebox/test/test_code_interpreter_sync_comprehensive.py +3416 -3412
- scalebox/test/test_csx_desktop_examples.py +130 -0
- scalebox/test/test_sandbox_async_comprehensive.py +736 -738
- scalebox/test/test_sandbox_stress_and_edge_cases.py +778 -778
- scalebox/test/test_sandbox_sync_comprehensive.py +779 -770
- scalebox/test/test_sandbox_usage_examples.py +987 -987
- scalebox/test/testacreate.py +24 -24
- scalebox/test/testagetinfo.py +18 -18
- scalebox/test/testcodeinterpreter_async.py +508 -508
- scalebox/test/testcodeinterpreter_sync.py +239 -239
- scalebox/test/testcomputeuse.py +2 -2
- scalebox/test/testnovnc.py +12 -12
- scalebox/test/testsandbox_api.py +15 -0
- scalebox/test/testsandbox_async.py +202 -118
- scalebox/test/testsandbox_sync.py +71 -38
- scalebox/version.py +2 -2
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/METADATA +104 -103
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/RECORD +66 -66
- scalebox/test/test_code_interpreter_e2basync_comprehensive.py +0 -2655
- scalebox/test/test_e2b_first.py +0 -11
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/WHEEL +0 -0
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/entry_points.txt +0 -0
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/licenses/LICENSE +0 -0
- {scalebox_sdk-0.1.4.dist-info → scalebox_sdk-0.1.25.dist-info}/top_level.txt +0 -0
|
@@ -1,187 +1,187 @@
|
|
|
1
|
-
from typing import Dict, Optional
|
|
2
|
-
|
|
3
|
-
import aiohttp
|
|
4
|
-
|
|
5
|
-
from ... import csx_connect
|
|
6
|
-
from ...connection_config import (
|
|
7
|
-
KEEPALIVE_PING_HEADER,
|
|
8
|
-
KEEPALIVE_PING_INTERVAL_SEC,
|
|
9
|
-
ConnectionConfig,
|
|
10
|
-
Username,
|
|
11
|
-
)
|
|
12
|
-
from ...exceptions import SandboxException
|
|
13
|
-
from ...generated import api_pb2, api_pb2_connect
|
|
14
|
-
from ...generated.rpc import authentication_header, handle_rpc_exception
|
|
15
|
-
from ...sandbox.commands.command_handle import PtySize
|
|
16
|
-
from ...sandbox_async.commands.command_handle import (
|
|
17
|
-
AsyncCommandHandle,
|
|
18
|
-
OutputHandler,
|
|
19
|
-
PtyOutput,
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
class Pty:
|
|
24
|
-
"""
|
|
25
|
-
Module for interacting with PTYs (pseudo-terminals) in the sandbox.
|
|
26
|
-
"""
|
|
27
|
-
|
|
28
|
-
def __init__(
|
|
29
|
-
self,
|
|
30
|
-
envd_api_url: str,
|
|
31
|
-
connection_config: ConnectionConfig,
|
|
32
|
-
pool: aiohttp.ClientSession,
|
|
33
|
-
) -> None:
|
|
34
|
-
self._connection_config = connection_config
|
|
35
|
-
self._rpc = api_pb2_connect.AsyncProcessClient(
|
|
36
|
-
envd_api_url,
|
|
37
|
-
pool
|
|
38
|
-
)
|
|
39
|
-
self._headers = connection_config.headers
|
|
40
|
-
self._pool = pool
|
|
41
|
-
|
|
42
|
-
async def kill(
|
|
43
|
-
self,
|
|
44
|
-
pid: int,
|
|
45
|
-
request_timeout: Optional[float] = None,
|
|
46
|
-
) -> bool:
|
|
47
|
-
"""
|
|
48
|
-
Kill PTY.
|
|
49
|
-
|
|
50
|
-
:param pid: Process ID of the PTY
|
|
51
|
-
:param request_timeout: Timeout for the request in **seconds**
|
|
52
|
-
|
|
53
|
-
:return: `true` if the PTY was killed, `false` if the PTY was not found
|
|
54
|
-
"""
|
|
55
|
-
try:
|
|
56
|
-
await self._rpc.send_signal(
|
|
57
|
-
api_pb2.SendSignalRequest(
|
|
58
|
-
process=api_pb2.ProcessSelector(pid=pid),
|
|
59
|
-
signal=api_pb2.Signal.SIGNAL_SIGKILL,
|
|
60
|
-
),
|
|
61
|
-
self._headers,
|
|
62
|
-
timeout_seconds=self._connection_config.get_request_timeout(
|
|
63
|
-
request_timeout
|
|
64
|
-
),
|
|
65
|
-
)
|
|
66
|
-
return True
|
|
67
|
-
except Exception as e:
|
|
68
|
-
if isinstance(e, csx_connect.ConnectException):
|
|
69
|
-
if e.status == csx_connect.Code.not_found:
|
|
70
|
-
return False
|
|
71
|
-
raise handle_rpc_exception(e)
|
|
72
|
-
|
|
73
|
-
async def send_stdin(
|
|
74
|
-
self,
|
|
75
|
-
pid: int,
|
|
76
|
-
data: bytes,
|
|
77
|
-
request_timeout: Optional[float] = None,
|
|
78
|
-
) -> None:
|
|
79
|
-
"""
|
|
80
|
-
Send input to a PTY.
|
|
81
|
-
|
|
82
|
-
:param pid: Process ID of the PTY
|
|
83
|
-
:param data: Input data to send
|
|
84
|
-
:param request_timeout: Timeout for the request in **seconds**
|
|
85
|
-
"""
|
|
86
|
-
try:
|
|
87
|
-
await self._rpc.send_input(
|
|
88
|
-
api_pb2.SendInputRequest(
|
|
89
|
-
process=api_pb2.ProcessSelector(pid=pid),
|
|
90
|
-
input=api_pb2.ProcessInput(
|
|
91
|
-
pty=data,
|
|
92
|
-
),
|
|
93
|
-
),
|
|
94
|
-
self._headers,
|
|
95
|
-
timeout_seconds=self._connection_config.get_request_timeout(
|
|
96
|
-
request_timeout
|
|
97
|
-
),
|
|
98
|
-
)
|
|
99
|
-
except Exception as e:
|
|
100
|
-
raise handle_rpc_exception(e)
|
|
101
|
-
|
|
102
|
-
async def create(
|
|
103
|
-
self,
|
|
104
|
-
size: PtySize,
|
|
105
|
-
on_data: OutputHandler[PtyOutput],
|
|
106
|
-
user: Username = "user",
|
|
107
|
-
cwd: Optional[str] = None,
|
|
108
|
-
envs: Optional[Dict[str, str]] = None,
|
|
109
|
-
timeout: Optional[float] = 60,
|
|
110
|
-
request_timeout: Optional[float] = None,
|
|
111
|
-
) -> AsyncCommandHandle:
|
|
112
|
-
"""
|
|
113
|
-
Start a new PTY (pseudo-terminal).
|
|
114
|
-
|
|
115
|
-
:param size: Size of the PTY
|
|
116
|
-
:param on_data: Callback to handle PTY data
|
|
117
|
-
:param user: User to use for the PTY
|
|
118
|
-
:param cwd: Working directory for the PTY
|
|
119
|
-
:param envs: Environment variables for the PTY
|
|
120
|
-
:param timeout: Timeout for the PTY in **seconds**
|
|
121
|
-
:param request_timeout: Timeout for the request in **seconds**
|
|
122
|
-
|
|
123
|
-
:return: Handle to interact with the PTY
|
|
124
|
-
"""
|
|
125
|
-
envs = envs or {}
|
|
126
|
-
envs["TERM"] = "xterm-256color"
|
|
127
|
-
events = self._rpc.start(
|
|
128
|
-
api_pb2.StartRequest(
|
|
129
|
-
process=api_pb2.ProcessConfig(
|
|
130
|
-
cmd="/bin/bash",
|
|
131
|
-
envs=envs,
|
|
132
|
-
args=["-i", "-l"],
|
|
133
|
-
cwd=cwd,
|
|
134
|
-
),
|
|
135
|
-
pty=api_pb2.PTY(
|
|
136
|
-
size=api_pb2.PTY.Size(rows=size.rows, cols=size.cols)
|
|
137
|
-
),
|
|
138
|
-
),
|
|
139
|
-
self._headers,
|
|
140
|
-
timeout_seconds=self._connection_config.get_request_timeout(
|
|
141
|
-
request_timeout
|
|
142
|
-
),
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
try:
|
|
146
|
-
start_event = await events.__anext__()
|
|
147
|
-
|
|
148
|
-
if not start_event.HasField("event"):
|
|
149
|
-
raise SandboxException(
|
|
150
|
-
f"Failed to start process: expected start event, got {start_event}"
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
return AsyncCommandHandle(
|
|
154
|
-
pid=start_event.event.start.pid,
|
|
155
|
-
handle_kill=lambda: self.kill(start_event.event.start.pid),
|
|
156
|
-
events=events,
|
|
157
|
-
on_pty=on_data,
|
|
158
|
-
)
|
|
159
|
-
except Exception as e:
|
|
160
|
-
raise handle_rpc_exception(e)
|
|
161
|
-
|
|
162
|
-
async def resize(
|
|
163
|
-
self,
|
|
164
|
-
pid: int,
|
|
165
|
-
size: PtySize,
|
|
166
|
-
request_timeout: Optional[float] = None,
|
|
167
|
-
):
|
|
168
|
-
"""
|
|
169
|
-
Resize PTY.
|
|
170
|
-
Call this when the terminal window is resized and the number of columns and rows has changed.
|
|
171
|
-
|
|
172
|
-
:param pid: Process ID of the PTY
|
|
173
|
-
:param size: New size of the PTY
|
|
174
|
-
:param request_timeout: Timeout for the request in **seconds**
|
|
175
|
-
"""
|
|
176
|
-
await self._rpc.update(
|
|
177
|
-
api_pb2.UpdateRequest(
|
|
178
|
-
process=api_pb2.ProcessSelector(pid=pid),
|
|
179
|
-
pty=api_pb2.PTY(
|
|
180
|
-
size=api_pb2.PTY.Size(rows=size.rows, cols=size.cols),
|
|
181
|
-
),
|
|
182
|
-
),
|
|
183
|
-
self._headers,
|
|
184
|
-
timeout_seconds=self._connection_config.get_request_timeout(
|
|
185
|
-
request_timeout
|
|
186
|
-
),
|
|
187
|
-
)
|
|
1
|
+
from typing import Dict, Optional
|
|
2
|
+
|
|
3
|
+
import aiohttp
|
|
4
|
+
|
|
5
|
+
from ... import csx_connect
|
|
6
|
+
from ...connection_config import (
|
|
7
|
+
KEEPALIVE_PING_HEADER,
|
|
8
|
+
KEEPALIVE_PING_INTERVAL_SEC,
|
|
9
|
+
ConnectionConfig,
|
|
10
|
+
Username,
|
|
11
|
+
)
|
|
12
|
+
from ...exceptions import SandboxException
|
|
13
|
+
from ...generated import api_pb2, api_pb2_connect
|
|
14
|
+
from ...generated.rpc import authentication_header, handle_rpc_exception
|
|
15
|
+
from ...sandbox.commands.command_handle import PtySize
|
|
16
|
+
from ...sandbox_async.commands.command_handle import (
|
|
17
|
+
AsyncCommandHandle,
|
|
18
|
+
OutputHandler,
|
|
19
|
+
PtyOutput,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Pty:
|
|
24
|
+
"""
|
|
25
|
+
Module for interacting with PTYs (pseudo-terminals) in the sandbox.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
envd_api_url: str,
|
|
31
|
+
connection_config: ConnectionConfig,
|
|
32
|
+
pool: aiohttp.ClientSession,
|
|
33
|
+
) -> None:
|
|
34
|
+
self._connection_config = connection_config
|
|
35
|
+
self._rpc = api_pb2_connect.AsyncProcessClient(
|
|
36
|
+
envd_api_url,
|
|
37
|
+
pool
|
|
38
|
+
)
|
|
39
|
+
self._headers = connection_config.headers
|
|
40
|
+
self._pool = pool
|
|
41
|
+
|
|
42
|
+
async def kill(
|
|
43
|
+
self,
|
|
44
|
+
pid: int,
|
|
45
|
+
request_timeout: Optional[float] = None,
|
|
46
|
+
) -> bool:
|
|
47
|
+
"""
|
|
48
|
+
Kill PTY.
|
|
49
|
+
|
|
50
|
+
:param pid: Process ID of the PTY
|
|
51
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
52
|
+
|
|
53
|
+
:return: `true` if the PTY was killed, `false` if the PTY was not found
|
|
54
|
+
"""
|
|
55
|
+
try:
|
|
56
|
+
await self._rpc.send_signal(
|
|
57
|
+
api_pb2.SendSignalRequest(
|
|
58
|
+
process=api_pb2.ProcessSelector(pid=pid),
|
|
59
|
+
signal=api_pb2.Signal.SIGNAL_SIGKILL,
|
|
60
|
+
),
|
|
61
|
+
self._headers,
|
|
62
|
+
timeout_seconds=self._connection_config.get_request_timeout(
|
|
63
|
+
request_timeout
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
return True
|
|
67
|
+
except Exception as e:
|
|
68
|
+
if isinstance(e, csx_connect.ConnectException):
|
|
69
|
+
if e.status == csx_connect.Code.not_found:
|
|
70
|
+
return False
|
|
71
|
+
raise handle_rpc_exception(e)
|
|
72
|
+
|
|
73
|
+
async def send_stdin(
|
|
74
|
+
self,
|
|
75
|
+
pid: int,
|
|
76
|
+
data: bytes,
|
|
77
|
+
request_timeout: Optional[float] = None,
|
|
78
|
+
) -> None:
|
|
79
|
+
"""
|
|
80
|
+
Send input to a PTY.
|
|
81
|
+
|
|
82
|
+
:param pid: Process ID of the PTY
|
|
83
|
+
:param data: Input data to send
|
|
84
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
await self._rpc.send_input(
|
|
88
|
+
api_pb2.SendInputRequest(
|
|
89
|
+
process=api_pb2.ProcessSelector(pid=pid),
|
|
90
|
+
input=api_pb2.ProcessInput(
|
|
91
|
+
pty=data,
|
|
92
|
+
),
|
|
93
|
+
),
|
|
94
|
+
self._headers,
|
|
95
|
+
timeout_seconds=self._connection_config.get_request_timeout(
|
|
96
|
+
request_timeout
|
|
97
|
+
),
|
|
98
|
+
)
|
|
99
|
+
except Exception as e:
|
|
100
|
+
raise handle_rpc_exception(e)
|
|
101
|
+
|
|
102
|
+
async def create(
|
|
103
|
+
self,
|
|
104
|
+
size: PtySize,
|
|
105
|
+
on_data: OutputHandler[PtyOutput],
|
|
106
|
+
user: Username = "user",
|
|
107
|
+
cwd: Optional[str] = None,
|
|
108
|
+
envs: Optional[Dict[str, str]] = None,
|
|
109
|
+
timeout: Optional[float] = 60,
|
|
110
|
+
request_timeout: Optional[float] = None,
|
|
111
|
+
) -> AsyncCommandHandle:
|
|
112
|
+
"""
|
|
113
|
+
Start a new PTY (pseudo-terminal).
|
|
114
|
+
|
|
115
|
+
:param size: Size of the PTY
|
|
116
|
+
:param on_data: Callback to handle PTY data
|
|
117
|
+
:param user: User to use for the PTY
|
|
118
|
+
:param cwd: Working directory for the PTY
|
|
119
|
+
:param envs: Environment variables for the PTY
|
|
120
|
+
:param timeout: Timeout for the PTY in **seconds**
|
|
121
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
122
|
+
|
|
123
|
+
:return: Handle to interact with the PTY
|
|
124
|
+
"""
|
|
125
|
+
envs = envs or {}
|
|
126
|
+
envs["TERM"] = "xterm-256color"
|
|
127
|
+
events = self._rpc.start(
|
|
128
|
+
api_pb2.StartRequest(
|
|
129
|
+
process=api_pb2.ProcessConfig(
|
|
130
|
+
cmd="/bin/bash",
|
|
131
|
+
envs=envs,
|
|
132
|
+
args=["-i", "-l"],
|
|
133
|
+
cwd=cwd,
|
|
134
|
+
),
|
|
135
|
+
pty=api_pb2.PTY(
|
|
136
|
+
size=api_pb2.PTY.Size(rows=size.rows, cols=size.cols)
|
|
137
|
+
),
|
|
138
|
+
),
|
|
139
|
+
self._headers,
|
|
140
|
+
timeout_seconds=self._connection_config.get_request_timeout(
|
|
141
|
+
request_timeout
|
|
142
|
+
),
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
try:
|
|
146
|
+
start_event = await events.__anext__()
|
|
147
|
+
|
|
148
|
+
if not start_event.HasField("event"):
|
|
149
|
+
raise SandboxException(
|
|
150
|
+
f"Failed to start process: expected start event, got {start_event}"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
return AsyncCommandHandle(
|
|
154
|
+
pid=start_event.event.start.pid,
|
|
155
|
+
handle_kill=lambda: self.kill(start_event.event.start.pid),
|
|
156
|
+
events=events,
|
|
157
|
+
on_pty=on_data,
|
|
158
|
+
)
|
|
159
|
+
except Exception as e:
|
|
160
|
+
raise handle_rpc_exception(e)
|
|
161
|
+
|
|
162
|
+
async def resize(
|
|
163
|
+
self,
|
|
164
|
+
pid: int,
|
|
165
|
+
size: PtySize,
|
|
166
|
+
request_timeout: Optional[float] = None,
|
|
167
|
+
):
|
|
168
|
+
"""
|
|
169
|
+
Resize PTY.
|
|
170
|
+
Call this when the terminal window is resized and the number of columns and rows has changed.
|
|
171
|
+
|
|
172
|
+
:param pid: Process ID of the PTY
|
|
173
|
+
:param size: New size of the PTY
|
|
174
|
+
:param request_timeout: Timeout for the request in **seconds**
|
|
175
|
+
"""
|
|
176
|
+
await self._rpc.update(
|
|
177
|
+
api_pb2.UpdateRequest(
|
|
178
|
+
process=api_pb2.ProcessSelector(pid=pid),
|
|
179
|
+
pty=api_pb2.PTY(
|
|
180
|
+
size=api_pb2.PTY.Size(rows=size.rows, cols=size.cols),
|
|
181
|
+
),
|
|
182
|
+
),
|
|
183
|
+
self._headers,
|
|
184
|
+
timeout_seconds=self._connection_config.get_request_timeout(
|
|
185
|
+
request_timeout
|
|
186
|
+
),
|
|
187
|
+
)
|