scalebox-sdk 0.1.24__py3-none-any.whl → 1.0.1__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.
Files changed (87) hide show
  1. scalebox/__init__.py +2 -2
  2. scalebox/api/__init__.py +130 -128
  3. scalebox/api/client/__init__.py +8 -8
  4. scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +2 -2
  5. scalebox/api/client/api/sandboxes/post_sandboxes.py +2 -2
  6. scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +193 -0
  7. scalebox/api/client/client.py +288 -288
  8. scalebox/api/client/models/connect_sandbox.py +59 -0
  9. scalebox/api/client/models/error.py +2 -2
  10. scalebox/api/client/models/listed_sandbox.py +19 -1
  11. scalebox/api/client/models/new_sandbox.py +10 -0
  12. scalebox/api/client/models/sandbox.py +138 -125
  13. scalebox/api/client/models/sandbox_detail.py +24 -0
  14. scalebox/api/client/types.py +46 -46
  15. scalebox/cli.py +125 -125
  16. scalebox/client/aclient.py +57 -57
  17. scalebox/client/client.py +102 -102
  18. scalebox/code_interpreter/__init__.py +12 -12
  19. scalebox/code_interpreter/charts.py +230 -230
  20. scalebox/code_interpreter/constants.py +3 -3
  21. scalebox/code_interpreter/exceptions.py +13 -13
  22. scalebox/code_interpreter/models.py +485 -485
  23. scalebox/connection_config.py +34 -1
  24. scalebox/csx_connect/__init__.py +1 -1
  25. scalebox/csx_connect/client.py +485 -485
  26. scalebox/csx_desktop/main.py +651 -651
  27. scalebox/exceptions.py +83 -83
  28. scalebox/generated/api.py +61 -61
  29. scalebox/generated/api_pb2.py +203 -203
  30. scalebox/generated/api_pb2.pyi +956 -956
  31. scalebox/generated/api_pb2_connect.py +1407 -1407
  32. scalebox/generated/rpc.py +50 -50
  33. scalebox/sandbox/main.py +146 -139
  34. scalebox/sandbox/sandbox_api.py +105 -91
  35. scalebox/sandbox/signature.py +40 -40
  36. scalebox/sandbox/utils.py +34 -34
  37. scalebox/sandbox_async/commands/command.py +307 -307
  38. scalebox/sandbox_async/commands/command_handle.py +187 -187
  39. scalebox/sandbox_async/commands/pty.py +187 -187
  40. scalebox/sandbox_async/filesystem/filesystem.py +557 -557
  41. scalebox/sandbox_async/filesystem/watch_handle.py +61 -61
  42. scalebox/sandbox_async/main.py +228 -46
  43. scalebox/sandbox_async/sandbox_api.py +124 -3
  44. scalebox/sandbox_async/utils.py +7 -7
  45. scalebox/sandbox_sync/__init__.py +2 -2
  46. scalebox/sandbox_sync/commands/command.py +300 -300
  47. scalebox/sandbox_sync/commands/command_handle.py +150 -150
  48. scalebox/sandbox_sync/commands/pty.py +181 -181
  49. scalebox/sandbox_sync/filesystem/filesystem.py +3 -3
  50. scalebox/sandbox_sync/filesystem/watch_handle.py +66 -66
  51. scalebox/sandbox_sync/main.py +208 -133
  52. scalebox/sandbox_sync/sandbox_api.py +119 -3
  53. scalebox/test/CODE_INTERPRETER_TESTS_READY.md +323 -323
  54. scalebox/test/README.md +329 -329
  55. scalebox/test/bedrock_openai_adapter.py +67 -0
  56. scalebox/test/code_interpreter_test.py +34 -34
  57. scalebox/test/code_interpreter_test_sync.py +34 -34
  58. scalebox/test/run_stress_code_interpreter_sync.py +166 -0
  59. scalebox/test/simple_upload_example.py +123 -0
  60. scalebox/test/stabitiy_test.py +310 -0
  61. scalebox/test/test_browser_use.py +25 -0
  62. scalebox/test/test_browser_use_scalebox.py +61 -0
  63. scalebox/test/test_code_interpreter_sync_comprehensive.py +115 -65
  64. scalebox/test/test_connect_pause_async.py +277 -0
  65. scalebox/test/test_connect_pause_sync.py +267 -0
  66. scalebox/test/test_desktop_sandbox_sf.py +117 -0
  67. scalebox/test/test_download_url.py +49 -0
  68. scalebox/test/test_sandbox_async_comprehensive.py +1 -1
  69. scalebox/test/test_sandbox_object_storage_example.py +146 -0
  70. scalebox/test/test_sandbox_object_storage_example_async.py +156 -0
  71. scalebox/test/test_sf.py +137 -0
  72. scalebox/test/test_watch_dir_async.py +56 -0
  73. scalebox/test/testacreate.py +1 -1
  74. scalebox/test/testagetinfo.py +1 -1
  75. scalebox/test/testcomputeuse.py +243 -243
  76. scalebox/test/testsandbox_api.py +13 -0
  77. scalebox/test/testsandbox_sync.py +1 -1
  78. scalebox/test/upload_100mb_example.py +355 -0
  79. scalebox/utils/httpcoreclient.py +297 -297
  80. scalebox/utils/httpxclient.py +403 -403
  81. scalebox/version.py +2 -2
  82. {scalebox_sdk-0.1.24.dist-info → scalebox_sdk-1.0.1.dist-info}/METADATA +1 -1
  83. {scalebox_sdk-0.1.24.dist-info → scalebox_sdk-1.0.1.dist-info}/RECORD +87 -69
  84. {scalebox_sdk-0.1.24.dist-info → scalebox_sdk-1.0.1.dist-info}/WHEEL +1 -1
  85. {scalebox_sdk-0.1.24.dist-info → scalebox_sdk-1.0.1.dist-info}/entry_points.txt +0 -0
  86. {scalebox_sdk-0.1.24.dist-info → scalebox_sdk-1.0.1.dist-info}/licenses/LICENSE +0 -0
  87. {scalebox_sdk-0.1.24.dist-info → scalebox_sdk-1.0.1.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
+ )