scalebox-sdk 0.1.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.
- scalebox/__init__.py +80 -0
- scalebox/api/__init__.py +128 -0
- scalebox/api/client/__init__.py +8 -0
- scalebox/api/client/api/__init__.py +1 -0
- scalebox/api/client/api/sandboxes/__init__.py +0 -0
- scalebox/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +161 -0
- scalebox/api/client/api/sandboxes/get_sandboxes.py +176 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_metrics.py +173 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +163 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +199 -0
- scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +214 -0
- scalebox/api/client/api/sandboxes/get_v2_sandboxes.py +229 -0
- scalebox/api/client/api/sandboxes/post_sandboxes.py +174 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +165 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +182 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +190 -0
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +194 -0
- scalebox/api/client/client.py +288 -0
- scalebox/api/client/errors.py +16 -0
- scalebox/api/client/models/__init__.py +81 -0
- scalebox/api/client/models/build_log_entry.py +79 -0
- scalebox/api/client/models/created_access_token.py +100 -0
- scalebox/api/client/models/created_team_api_key.py +166 -0
- scalebox/api/client/models/error.py +67 -0
- scalebox/api/client/models/identifier_masking_details.py +83 -0
- scalebox/api/client/models/listed_sandbox.py +138 -0
- scalebox/api/client/models/log_level.py +11 -0
- scalebox/api/client/models/new_access_token.py +59 -0
- scalebox/api/client/models/new_sandbox.py +125 -0
- scalebox/api/client/models/new_team_api_key.py +59 -0
- scalebox/api/client/models/node.py +154 -0
- scalebox/api/client/models/node_detail.py +152 -0
- scalebox/api/client/models/node_status.py +11 -0
- scalebox/api/client/models/node_status_change.py +61 -0
- scalebox/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +59 -0
- scalebox/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +59 -0
- scalebox/api/client/models/resumed_sandbox.py +68 -0
- scalebox/api/client/models/sandbox.py +125 -0
- scalebox/api/client/models/sandbox_detail.py +178 -0
- scalebox/api/client/models/sandbox_log.py +70 -0
- scalebox/api/client/models/sandbox_logs.py +73 -0
- scalebox/api/client/models/sandbox_metric.py +110 -0
- scalebox/api/client/models/sandbox_state.py +9 -0
- scalebox/api/client/models/sandboxes_with_metrics.py +59 -0
- scalebox/api/client/models/team.py +83 -0
- scalebox/api/client/models/team_api_key.py +158 -0
- scalebox/api/client/models/team_user.py +68 -0
- scalebox/api/client/models/template.py +179 -0
- scalebox/api/client/models/template_build.py +117 -0
- scalebox/api/client/models/template_build_file_upload.py +70 -0
- scalebox/api/client/models/template_build_request.py +115 -0
- scalebox/api/client/models/template_build_request_v2.py +88 -0
- scalebox/api/client/models/template_build_start_v2.py +114 -0
- scalebox/api/client/models/template_build_status.py +11 -0
- scalebox/api/client/models/template_step.py +91 -0
- scalebox/api/client/models/template_update_request.py +59 -0
- scalebox/api/client/models/update_team_api_key.py +59 -0
- scalebox/api/client/py.typed +1 -0
- scalebox/api/client/types.py +46 -0
- scalebox/api/metadata.py +19 -0
- scalebox/cli.py +125 -0
- scalebox/client/__init__.py +0 -0
- scalebox/client/aclient.py +57 -0
- scalebox/client/api.proto +460 -0
- scalebox/client/buf.gen.yaml +8 -0
- scalebox/client/client.py +102 -0
- scalebox/client/requirements.txt +5 -0
- scalebox/code_interpreter/__init__.py +12 -0
- scalebox/code_interpreter/charts.py +230 -0
- scalebox/code_interpreter/code_interpreter_async.py +369 -0
- scalebox/code_interpreter/code_interpreter_sync.py +317 -0
- scalebox/code_interpreter/constants.py +3 -0
- scalebox/code_interpreter/exceptions.py +13 -0
- scalebox/code_interpreter/models.py +485 -0
- scalebox/connection_config.py +92 -0
- scalebox/csx_connect/__init__.py +1 -0
- scalebox/csx_connect/client.py +485 -0
- scalebox/csx_desktop/__init__.py +0 -0
- scalebox/csx_desktop/main.py +651 -0
- scalebox/exceptions.py +83 -0
- scalebox/generated/__init__.py +0 -0
- scalebox/generated/api.py +61 -0
- scalebox/generated/api_pb2.py +203 -0
- scalebox/generated/api_pb2.pyi +956 -0
- scalebox/generated/api_pb2_connect.py +1456 -0
- scalebox/generated/rpc.py +50 -0
- scalebox/generated/versions.py +3 -0
- scalebox/requirements.txt +36 -0
- scalebox/sandbox/__init__.py +0 -0
- scalebox/sandbox/commands/__init__.py +0 -0
- scalebox/sandbox/commands/command_handle.py +69 -0
- scalebox/sandbox/commands/main.py +39 -0
- scalebox/sandbox/filesystem/__init__.py +0 -0
- scalebox/sandbox/filesystem/filesystem.py +95 -0
- scalebox/sandbox/filesystem/watch_handle.py +60 -0
- scalebox/sandbox/main.py +139 -0
- scalebox/sandbox/sandbox_api.py +91 -0
- scalebox/sandbox/signature.py +40 -0
- scalebox/sandbox/utils.py +34 -0
- scalebox/sandbox_async/__init__.py +1 -0
- scalebox/sandbox_async/commands/command.py +307 -0
- scalebox/sandbox_async/commands/command_handle.py +187 -0
- scalebox/sandbox_async/commands/pty.py +187 -0
- scalebox/sandbox_async/filesystem/filesystem.py +557 -0
- scalebox/sandbox_async/filesystem/watch_handle.py +61 -0
- scalebox/sandbox_async/main.py +646 -0
- scalebox/sandbox_async/sandbox_api.py +365 -0
- scalebox/sandbox_async/utils.py +7 -0
- scalebox/sandbox_sync/__init__.py +2 -0
- scalebox/sandbox_sync/commands/__init__.py +0 -0
- scalebox/sandbox_sync/commands/command.py +300 -0
- scalebox/sandbox_sync/commands/command_handle.py +150 -0
- scalebox/sandbox_sync/commands/pty.py +181 -0
- scalebox/sandbox_sync/filesystem/__init__.py +0 -0
- scalebox/sandbox_sync/filesystem/filesystem.py +543 -0
- scalebox/sandbox_sync/filesystem/watch_handle.py +66 -0
- scalebox/sandbox_sync/main.py +790 -0
- scalebox/sandbox_sync/sandbox_api.py +356 -0
- scalebox/test/CODE_INTERPRETER_TESTS_READY.md +323 -0
- scalebox/test/README.md +329 -0
- scalebox/test/__init__.py +0 -0
- scalebox/test/aclient.py +72 -0
- scalebox/test/code_interpreter_centext.py +21 -0
- scalebox/test/code_interpreter_centext_sync.py +21 -0
- scalebox/test/code_interpreter_test.py +34 -0
- scalebox/test/code_interpreter_test_sync.py +34 -0
- scalebox/test/run_all_validation_tests.py +334 -0
- scalebox/test/run_code_interpreter_tests.sh +67 -0
- scalebox/test/run_tests.sh +230 -0
- scalebox/test/test_basic.py +78 -0
- scalebox/test/test_code_interpreter_async_comprehensive.py +2653 -0
- scalebox/test/test_code_interpreter_e2basync_comprehensive.py +2655 -0
- scalebox/test/test_code_interpreter_e2bsync_comprehensive.py +3416 -0
- scalebox/test/test_code_interpreter_sync_comprehensive.py +3412 -0
- scalebox/test/test_e2b_first.py +11 -0
- scalebox/test/test_sandbox_async_comprehensive.py +738 -0
- scalebox/test/test_sandbox_stress_and_edge_cases.py +778 -0
- scalebox/test/test_sandbox_sync_comprehensive.py +770 -0
- scalebox/test/test_sandbox_usage_examples.py +987 -0
- scalebox/test/testacreate.py +24 -0
- scalebox/test/testagetinfo.py +18 -0
- scalebox/test/testcodeinterpreter_async.py +508 -0
- scalebox/test/testcodeinterpreter_sync.py +239 -0
- scalebox/test/testcomputeuse.py +243 -0
- scalebox/test/testnovnc.py +12 -0
- scalebox/test/testsandbox_async.py +118 -0
- scalebox/test/testsandbox_sync.py +38 -0
- scalebox/utils/__init__.py +0 -0
- scalebox/utils/httpcoreclient.py +297 -0
- scalebox/utils/httpxclient.py +403 -0
- scalebox/version.py +16 -0
- scalebox_sdk-0.1.0.dist-info/METADATA +292 -0
- scalebox_sdk-0.1.0.dist-info/RECORD +157 -0
- scalebox_sdk-0.1.0.dist-info/WHEEL +5 -0
- scalebox_sdk-0.1.0.dist-info/entry_points.txt +2 -0
- scalebox_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
- scalebox_sdk-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Simple sync CodeInterpreter test example.
|
|
4
|
+
Similar to testsandbox_sync.py but for code interpreter functionality.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from scalebox.code_interpreter import Context, Sandbox
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def output_handler(output):
|
|
11
|
+
"""处理输出的回调函数"""
|
|
12
|
+
print(f"输出: {output.content}")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def result_handler(result):
|
|
16
|
+
"""处理结果的回调函数"""
|
|
17
|
+
print(f"结果: {result}")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def error_handler(error):
|
|
21
|
+
"""处理错误的回调函数"""
|
|
22
|
+
print(f"错误: {error.name} - {error.value}")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# 创建代码解释器沙箱
|
|
26
|
+
sandbox = Sandbox(template="code-interpreter-v1")
|
|
27
|
+
|
|
28
|
+
print("=== 基础Python代码执行 ===")
|
|
29
|
+
# 基础Python代码执行
|
|
30
|
+
result = sandbox.run_code(
|
|
31
|
+
"""
|
|
32
|
+
print("Hello from CodeInterpreter!")
|
|
33
|
+
x = 1 + 2
|
|
34
|
+
y = x * 3
|
|
35
|
+
print(f"计算结果: x={x}, y={y}")
|
|
36
|
+
{"x": x, "y": y}
|
|
37
|
+
""",
|
|
38
|
+
language="python",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
print(f"执行结果: {result}")
|
|
42
|
+
print(f"标准输出: {result.logs.stdout}")
|
|
43
|
+
if result.error:
|
|
44
|
+
print(f"错误: {result.error}")
|
|
45
|
+
|
|
46
|
+
print("\n=== 数学计算示例 ===")
|
|
47
|
+
# 数学计算
|
|
48
|
+
math_result = sandbox.run_code(
|
|
49
|
+
"""
|
|
50
|
+
import math
|
|
51
|
+
import numpy as np
|
|
52
|
+
|
|
53
|
+
# 计算圆的面积和周长
|
|
54
|
+
radius = 5
|
|
55
|
+
area = math.pi * radius ** 2
|
|
56
|
+
circumference = 2 * math.pi * radius
|
|
57
|
+
|
|
58
|
+
print(f"半径: {radius}")
|
|
59
|
+
print(f"面积: {area:.2f}")
|
|
60
|
+
print(f"周长: {circumference:.2f}")
|
|
61
|
+
|
|
62
|
+
# 使用numpy
|
|
63
|
+
arr = np.array([1, 2, 3, 4, 5])
|
|
64
|
+
mean_val = np.mean(arr)
|
|
65
|
+
print(f"数组平均值: {mean_val}")
|
|
66
|
+
|
|
67
|
+
{"radius": radius, "area": area, "mean": mean_val}
|
|
68
|
+
"""
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
print(f"数学计算结果: {math_result}")
|
|
72
|
+
|
|
73
|
+
print("\n=== 使用回调函数 ===")
|
|
74
|
+
# 使用回调函数
|
|
75
|
+
callback_result = sandbox.run_code(
|
|
76
|
+
"""
|
|
77
|
+
print("开始执行带回调的代码")
|
|
78
|
+
for i in range(3):
|
|
79
|
+
print(f"步骤 {i+1}")
|
|
80
|
+
|
|
81
|
+
result_data = {"steps": 3, "status": "completed"}
|
|
82
|
+
print(f"执行完成: {result_data}")
|
|
83
|
+
result_data
|
|
84
|
+
""",
|
|
85
|
+
on_stdout=output_handler,
|
|
86
|
+
on_result=result_handler,
|
|
87
|
+
on_error=error_handler,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
print("\n=== 创建和使用上下文 ===")
|
|
91
|
+
# 创建上下文
|
|
92
|
+
context = sandbox.create_code_context(language="python", cwd="/tmp")
|
|
93
|
+
print(f"创建上下文: {context.id}")
|
|
94
|
+
|
|
95
|
+
# 在上下文中执行代码
|
|
96
|
+
context_result1 = sandbox.run_code(
|
|
97
|
+
"""
|
|
98
|
+
# 在上下文中定义变量
|
|
99
|
+
context_var = "Hello from context"
|
|
100
|
+
numbers = [1, 2, 3, 4, 5]
|
|
101
|
+
print(f"定义了变量: {context_var}")
|
|
102
|
+
print(f"数组: {numbers}")
|
|
103
|
+
""",
|
|
104
|
+
context=context,
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# 在同一上下文中使用变量
|
|
108
|
+
context_result2 = sandbox.run_code(
|
|
109
|
+
"""
|
|
110
|
+
print(f"从上下文读取: {context_var}")
|
|
111
|
+
numbers.append(6)
|
|
112
|
+
print(f"修改后的数组: {numbers}")
|
|
113
|
+
sum(numbers)
|
|
114
|
+
""",
|
|
115
|
+
context=context,
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
print(f"上下文测试结果: {context_result2}")
|
|
119
|
+
|
|
120
|
+
print("\n=== 错误处理示例 ===")
|
|
121
|
+
# 故意产生错误
|
|
122
|
+
error_result = sandbox.run_code(
|
|
123
|
+
"""
|
|
124
|
+
print("这行会执行")
|
|
125
|
+
x = 10 / 0 # 这里会产生除零错误
|
|
126
|
+
print("这行不会执行")
|
|
127
|
+
""",
|
|
128
|
+
on_error=error_handler,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
print(f"错误处理结果: {error_result.error}")
|
|
132
|
+
|
|
133
|
+
print("\n=== 数据处理示例 ===")
|
|
134
|
+
# 数据处理
|
|
135
|
+
data_result = sandbox.run_code(
|
|
136
|
+
"""
|
|
137
|
+
import pandas as pd
|
|
138
|
+
|
|
139
|
+
# 创建示例数据
|
|
140
|
+
data = {
|
|
141
|
+
'name': ['Alice', 'Bob', 'Charlie'],
|
|
142
|
+
'age': [25, 30, 35],
|
|
143
|
+
'city': ['New York', 'London', 'Tokyo']
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
df = pd.DataFrame(data)
|
|
147
|
+
print("数据框:")
|
|
148
|
+
print(df)
|
|
149
|
+
|
|
150
|
+
# 简单分析
|
|
151
|
+
avg_age = df['age'].mean()
|
|
152
|
+
print(f"平均年龄: {avg_age}")
|
|
153
|
+
|
|
154
|
+
{"total_people": len(df), "avg_age": avg_age}
|
|
155
|
+
"""
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
print(f"数据处理结果: {data_result}")
|
|
159
|
+
|
|
160
|
+
print("\n=== 结果格式示例 ===")
|
|
161
|
+
# 展示不同格式的结果生成
|
|
162
|
+
format_result = sandbox.run_code(
|
|
163
|
+
"""
|
|
164
|
+
import matplotlib.pyplot as plt
|
|
165
|
+
import numpy as np
|
|
166
|
+
import json
|
|
167
|
+
import base64
|
|
168
|
+
import io
|
|
169
|
+
|
|
170
|
+
print("演示多种结果格式:")
|
|
171
|
+
|
|
172
|
+
# 1. 文本格式
|
|
173
|
+
text_result = "这是文本格式的结果示例"
|
|
174
|
+
print(f"文本: {text_result}")
|
|
175
|
+
|
|
176
|
+
# 2. JSON数据格式
|
|
177
|
+
json_data = {
|
|
178
|
+
"test_name": "CodeInterpreter格式测试",
|
|
179
|
+
"formats": ["text", "json", "html", "image"],
|
|
180
|
+
"timestamp": "2024-09-17T10:30:00Z",
|
|
181
|
+
"results": {
|
|
182
|
+
"success": True,
|
|
183
|
+
"format_count": 4
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
print(f"JSON: {json.dumps(json_data, ensure_ascii=False, indent=2)}")
|
|
187
|
+
|
|
188
|
+
# 3. HTML格式示例
|
|
189
|
+
html_content = \"\"\"
|
|
190
|
+
<div class="result-demo">
|
|
191
|
+
<h3>CodeInterpreter 结果格式演示</h3>
|
|
192
|
+
<p><strong>状态:</strong> <span style="color: green;">成功</span></p>
|
|
193
|
+
<ul>
|
|
194
|
+
<li>文本格式支持</li>
|
|
195
|
+
<li>JSON数据结构</li>
|
|
196
|
+
<li>HTML内容渲染</li>
|
|
197
|
+
<li>图像base64编码</li>
|
|
198
|
+
</ul>
|
|
199
|
+
</div>
|
|
200
|
+
\"\"\"
|
|
201
|
+
print(f"HTML: {html_content[:100]}...")
|
|
202
|
+
|
|
203
|
+
# 4. 简单图像生成
|
|
204
|
+
fig, ax = plt.subplots(1, 1, figsize=(6, 4))
|
|
205
|
+
x = np.linspace(0, 2*np.pi, 50)
|
|
206
|
+
y = np.sin(x)
|
|
207
|
+
ax.plot(x, y, 'b-', linewidth=2)
|
|
208
|
+
ax.set_title('简单正弦波示例')
|
|
209
|
+
ax.grid(True)
|
|
210
|
+
|
|
211
|
+
# 转换为base64
|
|
212
|
+
img_buffer = io.BytesIO()
|
|
213
|
+
plt.savefig(img_buffer, format='png', dpi=80, bbox_inches='tight')
|
|
214
|
+
img_buffer.seek(0)
|
|
215
|
+
img_base64 = base64.b64encode(img_buffer.getvalue()).decode()
|
|
216
|
+
img_buffer.close()
|
|
217
|
+
plt.close()
|
|
218
|
+
|
|
219
|
+
print(f"图像: PNG base64编码 ({len(img_base64)} 字符)")
|
|
220
|
+
|
|
221
|
+
# 返回综合结果
|
|
222
|
+
{
|
|
223
|
+
"text": text_result,
|
|
224
|
+
"json_data": json_data,
|
|
225
|
+
"html": html_content,
|
|
226
|
+
"png_base64": img_base64[:50] + "...", # 只显示前50个字符
|
|
227
|
+
"summary": {
|
|
228
|
+
"formats_demonstrated": 4,
|
|
229
|
+
"total_size": len(text_result) + len(str(json_data)) + len(html_content) + len(img_base64),
|
|
230
|
+
"description": "多格式结果演示完成"
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
"""
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
print(f"结果格式测试: {format_result}")
|
|
237
|
+
|
|
238
|
+
print("\n=== 测试完成 ===")
|
|
239
|
+
print("CodeInterpreter基础功能测试完成!")
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import time
|
|
2
|
+
|
|
3
|
+
from scalebox.csx_desktop.main import Sandbox
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def desktop_automation_demo():
|
|
7
|
+
"""桌面自动化功能演示"""
|
|
8
|
+
|
|
9
|
+
# 1. 创建桌面沙箱实例
|
|
10
|
+
print("正在启动桌面沙箱...")
|
|
11
|
+
desktop = Sandbox(timeout=3600, template="browser-use")
|
|
12
|
+
# print(f"沙箱已启动,ID: {desktop.sandbox_id}")
|
|
13
|
+
|
|
14
|
+
# 2. 启动VNC流以便远程查看桌面
|
|
15
|
+
print("启动VNC远程桌面...")
|
|
16
|
+
time.sleep(5)
|
|
17
|
+
desktop.stream.start()
|
|
18
|
+
vnc_url = desktop.stream.get_url(auto_connect=True)
|
|
19
|
+
print(f"VNC访问URL: {vnc_url}")
|
|
20
|
+
# print(f"VNC认证密钥: {desktop.stream.get_auth_key()}")
|
|
21
|
+
|
|
22
|
+
# 等待系统完全启动
|
|
23
|
+
time.sleep(3)
|
|
24
|
+
|
|
25
|
+
# 3. 基本鼠标操作示例
|
|
26
|
+
print("执行鼠标操作...")
|
|
27
|
+
|
|
28
|
+
# 获取屏幕尺寸
|
|
29
|
+
screen_width, screen_height = desktop.get_screen_size()
|
|
30
|
+
print(f"屏幕尺寸: {screen_width}x{screen_height}")
|
|
31
|
+
|
|
32
|
+
# 移动鼠标到屏幕中心
|
|
33
|
+
center_x, center_y = screen_width // 2, screen_height // 2
|
|
34
|
+
desktop.move_mouse(center_x, center_y)
|
|
35
|
+
|
|
36
|
+
# 获取当前光标位置
|
|
37
|
+
cursor_x, cursor_y = desktop.get_cursor_position()
|
|
38
|
+
print(f"光标位置: ({cursor_x}, {cursor_y})")
|
|
39
|
+
|
|
40
|
+
# 左键点击
|
|
41
|
+
desktop.left_click(center_x, center_y)
|
|
42
|
+
|
|
43
|
+
# 右键点击
|
|
44
|
+
desktop.right_click(center_x + 100, center_y)
|
|
45
|
+
|
|
46
|
+
# 双击
|
|
47
|
+
desktop.double_click(center_x, center_y + 100)
|
|
48
|
+
|
|
49
|
+
# 鼠标拖动示例
|
|
50
|
+
desktop.drag((center_x, center_y), (center_x + 200, center_y))
|
|
51
|
+
|
|
52
|
+
# 鼠标滚动
|
|
53
|
+
desktop.scroll("down", 2) # 向下滚动2次
|
|
54
|
+
desktop.scroll("up", 1) # 向上滚动1次
|
|
55
|
+
|
|
56
|
+
# 4. 键盘输入示例
|
|
57
|
+
print("执行键盘操作...")
|
|
58
|
+
|
|
59
|
+
# 打开终端
|
|
60
|
+
desktop.launch("xfce4-terminal") # 或 xfce4-terminal
|
|
61
|
+
time.sleep(2)
|
|
62
|
+
|
|
63
|
+
# 获取当前窗口ID
|
|
64
|
+
current_window = desktop.get_current_window_id()
|
|
65
|
+
print(f"当前窗口ID: {current_window}")
|
|
66
|
+
|
|
67
|
+
# 输入命令
|
|
68
|
+
desktop.write("echo 'Hello from SBX Sandbox!'")
|
|
69
|
+
desktop.press("enter")
|
|
70
|
+
|
|
71
|
+
# 特殊按键
|
|
72
|
+
desktop.press("ctrl+shift+t") # 新建标签页
|
|
73
|
+
time.sleep(1)
|
|
74
|
+
|
|
75
|
+
desktop.write("ls -la")
|
|
76
|
+
desktop.press("enter")
|
|
77
|
+
|
|
78
|
+
# 5. 窗口管理示例
|
|
79
|
+
print("执行窗口管理操作...")
|
|
80
|
+
|
|
81
|
+
# 获取所有可见窗口
|
|
82
|
+
terminal_windows = desktop.get_application_windows("xfce4-terminal")
|
|
83
|
+
print(f"终端窗口: {terminal_windows}")
|
|
84
|
+
|
|
85
|
+
if terminal_windows:
|
|
86
|
+
# 获取窗口标题
|
|
87
|
+
window_title = desktop.get_window_title(terminal_windows[0])
|
|
88
|
+
print(f"窗口标题: {window_title}")
|
|
89
|
+
|
|
90
|
+
# 6. 启动应用程序示例
|
|
91
|
+
print("启动其他应用程序...")
|
|
92
|
+
|
|
93
|
+
# 使用gtk-launch启动应用程序
|
|
94
|
+
try:
|
|
95
|
+
desktop.launch("firefox-esr") # 启动Firefox浏览器
|
|
96
|
+
time.sleep(3)
|
|
97
|
+
|
|
98
|
+
# 在Firefox中输入URL
|
|
99
|
+
desktop.press("ctrl+l") # 聚焦地址栏
|
|
100
|
+
desktop.write("https://www.google.com")
|
|
101
|
+
desktop.press("enter")
|
|
102
|
+
|
|
103
|
+
except Exception as e:
|
|
104
|
+
print(f"启动Firefox失败: {e}")
|
|
105
|
+
|
|
106
|
+
# 7. 文件操作示例 - 创建并打开文件
|
|
107
|
+
print("执行文件操作...")
|
|
108
|
+
|
|
109
|
+
# 创建测试文件
|
|
110
|
+
test_content = """Hello World!
|
|
111
|
+
This is a test file created from SBX Sandbox SDK.
|
|
112
|
+
Current time: {time}
|
|
113
|
+
""".format(
|
|
114
|
+
time=time.ctime()
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
desktop.files.write("/tmp/test_file.txt", test_content)
|
|
118
|
+
print("已创建测试文件")
|
|
119
|
+
|
|
120
|
+
# 使用默认程序打开文件
|
|
121
|
+
# desktop.open("/tmp/test_file.txt")
|
|
122
|
+
# time.sleep(2)
|
|
123
|
+
|
|
124
|
+
# 8. 截图功能示例
|
|
125
|
+
print("执行截图操作...")
|
|
126
|
+
|
|
127
|
+
# 截取屏幕并保存为bytes
|
|
128
|
+
screenshot_bytes = desktop.screenshot(format="bytes")
|
|
129
|
+
print(f"截图大小: {len(screenshot_bytes)} 字节")
|
|
130
|
+
|
|
131
|
+
# 也可以获取截图流
|
|
132
|
+
# screenshot_stream = desktop.screenshot(format="stream")
|
|
133
|
+
# for chunk in screenshot_stream:
|
|
134
|
+
# # 处理截图数据
|
|
135
|
+
# pass
|
|
136
|
+
|
|
137
|
+
# 9. 复杂自动化脚本示例
|
|
138
|
+
print("执行复杂自动化任务...")
|
|
139
|
+
|
|
140
|
+
# 返回终端窗口
|
|
141
|
+
terminal_windows = desktop.get_application_windows("xfce4-terminal")
|
|
142
|
+
if terminal_windows:
|
|
143
|
+
# 激活终端窗口
|
|
144
|
+
desktop.commands.run(
|
|
145
|
+
f"DISPLAY={desktop._display} xdotool windowactivate {terminal_windows[0]}"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# 创建Python脚本并执行
|
|
149
|
+
python_script = """#!/usr/bin/env python3
|
|
150
|
+
import time
|
|
151
|
+
print("starting...")
|
|
152
|
+
for i in range(5):
|
|
153
|
+
print(f"count: {i}")
|
|
154
|
+
time.sleep(0.5)
|
|
155
|
+
print("success!")
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
script_path = "/tmp/automation_script.py"
|
|
159
|
+
desktop.files.write(script_path, python_script)
|
|
160
|
+
|
|
161
|
+
desktop.write(f"python3 /uploads{script_path}")
|
|
162
|
+
desktop.press("enter")
|
|
163
|
+
|
|
164
|
+
# 10. 等待和定时操作
|
|
165
|
+
print("等待操作完成...")
|
|
166
|
+
desktop.wait(2000) # 等待2秒
|
|
167
|
+
|
|
168
|
+
# 展示所有功能已完成
|
|
169
|
+
desktop.write("echo 'All successfully!'")
|
|
170
|
+
desktop.press("enter")
|
|
171
|
+
|
|
172
|
+
print("演示完成! 沙箱将在10分钟后自动关闭或按Ctrl+C提前结束")
|
|
173
|
+
|
|
174
|
+
# 保持沙箱运行以便观察
|
|
175
|
+
try:
|
|
176
|
+
time.sleep(600) # 保持10分钟
|
|
177
|
+
except KeyboardInterrupt:
|
|
178
|
+
print("提前结束沙箱会话")
|
|
179
|
+
|
|
180
|
+
# 11. 清理工作会在with语句退出时自动执行
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
# def specific_use_cases():
|
|
184
|
+
# """特定用例示例"""
|
|
185
|
+
#
|
|
186
|
+
# # 用例1: 网页自动化测试
|
|
187
|
+
# def web_automation():
|
|
188
|
+
# with Sandbox() as desktop:
|
|
189
|
+
# desktop.open("firefox")
|
|
190
|
+
# time.sleep(3)
|
|
191
|
+
# desktop.press("ctrl+l")
|
|
192
|
+
# desktop.write("https://www.google.com")
|
|
193
|
+
# desktop.press("enter")
|
|
194
|
+
# time.sleep(2)
|
|
195
|
+
# desktop.write("E2B Sandbox Automation")
|
|
196
|
+
# desktop.press("enter")
|
|
197
|
+
# # 更多网页自动化操作...
|
|
198
|
+
#
|
|
199
|
+
# # 用例2: GUI应用测试
|
|
200
|
+
# def gui_app_testing():
|
|
201
|
+
# with Sandbox() as desktop:
|
|
202
|
+
# # 启动待测试的GUI应用
|
|
203
|
+
# desktop.launch("some-gui-application")
|
|
204
|
+
# time.sleep(2)
|
|
205
|
+
#
|
|
206
|
+
# # 执行一系列测试操作
|
|
207
|
+
# desktop.move_mouse(100, 100)
|
|
208
|
+
# desktop.left_click()
|
|
209
|
+
# desktop.write("测试输入")
|
|
210
|
+
# desktop.press("enter")
|
|
211
|
+
#
|
|
212
|
+
# # 验证结果
|
|
213
|
+
# screenshot = desktop.screenshot(format="bytes")
|
|
214
|
+
# # 这里可以添加截图分析逻辑
|
|
215
|
+
#
|
|
216
|
+
# # 用例3: 教育演示
|
|
217
|
+
# def educational_demo():
|
|
218
|
+
# with Sandbox() as desktop:
|
|
219
|
+
# # 打开编程环境
|
|
220
|
+
# desktop.open("vscode") # 或其他IDE
|
|
221
|
+
#
|
|
222
|
+
# # 逐步演示代码编写和执行过程
|
|
223
|
+
# time.sleep(2)
|
|
224
|
+
# desktop.write("# Python编程演示")
|
|
225
|
+
# desktop.press("enter")
|
|
226
|
+
# desktop.write("print('Hello, Students!')")
|
|
227
|
+
# desktop.press("enter")
|
|
228
|
+
#
|
|
229
|
+
# # 保存并运行
|
|
230
|
+
# desktop.press("ctrl+s")
|
|
231
|
+
# desktop.press("ctrl+alt+t") # 打开终端
|
|
232
|
+
# desktop.write("python3 demo.py")
|
|
233
|
+
# desktop.press("enter")
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
if __name__ == "__main__":
|
|
237
|
+
try:
|
|
238
|
+
desktop_automation_demo()
|
|
239
|
+
except Exception as e:
|
|
240
|
+
print(f"演示过程中发生错误: {e}")
|
|
241
|
+
import traceback
|
|
242
|
+
|
|
243
|
+
traceback.print_exc()
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from email.mime import application
|
|
2
|
+
|
|
3
|
+
from csx_desktop.main import Sandbox
|
|
4
|
+
|
|
5
|
+
sandbox = Sandbox()
|
|
6
|
+
sandbox.stream.start()
|
|
7
|
+
|
|
8
|
+
print(sandbox.get_screen_size())
|
|
9
|
+
sandbox.launch("firefox-esr")
|
|
10
|
+
windpws_id = sandbox.get_current_window_id()
|
|
11
|
+
print(windpws_id)
|
|
12
|
+
print(sandbox.get_window_title(window_id=windpws_id))
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from sandbox_async.main import AsyncSandbox
|
|
4
|
+
|
|
5
|
+
from scalebox.sandbox.commands.command_handle import PtySize
|
|
6
|
+
|
|
7
|
+
# from scalebox.sandbox_async.main import AsyncSandbox
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
async def pty_output_handler(output):
|
|
11
|
+
"""处理 PTY 输出的回调函数"""
|
|
12
|
+
print(f"PTY 输出: {output}")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def main():
|
|
16
|
+
sandbox = AsyncSandbox()
|
|
17
|
+
proc = await sandbox.commands.run("echo hello from async")
|
|
18
|
+
print("exit_code =", proc.exit_code)
|
|
19
|
+
print("stdout =", proc.stdout)
|
|
20
|
+
# 4. 创建 PTY
|
|
21
|
+
pty_size = PtySize(rows=24, cols=80)
|
|
22
|
+
pty_handle = await sandbox.pty.create(
|
|
23
|
+
size=pty_size,
|
|
24
|
+
on_data=pty_output_handler,
|
|
25
|
+
cwd="/root",
|
|
26
|
+
envs={"CUSTOM_ENV": "value"},
|
|
27
|
+
timeout=120,
|
|
28
|
+
request_timeout=30,
|
|
29
|
+
)
|
|
30
|
+
print(f"PTY 已创建,PID: {pty_handle.pid}")
|
|
31
|
+
|
|
32
|
+
# 5. 向 PTY 发送输入
|
|
33
|
+
await sandbox.pty.send_stdin(
|
|
34
|
+
pid=pty_handle.pid, data=b"echo 'Hello from PTY'\n", request_timeout=10
|
|
35
|
+
)
|
|
36
|
+
await asyncio.sleep(2)
|
|
37
|
+
|
|
38
|
+
# 6. 调整 PTY 大小
|
|
39
|
+
new_size = PtySize(rows=30, cols=100)
|
|
40
|
+
await sandbox.pty.resize(pid=pty_handle.pid, size=new_size, request_timeout=10)
|
|
41
|
+
print("PTY 大小已调整")
|
|
42
|
+
killed = await sandbox.pty.kill(pty_handle.pid)
|
|
43
|
+
print(f"PTY 是否被杀死: {killed}")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# 静态方法使用示例
|
|
47
|
+
async def static_methods_example():
|
|
48
|
+
# 1. 创建沙箱
|
|
49
|
+
sandbox = await AsyncSandbox.create()
|
|
50
|
+
sandbox_id = sandbox.sandbox_id
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
# 2. 使用静态方法获取沙箱信息
|
|
54
|
+
info = await AsyncSandbox.get_info(sandbox_id)
|
|
55
|
+
print(f"静态方法获取的沙箱信息: {info}")
|
|
56
|
+
|
|
57
|
+
# 3. 使用静态方法设置超时
|
|
58
|
+
await AsyncSandbox.set_timeout(sandbox_id, 1800) # 30分钟
|
|
59
|
+
|
|
60
|
+
# 4. 使用静态方法获取指标
|
|
61
|
+
try:
|
|
62
|
+
metrics = await AsyncSandbox.get_metrics(sandbox_id)
|
|
63
|
+
print(f"静态方法获取的指标: {metrics}")
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(f"静态方法获取指标失败: {e}")
|
|
66
|
+
|
|
67
|
+
finally:
|
|
68
|
+
# 5. 使用静态方法关闭沙箱
|
|
69
|
+
killed = await AsyncSandbox.kill(sandbox_id)
|
|
70
|
+
print(f"静态方法关闭沙箱结果: {killed}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# 连接现有沙箱示例
|
|
74
|
+
async def connect_example():
|
|
75
|
+
# 1. 创建沙箱并获取ID
|
|
76
|
+
sandbox = await AsyncSandbox.create()
|
|
77
|
+
sandbox_id = sandbox.sandbox_id
|
|
78
|
+
await sandbox.kill() # 先关闭
|
|
79
|
+
|
|
80
|
+
# 2. 连接到现有沙箱
|
|
81
|
+
try:
|
|
82
|
+
connected_sandbox = await AsyncSandbox.connect(sandbox_id)
|
|
83
|
+
print(f"成功连接到沙箱: {connected_sandbox.sandbox_id}")
|
|
84
|
+
|
|
85
|
+
# 使用连接的沙箱
|
|
86
|
+
is_running = await connected_sandbox.is_running()
|
|
87
|
+
print(f"连接后沙箱状态: {is_running}")
|
|
88
|
+
|
|
89
|
+
await connected_sandbox.kill()
|
|
90
|
+
except Exception as e:
|
|
91
|
+
print(f"连接沙箱失败: {e}")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# 上下文管理器使用示例
|
|
95
|
+
async def context_manager_example():
|
|
96
|
+
sandbox = AsyncSandbox()
|
|
97
|
+
# async with AsyncSandbox() as sandbox:
|
|
98
|
+
# # 在上下文中使用沙箱
|
|
99
|
+
# is_running = await sandbox.is_running()
|
|
100
|
+
# print(f"上下文管理器中的沙箱状态: {is_running}")
|
|
101
|
+
|
|
102
|
+
# 创建和使用 PTY
|
|
103
|
+
pty_handle = await sandbox.pty.create(
|
|
104
|
+
size=PtySize(rows=24, cols=80), on_data=pty_output_handler
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
# 发送命令
|
|
108
|
+
await sandbox.pty.send_stdin(pty_handle.pid, b"ls -la\n")
|
|
109
|
+
|
|
110
|
+
# 等待一段时间
|
|
111
|
+
await asyncio.sleep(10)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
# asyncio.run(main())0
|
|
116
|
+
# asyncio.run(static_methods_example())
|
|
117
|
+
# asyncio.run(connect_example())
|
|
118
|
+
asyncio.run(context_manager_example())
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from scalebox.sandbox.commands.command_handle import PtySize
|
|
2
|
+
from scalebox.sandbox_sync.main import Sandbox
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def output_handler(output):
|
|
6
|
+
"""处理 输出的回调函数"""
|
|
7
|
+
print(f"PTY 输出: {output}")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
sandbox = Sandbox(api_key=f"sk-Wk4IgtUYOqnttxGaxZmELEV4p2FXh15Evt0FIcSa")
|
|
11
|
+
# print(sandbox.files.list("/root",2))
|
|
12
|
+
# proc = sandbox.commands._start(
|
|
13
|
+
# cmd="python3 -c \"import math; print('π =', math.pi); exit(42)\"",
|
|
14
|
+
# ).wait(on_pty=None,
|
|
15
|
+
# on_stdout=lambda data: print("[STDOUT]", data, end=""),
|
|
16
|
+
# on_stderr=lambda data: print("[STDERR]", data, end=""),)
|
|
17
|
+
|
|
18
|
+
# proc = sandbox.commands._start(
|
|
19
|
+
# cmd="ls /",
|
|
20
|
+
# ).wait(on_pty=None,
|
|
21
|
+
# on_stdout=lambda data: print("[STDOUT]", data, end=""),
|
|
22
|
+
# on_stderr=lambda data: print("[STDERR]", data, end=""),)
|
|
23
|
+
#
|
|
24
|
+
# print("exit_code =", proc.exit_code) # 42
|
|
25
|
+
# print("full_output =", proc.stdout) # π = 3.141592653589793
|
|
26
|
+
# pty=sandbox.pty.create(size=PtySize(1024, 768),user="root",cwd="/root/",)
|
|
27
|
+
# sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"hello\"")
|
|
28
|
+
# sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\"")
|
|
29
|
+
# result=pty.wait(
|
|
30
|
+
# on_pty=lambda data: print("[STDOUT]", data, end=""),
|
|
31
|
+
# )
|
|
32
|
+
# print("exit_code =", result.exit_code)
|
|
33
|
+
# print("full_output =", result.stdout)
|
|
34
|
+
result = sandbox.commands.run(
|
|
35
|
+
cmd="ls /", on_stdout=output_handler, on_stderr=output_handler
|
|
36
|
+
)
|
|
37
|
+
print(result.exit_code)
|
|
38
|
+
print(result.error)
|
|
File without changes
|