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.
Files changed (157) hide show
  1. scalebox/__init__.py +80 -0
  2. scalebox/api/__init__.py +128 -0
  3. scalebox/api/client/__init__.py +8 -0
  4. scalebox/api/client/api/__init__.py +1 -0
  5. scalebox/api/client/api/sandboxes/__init__.py +0 -0
  6. scalebox/api/client/api/sandboxes/delete_sandboxes_sandbox_id.py +161 -0
  7. scalebox/api/client/api/sandboxes/get_sandboxes.py +176 -0
  8. scalebox/api/client/api/sandboxes/get_sandboxes_metrics.py +173 -0
  9. scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id.py +163 -0
  10. scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_logs.py +199 -0
  11. scalebox/api/client/api/sandboxes/get_sandboxes_sandbox_id_metrics.py +214 -0
  12. scalebox/api/client/api/sandboxes/get_v2_sandboxes.py +229 -0
  13. scalebox/api/client/api/sandboxes/post_sandboxes.py +174 -0
  14. scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_pause.py +165 -0
  15. scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_refreshes.py +182 -0
  16. scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_resume.py +190 -0
  17. scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_timeout.py +194 -0
  18. scalebox/api/client/client.py +288 -0
  19. scalebox/api/client/errors.py +16 -0
  20. scalebox/api/client/models/__init__.py +81 -0
  21. scalebox/api/client/models/build_log_entry.py +79 -0
  22. scalebox/api/client/models/created_access_token.py +100 -0
  23. scalebox/api/client/models/created_team_api_key.py +166 -0
  24. scalebox/api/client/models/error.py +67 -0
  25. scalebox/api/client/models/identifier_masking_details.py +83 -0
  26. scalebox/api/client/models/listed_sandbox.py +138 -0
  27. scalebox/api/client/models/log_level.py +11 -0
  28. scalebox/api/client/models/new_access_token.py +59 -0
  29. scalebox/api/client/models/new_sandbox.py +125 -0
  30. scalebox/api/client/models/new_team_api_key.py +59 -0
  31. scalebox/api/client/models/node.py +154 -0
  32. scalebox/api/client/models/node_detail.py +152 -0
  33. scalebox/api/client/models/node_status.py +11 -0
  34. scalebox/api/client/models/node_status_change.py +61 -0
  35. scalebox/api/client/models/post_sandboxes_sandbox_id_refreshes_body.py +59 -0
  36. scalebox/api/client/models/post_sandboxes_sandbox_id_timeout_body.py +59 -0
  37. scalebox/api/client/models/resumed_sandbox.py +68 -0
  38. scalebox/api/client/models/sandbox.py +125 -0
  39. scalebox/api/client/models/sandbox_detail.py +178 -0
  40. scalebox/api/client/models/sandbox_log.py +70 -0
  41. scalebox/api/client/models/sandbox_logs.py +73 -0
  42. scalebox/api/client/models/sandbox_metric.py +110 -0
  43. scalebox/api/client/models/sandbox_state.py +9 -0
  44. scalebox/api/client/models/sandboxes_with_metrics.py +59 -0
  45. scalebox/api/client/models/team.py +83 -0
  46. scalebox/api/client/models/team_api_key.py +158 -0
  47. scalebox/api/client/models/team_user.py +68 -0
  48. scalebox/api/client/models/template.py +179 -0
  49. scalebox/api/client/models/template_build.py +117 -0
  50. scalebox/api/client/models/template_build_file_upload.py +70 -0
  51. scalebox/api/client/models/template_build_request.py +115 -0
  52. scalebox/api/client/models/template_build_request_v2.py +88 -0
  53. scalebox/api/client/models/template_build_start_v2.py +114 -0
  54. scalebox/api/client/models/template_build_status.py +11 -0
  55. scalebox/api/client/models/template_step.py +91 -0
  56. scalebox/api/client/models/template_update_request.py +59 -0
  57. scalebox/api/client/models/update_team_api_key.py +59 -0
  58. scalebox/api/client/py.typed +1 -0
  59. scalebox/api/client/types.py +46 -0
  60. scalebox/api/metadata.py +19 -0
  61. scalebox/cli.py +125 -0
  62. scalebox/client/__init__.py +0 -0
  63. scalebox/client/aclient.py +57 -0
  64. scalebox/client/api.proto +460 -0
  65. scalebox/client/buf.gen.yaml +8 -0
  66. scalebox/client/client.py +102 -0
  67. scalebox/client/requirements.txt +5 -0
  68. scalebox/code_interpreter/__init__.py +12 -0
  69. scalebox/code_interpreter/charts.py +230 -0
  70. scalebox/code_interpreter/code_interpreter_async.py +369 -0
  71. scalebox/code_interpreter/code_interpreter_sync.py +317 -0
  72. scalebox/code_interpreter/constants.py +3 -0
  73. scalebox/code_interpreter/exceptions.py +13 -0
  74. scalebox/code_interpreter/models.py +485 -0
  75. scalebox/connection_config.py +92 -0
  76. scalebox/csx_connect/__init__.py +1 -0
  77. scalebox/csx_connect/client.py +485 -0
  78. scalebox/csx_desktop/__init__.py +0 -0
  79. scalebox/csx_desktop/main.py +651 -0
  80. scalebox/exceptions.py +83 -0
  81. scalebox/generated/__init__.py +0 -0
  82. scalebox/generated/api.py +61 -0
  83. scalebox/generated/api_pb2.py +203 -0
  84. scalebox/generated/api_pb2.pyi +956 -0
  85. scalebox/generated/api_pb2_connect.py +1456 -0
  86. scalebox/generated/rpc.py +50 -0
  87. scalebox/generated/versions.py +3 -0
  88. scalebox/requirements.txt +36 -0
  89. scalebox/sandbox/__init__.py +0 -0
  90. scalebox/sandbox/commands/__init__.py +0 -0
  91. scalebox/sandbox/commands/command_handle.py +69 -0
  92. scalebox/sandbox/commands/main.py +39 -0
  93. scalebox/sandbox/filesystem/__init__.py +0 -0
  94. scalebox/sandbox/filesystem/filesystem.py +95 -0
  95. scalebox/sandbox/filesystem/watch_handle.py +60 -0
  96. scalebox/sandbox/main.py +139 -0
  97. scalebox/sandbox/sandbox_api.py +91 -0
  98. scalebox/sandbox/signature.py +40 -0
  99. scalebox/sandbox/utils.py +34 -0
  100. scalebox/sandbox_async/__init__.py +1 -0
  101. scalebox/sandbox_async/commands/command.py +307 -0
  102. scalebox/sandbox_async/commands/command_handle.py +187 -0
  103. scalebox/sandbox_async/commands/pty.py +187 -0
  104. scalebox/sandbox_async/filesystem/filesystem.py +557 -0
  105. scalebox/sandbox_async/filesystem/watch_handle.py +61 -0
  106. scalebox/sandbox_async/main.py +646 -0
  107. scalebox/sandbox_async/sandbox_api.py +365 -0
  108. scalebox/sandbox_async/utils.py +7 -0
  109. scalebox/sandbox_sync/__init__.py +2 -0
  110. scalebox/sandbox_sync/commands/__init__.py +0 -0
  111. scalebox/sandbox_sync/commands/command.py +300 -0
  112. scalebox/sandbox_sync/commands/command_handle.py +150 -0
  113. scalebox/sandbox_sync/commands/pty.py +181 -0
  114. scalebox/sandbox_sync/filesystem/__init__.py +0 -0
  115. scalebox/sandbox_sync/filesystem/filesystem.py +543 -0
  116. scalebox/sandbox_sync/filesystem/watch_handle.py +66 -0
  117. scalebox/sandbox_sync/main.py +790 -0
  118. scalebox/sandbox_sync/sandbox_api.py +356 -0
  119. scalebox/test/CODE_INTERPRETER_TESTS_READY.md +323 -0
  120. scalebox/test/README.md +329 -0
  121. scalebox/test/__init__.py +0 -0
  122. scalebox/test/aclient.py +72 -0
  123. scalebox/test/code_interpreter_centext.py +21 -0
  124. scalebox/test/code_interpreter_centext_sync.py +21 -0
  125. scalebox/test/code_interpreter_test.py +34 -0
  126. scalebox/test/code_interpreter_test_sync.py +34 -0
  127. scalebox/test/run_all_validation_tests.py +334 -0
  128. scalebox/test/run_code_interpreter_tests.sh +67 -0
  129. scalebox/test/run_tests.sh +230 -0
  130. scalebox/test/test_basic.py +78 -0
  131. scalebox/test/test_code_interpreter_async_comprehensive.py +2653 -0
  132. scalebox/test/test_code_interpreter_e2basync_comprehensive.py +2655 -0
  133. scalebox/test/test_code_interpreter_e2bsync_comprehensive.py +3416 -0
  134. scalebox/test/test_code_interpreter_sync_comprehensive.py +3412 -0
  135. scalebox/test/test_e2b_first.py +11 -0
  136. scalebox/test/test_sandbox_async_comprehensive.py +738 -0
  137. scalebox/test/test_sandbox_stress_and_edge_cases.py +778 -0
  138. scalebox/test/test_sandbox_sync_comprehensive.py +770 -0
  139. scalebox/test/test_sandbox_usage_examples.py +987 -0
  140. scalebox/test/testacreate.py +24 -0
  141. scalebox/test/testagetinfo.py +18 -0
  142. scalebox/test/testcodeinterpreter_async.py +508 -0
  143. scalebox/test/testcodeinterpreter_sync.py +239 -0
  144. scalebox/test/testcomputeuse.py +243 -0
  145. scalebox/test/testnovnc.py +12 -0
  146. scalebox/test/testsandbox_async.py +118 -0
  147. scalebox/test/testsandbox_sync.py +38 -0
  148. scalebox/utils/__init__.py +0 -0
  149. scalebox/utils/httpcoreclient.py +297 -0
  150. scalebox/utils/httpxclient.py +403 -0
  151. scalebox/version.py +16 -0
  152. scalebox_sdk-0.1.0.dist-info/METADATA +292 -0
  153. scalebox_sdk-0.1.0.dist-info/RECORD +157 -0
  154. scalebox_sdk-0.1.0.dist-info/WHEEL +5 -0
  155. scalebox_sdk-0.1.0.dist-info/entry_points.txt +2 -0
  156. scalebox_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
  157. scalebox_sdk-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,356 @@
