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
- import asyncio
2
- import inspect
3
- from typing import Any, AsyncIterator, Callable, Coroutine, Optional, Tuple, Union
4
-
5
- from ...generated import api_pb2
6
- from ...generated.rpc import handle_rpc_exception
7
- from ...sandbox.commands.command_handle import (
8
- CommandExitException,
9
- CommandResult,
10
- PtyOutput,
11
- Stderr,
12
- Stdout,
13
- )
14
- from ...sandbox_async.utils import OutputHandler
15
-
16
-
17
- class AsyncCommandHandle:
18
- """
19
- Command execution handle.
20
-
21
- It provides methods for waiting for the command to finish, retrieving stdout/stderr, and killing the command.
22
- """
23
-
24
- @property
25
- def pid(self):
26
- """
27
- Command process ID.
28
- """
29
- return self._pid
30
-
31
- @property
32
- def stdout(self):
33
- """
34
- Command stdout output.
35
- """
36
- return self._stdout
37
-
38
- @property
39
- def stderr(self):
40
- """
41
- Command stderr output.
42
- """
43
- return self._stderr
44
-
45
- @property
46
- def error(self):
47
- """
48
- Command execution error message.
49
- """
50
- if self._result is None:
51
- return None
52
- return self._result.error
53
-
54
- @property
55
- def exit_code(self):
56
- """
57
- Command execution exit code.
58
-
59
- `0` if the command finished successfully.
60
-
61
- It is `None` if the command is still running.
62
- """
63
- if self._result is None:
64
- return None
65
- return self._result.exit_code
66
-
67
- def __init__(
68
- self,
69
- pid: int,
70
- handle_kill: Callable[[], Coroutine[Any, Any, bool]],
71
- events: AsyncIterator[
72
- Union[api_pb2.StartResponse, api_pb2.ConnectResponse]
73
- ],
74
- on_stdout: Optional[OutputHandler[Stdout]] = None,
75
- on_stderr: Optional[OutputHandler[Stderr]] = None,
76
- on_pty: Optional[OutputHandler[PtyOutput]] = None,
77
- ):
78
- self._pid = pid
79
- self._handle_kill = handle_kill
80
- self._events = events
81
-
82
- self._stdout: str = ""
83
- self._stderr: str = ""
84
-
85
- self._on_stdout = on_stdout
86
- self._on_stderr = on_stderr
87
- self._on_pty = on_pty
88
-
89
- self._result: Optional[CommandResult] = None
90
- self._iteration_exception: Optional[Exception] = None
91
-
92
- self._wait = asyncio.create_task(self._handle_events())
93
-
94
- async def _iterate_events(
95
- self,
96
- ) -> AsyncIterator[
97
- Union[
98
- Tuple[Stdout, None, None],
99
- Tuple[None, Stderr, None],
100
- Tuple[None, None, PtyOutput],
101
- ],
102
- ]:
103
- async for event in self._events:
104
- if event.event.HasField("data"):
105
- if event.event.data.stdout:
106
- out = event.event.data.stdout.decode("utf-8", "replace")
107
- self._stdout += out
108
- yield out, None, None
109
- if event.event.data.stderr:
110
- out = event.event.data.stderr.decode("utf-8", "replace")
111
- self._stderr += out
112
- yield None, out, None
113
- if event.event.data.pty:
114
- yield None, None, event.event.data.pty
115
- if event.event.HasField("end"):
116
- self._result = CommandResult(
117
- stdout=self._stdout,
118
- stderr=self._stderr,
119
- exit_code=event.event.end.exit_code,
120
- error=event.event.end.error,
121
- )
122
-
123
- async def disconnect(self) -> None:
124
- """
125
- Disconnects from the command.
126
-
127
- The command is not killed, but SDK stops receiving events from the command.
128
- You can reconnect to the command using `sandbox.commands.connect` method.
129
- """
130
- self._wait.cancel()
131
- # BUG: In Python 3.8 closing async generator can throw RuntimeError.
132
- # await self._events.aclose()
133
-
134
- async def _handle_events(self):
135
- try:
136
- async for stdout, stderr, pty in self._iterate_events():
137
- if stdout is not None and self._on_stdout:
138
- cb = self._on_stdout(stdout)
139
- if inspect.isawaitable(cb):
140
- await cb
141
- elif stderr is not None and self._on_stderr:
142
- cb = self._on_stderr(stderr)
143
- if inspect.isawaitable(cb):
144
- await cb
145
- elif pty is not None and self._on_pty:
146
- cb = self._on_pty(pty)
147
- if inspect.isawaitable(cb):
148
- await cb
149
- except StopAsyncIteration:
150
- pass
151
- except Exception as e:
152
- self._iteration_exception = handle_rpc_exception(e)
153
-
154
- async def wait(self) -> CommandResult:
155
- """
156
- Wait for the command to finish and return the result.
157
- If the command exits with a non-zero exit code, it throws a `CommandExitException`.
158
-
159
- :return: `CommandResult` result of command execution
160
- """
161
- await self._wait
162
- if self._iteration_exception:
163
- raise self._iteration_exception
164
-
165
- if self._result is None:
166
- raise Exception("Command ended without an end event")
167
-
168
- if self._result.exit_code != 0:
169
- raise CommandExitException(
170
- stdout=self._stdout,
171
- stderr=self._stderr,
172
- exit_code=self._result.exit_code,
173
- error=self._result.error,
174
- )
175
-
176
- return self._result
177
-
178
- async def kill(self) -> bool:
179
- """
180
- Kills the command.
181
-
182
- It uses `SIGKILL` signal to kill the command
183
-
184
- :return: `True` if the command was killed successfully, `False` if the command was not found
185
- """
186
- result = await self._handle_kill()
187
- return result
1
+ import asyncio
2
+ import inspect
3
+ from typing import Any, AsyncIterator, Callable, Coroutine, Optional, Tuple, Union
4
+
5
+ from ...generated import api_pb2
6
+ from ...generated.rpc import handle_rpc_exception
7
+ from ...sandbox.commands.command_handle import (
8
+ CommandExitException,
9
+ CommandResult,
10
+ PtyOutput,
11
+ Stderr,
12
+ Stdout,
13
+ )
14
+ from ...sandbox_async.utils import OutputHandler
15
+
16
+
17
+ class AsyncCommandHandle:
18
+ """
19
+ Command execution handle.
20
+
21
+ It provides methods for waiting for the command to finish, retrieving stdout/stderr, and killing the command.
22
+ """
23
+
24
+ @property
25
+ def pid(self):
26
+ """
27
+ Command process ID.
28
+ """
29
+ return self._pid
30
+
31
+ @property
32
+ def stdout(self):
33
+ """
34
+ Command stdout output.
35
+ """
36
+ return self._stdout
37
+
38
+ @property
39
+ def stderr(self):
40
+ """
41
+ Command stderr output.
42
+ """
43
+ return self._stderr
44
+
45
+ @property
46
+ def error(self):
47
+ """
48
+ Command execution error message.
49
+ """
50
+ if self._result is None:
51
+ return None
52
+ return self._result.error
53
+
54
+ @property
55
+ def exit_code(self):
56
+ """
57
+ Command execution exit code.
58
+
59
+ `0` if the command finished successfully.
60
+
61
+ It is `None` if the command is still running.
62
+ """
63
+ if self._result is None:
64
+ return None
65
+ return self._result.exit_code
66
+
67
+ def __init__(
68
+ self,
69
+ pid: int,
70
+ handle_kill: Callable[[], Coroutine[Any, Any, bool]],
71
+ events: AsyncIterator[
72
+ Union[api_pb2.StartResponse, api_pb2.ConnectResponse]
73
+ ],
74
+ on_stdout: Optional[OutputHandler[Stdout]] = None,
75
+ on_stderr: Optional[OutputHandler[Stderr]] = None,
76
+ on_pty: Optional[OutputHandler[PtyOutput]] = None,
77
+ ):
78
+ self._pid = pid
79
+ self._handle_kill = handle_kill
80
+ self._events = events
81
+
82
+ self._stdout: str = ""
83
+ self._stderr: str = ""
84
+
85
+ self._on_stdout = on_stdout
86
+ self._on_stderr = on_stderr
87
+ self._on_pty = on_pty
88
+
89
+ self._result: Optional[CommandResult] = None
90
+ self._iteration_exception: Optional[Exception] = None
91
+
92
+ self._wait = asyncio.create_task(self._handle_events())
93
+
94
+ async def _iterate_events(
95
+ self,
96
+ ) -> AsyncIterator[
97
+ Union[
98
+ Tuple[Stdout, None, None],
99
+ Tuple[None, Stderr, None],
100
+ Tuple[None, None, PtyOutput],
101
+ ],
102
+ ]:
103
+ async for event in self._events:
104
+ if event.event.HasField("data"):
105
+ if event.event.data.stdout:
106
+ out = event.event.data.stdout.decode("utf-8", "replace")
107
+ self._stdout += out
108
+ yield out, None, None
109
+ if event.event.data.stderr:
110
+ out = event.event.data.stderr.decode("utf-8", "replace")
111
+ self._stderr += out
112
+ yield None, out, None
113
+ if event.event.data.pty:
114
+ yield None, None, event.event.data.pty
115
+ if event.event.HasField("end"):
116
+ self._result = CommandResult(
117
+ stdout=self._stdout,
118
+ stderr=self._stderr,
119
+ exit_code=event.event.end.exit_code,
120
+ error=event.event.end.error,
121
+ )
122
+
123
+ async def disconnect(self) -> None:
124
+ """
125
+ Disconnects from the command.
126
+
127
+ The command is not killed, but SDK stops receiving events from the command.
128
+ You can reconnect to the command using `sandbox.commands.connect` method.
129
+ """
130
+ self._wait.cancel()
131
+ # BUG: In Python 3.8 closing async generator can throw RuntimeError.
132
+ # await self._events.aclose()
133
+
134
+ async def _handle_events(self):
135
+ try:
136
+ async for stdout, stderr, pty in self._iterate_events():
137
+ if stdout is not None and self._on_stdout:
138
+ cb = self._on_stdout(stdout)
139
+ if inspect.isawaitable(cb):
140
+ await cb
141
+ elif stderr is not None and self._on_stderr:
142
+ cb = self._on_stderr(stderr)
143
+ if inspect.isawaitable(cb):
144
+ await cb
145
+ elif pty is not None and self._on_pty:
146
+ cb = self._on_pty(pty)
147
+ if inspect.isawaitable(cb):
148
+ await cb
149
+ except StopAsyncIteration:
150
+ pass
151
+ except Exception as e:
152
+ self._iteration_exception = handle_rpc_exception(e)
153
+
154
+ async def wait(self) -> CommandResult:
155
+ """
156
+ Wait for the command to finish and return the result.
157
+ If the command exits with a non-zero exit code, it throws a `CommandExitException`.
158
+
159
+ :return: `CommandResult` result of command execution
160
+ """
161
+ await self._wait
162
+ if self._iteration_exception:
163
+ raise self._iteration_exception
164
+
165
+ if self._result is None:
166
+ raise Exception("Command ended without an end event")
167
+
168
+ if self._result.exit_code != 0:
169
+ raise CommandExitException(
170
+ stdout=self._stdout,
171
+ stderr=self._stderr,
172
+ exit_code=self._result.exit_code,
173
+ error=self._result.error,
174
+ )
175
+
176
+ return self._result
177
+
178
+ async def kill(self) -> bool:
179
+ """
180
+ Kills the command.
181
+
182
+ It uses `SIGKILL` signal to kill the command
183
+
184
+ :return: `True` if the command was killed successfully, `False` if the command was not found
185
+ """
186
+ result = await self._handle_kill()
187
+ return result