1
+ import datetime
2
+ import urllib.parse
3
+ from typing import Dict, List, Optional
4
+
5
+ from packaging.version import Version
6
+
7
+ from ..api import ApiClient, SandboxCreateResponse, handle_api_exception
8
+ from ..api.client.api.sandboxes import (
9
+ delete_sandboxes_sandbox_id,
10
+ get_sandboxes,
11
+ get_sandboxes_sandbox_id,
12
+ get_sandboxes_sandbox_id_metrics,
13
+ post_sandboxes,
14
+ post_sandboxes_sandbox_id_timeout,
15
+ )
16
+ from ..api.client.models import Error, NewSandbox, PostSandboxesSandboxIDTimeoutBody
17
+ from ..connection_config import ConnectionConfig, ProxyTypes
18
+ from ..exceptions import SandboxException, TemplateException
19
+ from ..sandbox.sandbox_api import (
20
+ ListedSandbox,
21
+ SandboxApiBase,
22
+ SandboxInfo,
23
+ SandboxMetrics,
24
+ SandboxQuery,
25
+ )
26
+
27
+
28
+ class SandboxApi(SandboxApiBase):
29
+ @classmethod
30
+ def list(
31
+ cls,
32
+ api_key: Optional[str] = None,
33
+ query: Optional[SandboxQuery] = None,
34
+ domain: Optional[str] = None,
35
+ debug: Optional[bool] = None,
36
+ request_timeout: Optional[float] = None,
37
+ headers: Optional[Dict[str, str]] = None,
38
+ proxy: Optional[ProxyTypes] = None,
39
+ ) -> List[ListedSandbox]:
40
+ """
41
+ List all running sandboxes.
42
+
43
+ :param api_key: API key to use for authentication, defaults to `E2B_API_KEY` environment variable
44
+ :param query: Filter the list of sandboxes, e.g. by metadata `SandboxQuery(metadata={"key": "value"})`, if there are multiple filters they are combined with AND.
45
+ :param domain: Domain to use for the request, only relevant for self-hosted environments
46
+ :param debug: Enable debug mode, all requested are then sent to localhost
47
+ :param request_timeout: Timeout for the request in **seconds**
48
+ :param headers: Additional headers to send with the request
49
+ :param proxy: Proxy to use for the request
50
+
51
+ :return: List of running sandboxes
52
+ """
53
+ config = ConnectionConfig(
54
+ api_key=api_key,
55
+ domain=domain,
56
+ debug=debug,
57
+ request_timeout=request_timeout,
58
+ headers=headers,
59
+ proxy=proxy,
60
+ )
61
+
62
+ # Convert filters to the format expected by the API
63
+ metadata = None
64
+ if query:
65
+ if query.metadata:
66
+ quoted_metadata = {
67
+ urllib.parse.quote(k): urllib.parse.quote(v)
68
+ for k, v in query.metadata.items()
69
+ }
70
+ metadata = urllib.parse.urlencode(quoted_metadata)
71
+
72
+ with ApiClient(
73
+ config,
74
+ limits=SandboxApiBase._limits,
75
+ ) as api_client:
76
+ res = get_sandboxes.sync_detailed(client=api_client, metadata=metadata)
77
+
78
+ if res.status_code >= 300:
79
+ raise handle_api_exception(res)
80
+
81
+ if res.parsed is None:
82
+ return []
83
+
84
+ return [
85
+ ListedSandbox(
86
+ sandbox_id=sandbox.sandbox_id,
87
+ template_id=sandbox.template_id,
88
+ name=sandbox.alias if isinstance(sandbox.alias, str) else None,
89
+ metadata=(
90
+ sandbox.metadata if isinstance(sandbox.metadata, dict) else {}
91
+ ),
92
+ state=sandbox.state,
93
+ cpu_count=sandbox.cpu_count,
94
+ memory_mb=sandbox.memory_mb,
95
+ started_at=sandbox.started_at,
96
+ end_at=sandbox.end_at,
97
+ )
98
+ for sandbox in res.parsed
99
+ ]
100
+
101
+ @classmethod
102
+ def _cls_get_info(
103
+ cls,
104
+ sandbox_id: str,
105
+ api_key: Optional[str] = None,
106
+ domain: Optional[str] = None,
107
+ debug: Optional[bool] = None,
108
+ request_timeout: Optional[float] = None,
109
+ headers: Optional[Dict[str, str]] = None,
110
+ proxy: Optional[ProxyTypes] = None,
111
+ ) -> SandboxInfo:
112
+ """
113
+ Get the sandbox info.
114
+ :param sandbox_id: Sandbox ID
115
+ :param api_key: API key to use for authentication, defaults to `E2B_API_KEY` environment variable
116
+ :param domain: Domain to use for the request, defaults to `E2B_DOMAIN` environment variable
117
+ :param debug: Debug mode, defaults to `E2B_DEBUG` environment variable
118
+ :param request_timeout: Timeout for the request in **seconds**
119
+ :param headers: Additional headers to send with the request
120
+
121
+ :return: Sandbox info
122
+ """
123
+ config = ConnectionConfig(
124
+ api_key=api_key,
125
+ domain=domain,
126
+ debug=debug,
127
+ request_timeout=request_timeout,
128
+ headers=headers,
129
+ proxy=proxy,
130
+ )
131
+
132
+ with ApiClient(
133
+ config,
134
+ limits=SandboxApiBase._limits,
135
+ ) as api_client:
136
+ res = get_sandboxes_sandbox_id.sync_detailed(
137
+ sandbox_id,
138
+ client=api_client,
139
+ )
140
+
141
+ if res.status_code >= 300:
142
+ raise handle_api_exception(res)
143
+
144
+ if res.parsed is None:
145
+ raise Exception("Body of the request is None")
146
+
147
+ return SandboxInfo(
148
+ sandbox_id=res.parsed.sandbox_id,
149
+ sandbox_domain=res.parsed.domain,
150
+ template_id=res.parsed.template_id,
151
+ name=res.parsed.alias if isinstance(res.parsed.alias, str) else None,
152
+ metadata=(
153
+ res.parsed.metadata if isinstance(res.parsed.metadata, dict) else {}
154
+ ),
155
+ started_at=res.parsed.started_at,
156
+ end_at=res.parsed.end_at,
157
+ envd_version=res.parsed.envd_version,
158
+ _envd_access_token=res.parsed.envd_access_token,
159
+ )
160
+
161
+ @classmethod
162
+ def _cls_kill(
163
+ cls,
164
+ sandbox_id: str,
165
+ api_key: Optional[str] = None,
166
+ domain: Optional[str] = None,
167
+ debug: Optional[bool] = None,
168
+ request_timeout: Optional[float] = None,
169
+ headers: Optional[Dict[str, str]] = None,
170
+ proxy: Optional[ProxyTypes] = None,
171
+ ) -> bool:
172
+ config = ConnectionConfig(
173
+ api_key=api_key,
174
+ domain=domain,
175
+ debug=debug,
176
+ request_timeout=request_timeout,
177
+ headers=headers,
178
+ proxy=proxy,
179
+ )
180
+
181
+ if config.debug:
182
+ # Skip killing the sandbox in debug mode
183
+ return True
184
+
185
+ with ApiClient(
186
+ config,
187
+ limits=SandboxApiBase._limits,
188
+ ) as api_client:
189
+ res = delete_sandboxes_sandbox_id.sync_detailed(
190
+ sandbox_id,
191
+ client=api_client,
192
+ )
193
+
194
+ if res.status_code == 404:
195
+ return False
196
+
197
+ if res.status_code >= 300:
198
+ raise handle_api_exception(res)
199
+
200
+ return True
201
+
202
+ @classmethod
203
+ def _cls_set_timeout(
204
+ cls,
205
+ sandbox_id: str,
206
+ timeout: int,
207
+ api_key: Optional[str] = None,
208
+ domain: Optional[str] = None,
209
+ debug: Optional[bool] = None,
210
+ request_timeout: Optional[float] = None,
211
+ headers: Optional[Dict[str, str]] = None,
212
+ proxy: Optional[ProxyTypes] = None,
213
+ ) -> None:
214
+ config = ConnectionConfig(
215
+ api_key=api_key,
216
+ domain=domain,
217
+ debug=debug,
218
+ request_timeout=request_timeout,
219
+ headers=headers,
220
+ proxy=proxy,
221
+ )
222
+
223
+ if config.debug:
224
+ # Skip setting timeout in debug mode
225
+ return
226
+
227
+ with ApiClient(
228
+ config,
229
+ limits=SandboxApiBase._limits,
230
+ ) as api_client:
231
+ res = post_sandboxes_sandbox_id_timeout.sync_detailed(
232
+ sandbox_id,
233
+ client=api_client,
234
+ body=PostSandboxesSandboxIDTimeoutBody(timeout=timeout),
235
+ )
236
+
237
+ if res.status_code >= 300:
238
+ raise handle_api_exception(res)
239
+
240
+ @classmethod
241
+ def _create_sandbox(
242
+ cls,
243
+ template: str,
244
+ timeout: int,
245
+ metadata: Optional[Dict[str, str]] = None,
246
+ env_vars: Optional[Dict[str, str]] = None,
247
+ secure: Optional[bool] = None,
248
+ api_key: Optional[str] = None,
249
+ domain: Optional[str] = None,
250
+ debug: Optional[bool] = None,
251
+ request_timeout: Optional[float] = None,
252
+ headers: Optional[Dict[str, str]] = None,
253
+ proxy: Optional[ProxyTypes] = None,
254
+ allow_internet_access: Optional[bool] = True,
255
+ ) -> SandboxCreateResponse:
256
+ config = ConnectionConfig(
257
+ api_key=api_key,
258
+ domain=domain,
259
+ debug=debug,
260
+ request_timeout=request_timeout,
261
+ headers=headers,
262
+ proxy=proxy,
263
+ )
264
+
265
+ with ApiClient(config, limits=SandboxApiBase._limits) as api_client:
266
+ res = post_sandboxes.sync_detailed(
267
+ body=NewSandbox(
268
+ template_id=template,
269
+ metadata=metadata or {},
270
+ timeout=timeout,
271
+ env_vars=env_vars or {},
272
+ secure=secure or False,
273
+ allow_internet_access=allow_internet_access,
274
+ ),
275
+ client=api_client,
276
+ )
277
+
278
+ if res.status_code >= 300:
279
+ raise handle_api_exception(res)
280
+
281
+ if res.parsed is None:
282
+ raise Exception("Body of the request is None")
283
+
284
+ # if Version(res.parsed.envd_version) < Version("0.1.0"):
285
+ # SandboxApi._cls_kill(res.parsed.sandbox_id)
286
+ # raise TemplateException(
287
+ # "You need to update the template to use the new SDK. "
288
+ # "You can do this by running `e2b template build` in the directory with the template."
289
+ # )
290
+
291
+ return SandboxCreateResponse(
292
+ sandbox_id=res.parsed.sandbox_id,
293
+ sandbox_domain=res.parsed.domain,
294
+ envd_version=res.parsed.envd_version,
295
+ envd_access_token=res.parsed.envd_access_token,
296
+ )
297
+
298
+ @classmethod
299
+ def _cls_get_metrics(
300
+ cls,
301
+ sandbox_id: str,
302
+ start: Optional[datetime.datetime] = None,
303
+ end: Optional[datetime.datetime] = None,
304
+ api_key: Optional[str] = None,
305
+ domain: Optional[str] = None,
306
+ debug: Optional[bool] = None,
307
+ request_timeout: Optional[float] = None,
308
+ headers: Optional[Dict[str, str]] = None,
309
+ proxy: Optional[ProxyTypes] = None,
310
+ ) -> List[SandboxMetrics]:
311
+ config = ConnectionConfig(
312
+ api_key=api_key,
313
+ domain=domain,
314
+ debug=debug,
315
+ request_timeout=request_timeout,
316
+ headers=headers,
317
+ proxy=proxy,
318
+ )
319
+
320
+ if config.debug:
321
+ # Skip getting the metrics in debug mode
322
+ return []
323
+
324
+ with ApiClient(
325
+ config,
326
+ limits=cls._limits,
327
+ ) as api_client:
328
+ res = get_sandboxes_sandbox_id_metrics.sync_detailed(
329
+ sandbox_id,
330
+ start=int(start.timestamp() * 1000) if start else None,
331
+ end=int(end.timestamp() * 1000) if end else None,
332
+ client=api_client,
333
+ )
334
+
335
+ if res.status_code >= 300:
336
+ raise handle_api_exception(res)
337
+
338
+ if res.parsed is None:
339
+ return []
340
+
341
+ if isinstance(res.parsed, Error):
342
+ raise SandboxException(f"{res.parsed.message}: Request failed")
343
+
344
+ # Convert to typed SandboxMetrics objects
345
+ return [
346
+ SandboxMetrics(
347
+ cpu_count=metric.cpu_count,
348
+ cpu_used_pct=metric.cpu_used_pct,
349
+ disk_total=metric.disk_total,
350
+ disk_used=metric.disk_used,
351
+ mem_total=metric.mem_total,
352
+ mem_used=metric.mem_used,
353
+ timestamp=metric.timestamp,
354
+ )
355
+ for metric in res.parsed
356
+ ]
@@ -0,0 +1,323 @@
1
+ # ✅ Code Interpreter 测试套件完成
2
+
3
+ 按照 `test_sandbox_sync_comprehensive.py` 和 `test_sandbox_async_comprehensive.py` 的风格,已成功创建完整的 Code Interpreter 测试套件。
4
+
5
+ ## 📁 已创建的文件
6
+
7
+ ### 🧪 综合测试文件
8
+ 1. **`test_code_interpreter_sync_comprehensive.py`** (24.6KB)
9
+ - 同步版本的全面测试套件
10
+ - 使用 `CodeInterpreterValidator` 类
11
+ - 包含 17+ 个详细测试用例
12
+
13
+ 2. **`test_code_interpreter_async_comprehensive.py`** (26.2KB)
14
+ - 异步版本的全面测试套件
15
+ - 使用 `AsyncCodeInterpreterValidator` 类
16
+ - 包含 11+ 个异步测试用例
17
+
18
+ ### 🎯 简单测试示例
19
+ 3. **`testcodeinterpreter_sync.py`** (3.4KB)
20
+ - 简单直接的同步测试示例
21
+ - 类似于 `testsandbox_sync.py` 的风格
22
+ - 适合快速验证基础功能
23
+
24
+ 4. **`testcodeinterpreter_async.py`** (7.2KB)
25
+ - 简单直接的异步测试示例
26
+ - 类似于 `testsandbox_async.py` 的风格
27
+ - 展示异步代码执行和并发处理
28
+
29
+ ### 🚀 运行脚本
30
+ 5. **`run_code_interpreter_tests.sh`** (2KB)
31
+ - 交互式测试运行脚本
32
+ - 支持选择不同类型的测试
33
+ - 一键运行所有测试
34
+
35
+ ## 📊 测试覆盖范围
36
+
37
+ ### 同步测试覆盖
38
+ - ✅ **基础代码执行** - Python代码解释和执行
39
+ - ✅ **数学计算** - numpy, math库使用
40
+ - ✅ **数据处理** - pandas数据分析
41
+ - ✅ **数据可视化** - matplotlib图表生成
42
+ - ✅ **回调函数处理** - stdout, stderr, result, error回调
43
+ - ✅ **上下文管理** - 创建、持久化、多上下文
44
+ - ✅ **错误处理** - 语法错误、运行时错误
45
+ - ✅ **数据类型测试** - 各种Python数据类型
46
+ - ✅ **文件操作模拟** - 文件读写操作
47
+ - ✅ **性能测试** - 计算性能、并发模拟
48
+ - ✅ **结果格式测试** - 文本、HTML、Markdown、SVG、图像、LaTeX、JSON、JavaScript、图表数据、混合格式
49
+ - ✅ **R语言支持** - R语言基础执行、数据分析、可视化、统计分析、上下文管理
50
+ - ✅ **网络请求模拟** - API调用模拟
51
+
52
+ ### 异步测试覆盖
53
+ - ✅ **异步代码执行** - async/await语法支持
54
+ - ✅ **并发代码执行** - 多任务并发处理
55
+ - ✅ **异步数据科学** - 异步数据处理工作流
56
+ - ✅ **异步回调处理** - 异步回调函数
57
+ - ✅ **异步上下文管理** - 异步上下文状态管理
58
+ - ✅ **异步性能测试** - 并发任务、批处理性能
59
+ - ✅ **异步错误处理** - 异步错误捕获
60
+ - ✅ **异步结果格式测试** - 异步文本生成、混合格式、实时数据流处理
61
+ - ✅ **异步R语言支持** - 异步R语言基础执行、数据分析、可视化、统计分析、上下文管理
62
+ - ✅ **WebSocket模拟** - 异步WebSocket连接模拟
63
+
64
+ ## 🎨 测试风格特点
65
+
66
+ ### 遵循sandbox测试风格
67
+ - 使用 `Validator` 类结构
68
+ - `test_results` 列表记录测试结果
69
+ - `run_test()` 方法执行单个测试
70
+ - `log_test_result()` 记录测试状态
71
+ - `cleanup()` 方法清理资源
72
+ - `print_summary()` 生成测试报告
73
+ - 测试方法以 `test_` 开头
74
+
75
+ ### 测试结构示例
76
+ ```python
77
+ class CodeInterpreterValidator:
78
+ def __init__(self):
79
+ self.sandbox = None
80
+ self.test_results = []
81
+ self.failed_tests = []
82
+
83
+ def run_test(self, test_func, test_name: str):
84
+ # 执行测试并记录结果
85
+
86
+ def test_basic_python_execution(self):
87
+ # 具体的测试逻辑
88
+
89
+ def cleanup(self):
90
+ # 清理沙箱资源
91
+
92
+ def print_summary(self):
93
+ # 打印测试摘要
94
+ ```
95
+
96
+ ## 🚀 运行方法
97
+
98
+ ### 1. 使用运行脚本(推荐)
99
+ ```bash
100
+ cd scalebox/test
101
+ ./run_code_interpreter_tests.sh
102
+ ```
103
+
104
+ ### 2. 直接运行测试文件
105
+ ```bash
106
+ # 简单同步测试
107
+ python3 testcodeinterpreter_sync.py
108
+
109
+ # 简单异步测试
110
+ python3 testcodeinterpreter_async.py
111
+
112
+ # 综合同步测试
113
+ python3 test_code_interpreter_sync_comprehensive.py
114
+
115
+ # 综合异步测试
116
+ python3 test_code_interpreter_async_comprehensive.py
117
+ ```
118
+
119
+ ### 3. 分别测试特定功能
120
+ ```bash
121
+ # 只测试基础功能
122
+ python3 -c "
123
+ from test_code_interpreter_sync_comprehensive import CodeInterpreterValidator
124
+ validator = CodeInterpreterValidator()
125
+ validator.run_test(validator.test_basic_python_execution, 'Basic Test')
126
+ validator.cleanup()
127
+ "
128
+ ```
129
+
130
+ ## 📋 测试报告示例
131
+
132
+ 运行后会生成如下格式的报告:
133
+ ```
134
+ ============================================================
135
+ CodeInterpreter综合验证测试报告
136
+ ============================================================
137
+ 总测试数: 17
138
+ 通过数: 16
139
+ 失败数: 1
140
+ 总耗时: 45.234秒
141
+ 成功率: 94.1%
142
+
143
+ 失败的测试:
144
+ ❌ Visualization Code
145
+
146
+ ============================================================
147
+ ```
148
+
149
+ ## 🎨 结果格式支持(新增功能)
150
+
151
+ ### 完整的 Result 类格式测试
152
+ 基于您提供的 `Result` 类定义,新增了对所有结果格式的全面测试:
153
+
154
+ #### 📝 文本格式 (text)
155
+ - 纯文本结果输出
156
+ - 多行文本处理
157
+ - 中文内容支持
158
+ - 格式化文本展示
159
+
160
+ #### 🌐 网页格式 (html)
161
+ - 完整的HTML文档生成
162
+ - CSS样式支持
163
+ - 表格和列表渲染
164
+ - 响应式设计
165
+
166
+ #### 📋 Markdown格式 (markdown)
167
+ - 标准Markdown语法
168
+ - 表格、列表、代码块
169
+ - 链接和图片引用
170
+ - 数学公式展示
171
+
172
+ #### 🖼️ 矢量图形 (svg)
173
+ - 动态SVG图形
174
+ - 进度条动画
175
+ - 交互式图表
176
+ - 矢量图形优化
177
+
178
+ #### 📊 图像格式 (png/jpeg)
179
+ - matplotlib图表转base64
180
+ - 多子图复杂图表
181
+ - 高质量图像输出
182
+ - 压缩优化
183
+
184
+ #### 📄 LaTeX格式 (latex)
185
+ - 完整的LaTeX文档
186
+ - 数学公式渲染
187
+ - 表格和图形
188
+ - 学术论文格式
189
+
190
+ #### 📈 JSON数据 (json_data)
191
+ - 结构化数据输出
192
+ - 嵌套对象处理
193
+ - 数组和复杂类型
194
+ - 性能指标数据
195
+
196
+ #### ⚡ JavaScript代码 (javascript)
197
+ - 交互式界面组件
198
+ - 实时数据更新
199
+ - 事件处理机制
200
+ - 图表库集成
201
+
202
+ #### 📊 图表数据 (chart)
203
+ - Chart.js兼容格式
204
+ - 多种图表类型
205
+ - 交互式配置
206
+ - 数据导出功能
207
+
208
+ #### 🎨 混合格式 (mixed)
209
+ - 同时生成多种格式
210
+ - 格式间数据关联
211
+ - 统一样式设计
212
+ - 完整报告生成
213
+
214
+ ### 异步结果格式增强
215
+ - **异步文本生成**: 非阻塞文本处理
216
+ - **并发格式处理**: 同时生成多种格式
217
+ - **实时数据流**: 动态数据收集和处理
218
+ - **性能优化**: 异步I/O和资源管理
219
+
220
+ ## 🔬 R语言支持(新增功能)
221
+
222
+ ### 完整的 R 语言 Kernel 测试
223
+ 基于 code-interpreter 的 R 语言支持,新增了全面的 R 语言测试用例:
224
+
225
+ #### 📊 **R语言基础执行** (`test_r_language_basic_execution`)
226
+ - R语言基础语法和变量操作
227
+ - 向量运算和数据框创建
228
+ - 基础数学函数和统计函数
229
+ - 数据结构和类型处理
230
+
231
+ #### 📈 **R语言数据分析** (`test_r_language_data_analysis`)
232
+ - dplyr 包的数据操作
233
+ - 数据过滤、分组和聚合
234
+ - 数据框操作和转换
235
+ - 复杂数据查询和统计
236
+
237
+ #### 📊 **R语言数据可视化** (`test_r_language_visualization`)
238
+ - ggplot2 包的高级图表
239
+ - 散点图、箱线图、直方图
240
+ - 多图表组合和主题设置
241
+ - 数据可视化最佳实践
242
+
243
+ #### 📉 **R语言统计分析** (`test_r_language_statistics`)
244
+ - 描述性统计分析
245
+ - t检验和假设检验
246
+ - 相关性分析和回归分析
247
+ - 正态性检验和统计推断
248
+
249
+ #### 🔄 **R语言上下文管理** (`test_r_language_context_management`)
250
+ - R语言专用上下文创建
251
+ - 全局变量和函数定义
252
+ - 上下文状态持久化
253
+ - 资源清理和管理
254
+
255
+ ### 异步 R 语言支持
256
+ - **异步R语言基础执行**: 非阻塞R代码执行
257
+ - **异步R语言数据分析**: 并发数据处理
258
+ - **异步R语言可视化**: 异步图表生成
259
+ - **异步R语言统计**: 并发统计分析
260
+ - **异步R语言上下文**: 异步上下文管理
261
+
262
+ ### R 语言测试特色
263
+ - **真实环境**: 使用真实的 R kernel 执行
264
+ - **完整覆盖**: 涵盖 R 语言的核心功能
265
+ - **库支持**: 测试 dplyr、ggplot2、stats 等常用包
266
+ - **上下文隔离**: 每个测试使用独立的 R 上下文
267
+ - **资源管理**: 自动清理 R 语言上下文资源
268
+
269
+ ## 💡 特色功能
270
+
271
+ ### 1. 丰富的代码示例
272
+ - 数学计算(三角函数、统计分析)
273
+ - 数据处理(pandas数据分析)
274
+ - 数据可视化(matplotlib图表)
275
+ - 异步编程(async/await, 并发)
276
+ - 批处理(并发数据处理)
277
+ - 网络模拟(API调用、WebSocket)
278
+
279
+ ### 2. 完整的错误处理
280
+ - 语法错误捕获
281
+ - 运行时错误处理
282
+ - 异步错误处理
283
+ - 回调函数错误处理
284
+
285
+ ### 3. 性能测试
286
+ - 计算性能基准测试
287
+ - 并发执行性能测试
288
+ - 异步批处理性能测试
289
+ - 吞吐量和效率分析
290
+
291
+ ### 4. 上下文管理
292
+ - 多个独立上下文
293
+ - 上下文状态持久化
294
+ - 异步上下文状态管理
295
+ - 上下文间的隔离验证
296
+
297
+ ## 🎯 使用场景
298
+
299
+ 1. **开发验证** - 验证Code Interpreter核心功能
300
+ 2. **功能测试** - 测试各种代码执行场景
301
+ 3. **性能评估** - 评估系统性能和并发能力
302
+ 4. **学习参考** - 作为Code Interpreter使用示例
303
+ 5. **回归测试** - 确保更新后功能正常
304
+
305
+ ## 📝 注意事项
306
+
307
+ 1. **依赖要求**: 需要安装numpy、pandas、matplotlib等库
308
+ 2. **环境配置**: 确保沙箱环境正确配置
309
+ 3. **执行时间**: 综合测试可能需要数分钟
310
+ 4. **资源清理**: 测试完成后会自动清理沙箱资源
311
+ 5. **错误处理**: 部分测试故意产生错误以验证错误处理机制
312
+
313
+ ---
314
+
315
+ **创建时间**: 2024年9月17日
316
+ **文件总数**: 6个
317
+ **代码总量**: 5000+行
318
+ **测试用例**: 49个
319
+ **结果格式支持**: 10+种格式
320
+ **语言支持**: Python + R语言
321
+ **状态**: ✅ 完成并可使用
322
+
323
+ 所有测试文件已按照您要求的 `test_sandbox` 风格创建完成,可以立即使用!🎉