scalebox-sdk 1.0.1__py3-none-any.whl → 1.0.3__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 (44) hide show
  1. scalebox/__init__.py +1 -1
  2. scalebox/api/client/api/sandboxes/get_sandboxes.py +1 -1
  3. scalebox/api/client/models/error.py +1 -1
  4. scalebox/api/client/models/listed_sandbox.py +6 -3
  5. scalebox/api/client/models/sandbox.py +2 -2
  6. scalebox/code_interpreter/code_interpreter_async.py +3 -1
  7. scalebox/code_interpreter/code_interpreter_sync.py +3 -1
  8. scalebox/connection_config.py +2 -0
  9. scalebox/generated/api_pb2_connect.py +3 -3
  10. scalebox/sandbox/main.py +1 -1
  11. scalebox/sandbox_async/main.py +1 -1
  12. scalebox/sandbox_sync/main.py +1 -1
  13. scalebox/test/bedrock_openai_adapter.py +8 -2
  14. scalebox/test/run_stress_code_interpreter_sync.py +18 -6
  15. scalebox/test/simple_upload_example.py +39 -31
  16. scalebox/test/stabitiy_test.py +82 -69
  17. scalebox/test/test_browser_use.py +4 -2
  18. scalebox/test/test_browser_use_scalebox.py +5 -4
  19. scalebox/test/test_code_interpreter_execcode.py +289 -211
  20. scalebox/test/test_code_interpreter_sync_comprehensive.py +2 -5
  21. scalebox/test/test_connect_pause_async.py +34 -11
  22. scalebox/test/test_connect_pause_sync.py +49 -16
  23. scalebox/test/test_csx_desktop_examples.py +3 -3
  24. scalebox/test/test_desktop_sandbox_sf.py +18 -23
  25. scalebox/test/test_download_url.py +6 -14
  26. scalebox/test/test_existing_sandbox.py +1037 -0
  27. scalebox/test/test_sandbox_async_comprehensive.py +4 -2
  28. scalebox/test/test_sandbox_object_storage_example.py +14 -9
  29. scalebox/test/test_sandbox_object_storage_example_async.py +6 -3
  30. scalebox/test/test_sandbox_sync_comprehensive.py +1 -1
  31. scalebox/test/test_sf.py +12 -8
  32. scalebox/test/test_watch_dir_async.py +6 -4
  33. scalebox/test/testagetinfo.py +1 -3
  34. scalebox/test/testsandbox_api.py +5 -3
  35. scalebox/test/testsandbox_async.py +17 -47
  36. scalebox/test/testsandbox_sync.py +18 -14
  37. scalebox/test/upload_100mb_example.py +77 -55
  38. scalebox/version.py +2 -2
  39. {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.3.dist-info}/METADATA +1 -1
  40. {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.3.dist-info}/RECORD +44 -43
  41. {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.3.dist-info}/WHEEL +0 -0
  42. {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.3.dist-info}/entry_points.txt +0 -0
  43. {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.3.dist-info}/licenses/LICENSE +0 -0
  44. {scalebox_sdk-1.0.1.dist-info → scalebox_sdk-1.0.3.dist-info}/top_level.txt +0 -0
@@ -274,7 +274,9 @@ class AsyncSandboxValidator:
274
274
  await self.sandbox.files.write("/tmp/old_name.txt", "content to rename")
275
275
 
276
276
  # 重命名
277
- result = await self.sandbox.files.rename("/tmp/old_name.txt", "/tmp/new_name.txt")
277
+ result = await self.sandbox.files.rename(
278
+ "/tmp/old_name.txt", "/tmp/new_name.txt"
279
+ )
278
280
  print(result)
279
281
  assert isinstance(result, EntryInfo)
280
282
  assert result.name == "new_name.txt"
@@ -290,7 +292,7 @@ class AsyncSandboxValidator:
290
292
  # 删除文件
291
293
  await self.sandbox.files.remove("/tmp/new_name.txt")
292
294
  assert await self.sandbox.files.exists("/tmp/new_name.txt") == False
293
-
295
+
294
296
  # 删除目录
295
297
  await self.sandbox.files.remove("/tmp/test_dir")
296
298
  assert await self.sandbox.files.exists("/tmp/test_dir") == False
@@ -38,7 +38,9 @@ from scalebox.sandbox_sync.main import Sandbox
38
38
  from scalebox.sandbox.sandbox_api import SandboxQuery
39
39
 
40
40
  logger = logging.getLogger(__name__)
41
- logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
41
+ logging.basicConfig(
42
+ level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
43
+ )
42
44
 
43
45
  # CONFIG_ENV = "SCALEBOX_OBJECT_STORAGE_CONFIG"
44
46
  # TEMPLATE_ENV = "SCALEBOX_OBJECT_STORAGE_TEMPLATE"
@@ -104,12 +106,14 @@ def create_sandbox_with_object_storage():
104
106
  template="base",
105
107
  timeout=3600,
106
108
  metadata={"example": "object_storage"},
107
- object_storage={"uri": "s3://bgd-test/test/",
108
- "mount_point": "/mnt/oss",
109
- # "access_key": "",
110
- # "secret_key": "",
111
- "region": "us-east-2",
112
- "endpoint": "https://s3.us-east-2.amazonaws.com",},
109
+ object_storage={
110
+ "uri": "s3://bgd-test/test/",
111
+ "mount_point": "/mnt/oss",
112
+ # "access_key": "",
113
+ # "secret_key": "",
114
+ "region": "us-east-2",
115
+ "endpoint": "https://s3.us-east-2.amazonaws.com",
116
+ },
113
117
  )
114
118
  print(sandbox.sandbox_id)
115
119
  print(sandbox.sandbox_domain)
@@ -120,7 +124,9 @@ def create_sandbox_with_object_storage():
120
124
  print(info)
121
125
  print(f"get_info.object_storage: {info.object_storage}")
122
126
 
123
- listed = Sandbox.list(query=SandboxQuery(metadata={"example": "object_storage"}))
127
+ listed = Sandbox.list(
128
+ query=SandboxQuery(metadata={"example": "object_storage"})
129
+ )
124
130
  print(f"List 根据 metadata 命中的沙箱数量: {len(listed)}")
125
131
  for listed_box in listed:
126
132
  detailed = Sandbox.get_info(sandbox_id=listed_box.sandbox_id)
@@ -143,4 +149,3 @@ def create_sandbox_with_object_storage():
143
149
 
144
150
  if __name__ == "__main__":
145
151
  create_sandbox_with_object_storage()
146
-
@@ -44,7 +44,9 @@ from scalebox.sandbox_async.main import AsyncSandbox
44
44
  from scalebox.sandbox.sandbox_api import SandboxQuery
45
45
 
46
46
  logger = logging.getLogger(__name__)
47
- logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
47
+ logging.basicConfig(
48
+ level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
49
+ )
48
50
 
49
51
  # CONFIG_ENV = "SCALEBOX_OBJECT_STORAGE_CONFIG"
50
52
  # TEMPLATE_ENV = "SCALEBOX_OBJECT_STORAGE_TEMPLATE"
@@ -140,7 +142,9 @@ async def create_sandbox_with_object_storage_async():
140
142
  )
141
143
 
142
144
  # 在沙箱中运行简单命令,确认可正常访问
143
- result = await sandbox.commands.run("echo 'async object storage sandbox is ready'")
145
+ result = await sandbox.commands.run(
146
+ "echo 'async object storage sandbox is ready'"
147
+ )
144
148
  print(f"命令输出: {result.stdout.strip()}")
145
149
  except SandboxException as exc:
146
150
  logger.error("创建或使用异步沙箱失败:%s", exc)
@@ -153,4 +157,3 @@ async def create_sandbox_with_object_storage_async():
153
157
 
154
158
  if __name__ == "__main__":
155
159
  asyncio.run(create_sandbox_with_object_storage_async())
156
-
@@ -292,7 +292,7 @@ class SandboxValidator:
292
292
  # 删除文件
293
293
  self.sandbox.files.remove("/tmp/new_name.txt")
294
294
  assert self.sandbox.files.exists("/tmp/new_name.txt") == False
295
-
295
+
296
296
  # 删除目录
297
297
  self.sandbox.files.remove("/tmp/test_dir")
298
298
  assert self.sandbox.files.exists("/tmp/test_dir") == False
scalebox/test/test_sf.py CHANGED
@@ -15,7 +15,7 @@ _chat = ChatOpenAI(
15
15
  model="Qwen/Qwen2.5-72B-Instruct",
16
16
  api_key="sk-nbxsvrydquzfkfrrnnuutnfchpghzeuxilgawvsjqzjhumkh",
17
17
  base_url="https://api.siliconflow.cn/v1",
18
- temperature=0.1
18
+ temperature=0.1,
19
19
  )
20
20
 
21
21
 
@@ -23,8 +23,10 @@ llm = ChatOpenAI(
23
23
  model="deepseek-ai/DeepSeek-R1",
24
24
  api_key="sk-nbxsvrydquzfkfrrnnuutnfchpghzeuxilgawvsjqzjhumkh",
25
25
  base_url="https://api.siliconflow.cn/v1",
26
- temperature=0.7
26
+ temperature=0.7,
27
27
  )
28
+
29
+
28
30
  # 2. 包一层模型,补 .provider + 转发所有必要方法
29
31
  class SiliconFlowModel:
30
32
  provider = "siliconflow"
@@ -50,8 +52,10 @@ class SiliconFlowModel:
50
52
  def bind(self, *args, **kwargs):
51
53
  return self.chat.bind(*args, **kwargs)
52
54
 
55
+
53
56
  # llm = SiliconFlowModel(_chat)
54
57
 
58
+
55
59
  # 3. 创建 Agent
56
60
  async def main():
57
61
  # chrome_path = subprocess.check_output(
@@ -77,13 +81,12 @@ async def main():
77
81
  browser = await pw.chromium.launch(
78
82
  proxy={
79
83
  "server": "http://net-proxy:80",
80
- "username":"sbx-jz9kgqolumvmfc7ds",
81
- "password": "npt-Vd4CpGtjBOQEI8wdBv3wSOd8P4Bup1NgfsM"
84
+ "username": "sbx-jz9kgqolumvmfc7ds",
85
+ "password": "npt-Vd4CpGtjBOQEI8wdBv3wSOd8P4Bup1NgfsM",
82
86
  },
83
87
  headless=False,
84
88
  args=[
85
89
  # '--no-sandbox',
86
-
87
90
  # '--disable-dev-shm-usage',
88
91
  # '--disable-gpu',
89
92
  # '--disable-extensions',
@@ -92,7 +95,7 @@ async def main():
92
95
  # '--disable-features=TranslateUI',
93
96
  "--disable-blink-features=AutomationControlled", # 禁用自动化控制标志
94
97
  "--start-maximized", # 最大化窗口
95
- ]
98
+ ],
96
99
  )
97
100
  # task = """
98
101
  # 1. 打开淘宝官网 (taobao.com)
@@ -118,13 +121,14 @@ async def main():
118
121
  llm=llm,
119
122
  # browser_profile=browser_profile,
120
123
  browser=browser,
121
- use_vision=False
124
+ use_vision=False,
122
125
  )
123
126
  result = await agent.run()
124
127
  print("---------- 最终结果 ----------")
125
128
  print(result)
126
129
  await browser.close()
127
130
 
131
+
128
132
  # if __name__ == "__main__":
129
133
  # asyncio.run(main())
130
134
  loop = asyncio.get_event_loop()
@@ -134,4 +138,4 @@ if loop.is_closed():
134
138
  try:
135
139
  loop.run_until_complete(main())
136
140
  finally:
137
- loop.close()
141
+ loop.close()
@@ -14,12 +14,16 @@ from scalebox.sandbox_async.main import AsyncSandbox
14
14
  from scalebox.sandbox.filesystem.watch_handle import FilesystemEvent
15
15
 
16
16
 
17
- logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
17
+ logging.basicConfig(
18
+ level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s"
19
+ )
18
20
  logger = logging.getLogger(__name__)
19
21
 
20
22
 
21
23
  async def main():
22
- async with await AsyncSandbox.create(template="base", timeout=300, metadata={"test": "watch_dir_async"}) as sandbox:
24
+ async with await AsyncSandbox.create(
25
+ template="base", timeout=300, metadata={"test": "watch_dir_async"}
26
+ ) as sandbox:
23
27
  watch_path = "/tmp/watch_async_test"
24
28
  await sandbox.files.make_dir(watch_path)
25
29
 
@@ -52,5 +56,3 @@ async def main():
52
56
 
53
57
  if __name__ == "__main__":
54
58
  asyncio.run(main())
55
-
56
-
@@ -5,9 +5,7 @@ from sandbox_async import AsyncSandbox
5
5
 
6
6
 
7
7
  async def main():
8
- sandbox = await AsyncSandbox.get_info(
9
- sandbox_id="", api_key="sk-Wk4Ig"
10
- )
8
+ sandbox = await AsyncSandbox.get_info(sandbox_id="", api_key="sk-Wk4Ig")
11
9
  print("✅ 沙箱已启动,sandbox_domain:", sandbox.sandbox_domain)
12
10
  print("✅ 沙箱已启动,ID:", sandbox.sandbox_id)
13
11
  print("✅ 沙箱已启动,connection_config:", sandbox.name)
@@ -3,11 +3,13 @@ import time
3
3
  from scalebox.sandbox.commands.command_handle import PtySize
4
4
  from scalebox.sandbox_sync.main import Sandbox
5
5
 
6
+
6
7
  def output_handler(output):
7
8
  """处理 输出的回调函数"""
8
9
  print(f"PTY 输出: {output}")
9
10
 
10
- sandboxes=Sandbox.list()
11
+
12
+ sandboxes = Sandbox.list()
11
13
  print(sandboxes)
12
- box=Sandbox.connect(sandbox_id="sbx-0b3ccqezz67asn3ax")
13
- print(box.files.list("/"))
14
+ box = Sandbox.connect(sandbox_id="sbx-0b3ccqezz67asn3ax")
15
+ print(box.files.list("/"))
@@ -13,7 +13,7 @@ async def pty_output_handler(output):
13
13
 
14
14
 
15
15
  async def main():
16
- sandbox = await (AsyncSandbox.create(timeout=3600))
16
+ sandbox = await AsyncSandbox.create(timeout=3600)
17
17
  proc = await sandbox.commands.run("echo hello from async")
18
18
  print("exit_code =", proc.exit_code)
19
19
  print("stdout =", proc.stdout)
@@ -24,99 +24,69 @@ async def main():
24
24
  on_data=pty_output_handler,
25
25
  cwd="/root",
26
26
  envs={"CUSTOM_ENV": "value"},
27
- request_timeout=40
27
+ request_timeout=40,
28
28
  )
29
29
  print(f"PTY 已创建,PID: {pty_handle.pid}")
30
30
 
31
31
  # 5. 向 PTY 发送输入
32
32
  await sandbox.pty.send_stdin(
33
- pid=pty_handle.pid,
34
- data=b"echo 'Hello from PTY 0s'\n",
35
- request_timeout=10
33
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 0s'\n", request_timeout=10
36
34
  )
37
35
  await asyncio.sleep(30)
38
36
  await sandbox.pty.send_stdin(
39
- pid=pty_handle.pid,
40
- data=b"echo 'Hello from PTY 30s'\n",
41
- request_timeout=10
37
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 30s'\n", request_timeout=10
42
38
  )
43
39
  await asyncio.sleep(30)
44
40
  await sandbox.pty.send_stdin(
45
- pid=pty_handle.pid,
46
- data=b"echo 'Hello from PTY 60s'\n",
47
- request_timeout=10
41
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 60s'\n", request_timeout=10
48
42
  )
49
43
  await asyncio.sleep(30)
50
44
  await sandbox.pty.send_stdin(
51
- pid=pty_handle.pid,
52
- data=b"echo 'Hello from PTY 90s'\n",
53
- request_timeout=10
45
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 90s'\n", request_timeout=10
54
46
  )
55
47
  await asyncio.sleep(30)
56
48
  await sandbox.pty.send_stdin(
57
- pid=pty_handle.pid,
58
- data=b"echo 'Hello from PTY 120s'\n",
59
- request_timeout=10
49
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 120s'\n", request_timeout=10
60
50
  )
61
51
  await asyncio.sleep(30)
62
52
  await sandbox.pty.send_stdin(
63
- pid=pty_handle.pid,
64
- data=b"echo 'Hello from PTY 150s'\n",
65
- request_timeout=10
53
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 150s'\n", request_timeout=10
66
54
  )
67
55
  await asyncio.sleep(30)
68
56
  await sandbox.pty.send_stdin(
69
- pid=pty_handle.pid,
70
- data=b"echo 'Hello from PTY 180s'\n",
71
- request_timeout=10
57
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 180s'\n", request_timeout=10
72
58
  )
73
59
  await asyncio.sleep(30)
74
60
  await sandbox.pty.send_stdin(
75
- pid=pty_handle.pid,
76
- data=b"echo 'Hello from PTY 210s'\n",
77
- request_timeout=10
61
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 210s'\n", request_timeout=10
78
62
  )
79
63
  await asyncio.sleep(30)
80
64
  await sandbox.pty.send_stdin(
81
- pid=pty_handle.pid,
82
- data=b"echo 'Hello from PTY 240s'\n",
83
- request_timeout=10
65
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 240s'\n", request_timeout=10
84
66
  )
85
67
  await asyncio.sleep(30)
86
68
  await sandbox.pty.send_stdin(
87
- pid=pty_handle.pid,
88
- data=b"echo 'Hello from PTY 270s'\n",
89
- request_timeout=10
69
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 270s'\n", request_timeout=10
90
70
  )
91
71
  await asyncio.sleep(30)
92
72
  await sandbox.pty.send_stdin(
93
- pid=pty_handle.pid,
94
- data=b"echo 'Hello from PTY 300s'\n",
95
- request_timeout=10
73
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 300s'\n", request_timeout=10
96
74
  )
97
75
  await asyncio.sleep(30)
98
76
  await sandbox.pty.send_stdin(
99
- pid=pty_handle.pid,
100
- data=b"echo 'Hello from PTY 330s'\n",
101
- request_timeout=10
77
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 330s'\n", request_timeout=10
102
78
  )
103
79
  await asyncio.sleep(30)
104
80
  await sandbox.pty.send_stdin(
105
- pid=pty_handle.pid,
106
- data=b"echo 'Hello from PTY 360s'\n",
107
- request_timeout=10
81
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 360s'\n", request_timeout=10
108
82
  )
109
83
  await asyncio.sleep(30)
110
84
  await sandbox.pty.send_stdin(
111
- pid=pty_handle.pid,
112
- data=b"echo 'Hello from PTY 390s'\n",
113
- request_timeout=10
85
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 390s'\n", request_timeout=10
114
86
  )
115
87
  await asyncio.sleep(30)
116
88
  await sandbox.pty.send_stdin(
117
- pid=pty_handle.pid,
118
- data=b"echo 'Hello from PTY 420s'\n",
119
- request_timeout=10
89
+ pid=pty_handle.pid, data=b"echo 'Hello from PTY 420s'\n", request_timeout=10
120
90
  )
121
91
 
122
92
  # 6. 调整 PTY 大小
@@ -7,6 +7,8 @@ from scalebox.sandbox_sync.main import Sandbox
7
7
  def output_handler(output):
8
8
  """处理 输出的回调函数"""
9
9
  print(f"PTY 输出: {output}")
10
+
11
+
10
12
  sandbox = Sandbox.create(api_key=f"sk-Wk4Ig")
11
13
  # print(sandbox.files.list("/root",2))
12
14
  # proc = sandbox.commands._start(
@@ -36,30 +38,32 @@ result = sandbox.commands.run(
36
38
  )
37
39
  print(result.exit_code)
38
40
  print(result.error)
39
- pty=sandbox.pty.create(size=PtySize(1024, 768),user="root",cwd="/root/",request_timeout=3600)
40
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"hello\"")
41
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\"")
41
+ pty = sandbox.pty.create(
42
+ size=PtySize(1024, 768), user="root", cwd="/root/", request_timeout=3600
43
+ )
44
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "hello"')
45
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!"')
42
46
  time.sleep(30)
43
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 30s")
47
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 30s')
44
48
  time.sleep(30)
45
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 60s")
49
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 60s')
46
50
  time.sleep(30)
47
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 90s")
51
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 90s')
48
52
  time.sleep(30)
49
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 120s")
53
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 120s')
50
54
  time.sleep(30)
51
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 150s")
55
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 150s')
52
56
  time.sleep(30)
53
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 180s")
57
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 180s')
54
58
  time.sleep(30)
55
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 210s")
59
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 210s')
56
60
  time.sleep(30)
57
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 240s")
61
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 240s')
58
62
  time.sleep(30)
59
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 270s")
63
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 270s')
60
64
  time.sleep(30)
61
- sandbox.pty.send_stdin(pid=pty.pid,data=b"echo \"world!\" 300s")
62
- result=pty.wait(
65
+ sandbox.pty.send_stdin(pid=pty.pid, data=b'echo "world!" 300s')
66
+ result = pty.wait(
63
67
  on_pty=lambda data: print("[STDOUT]", data, end=""),
64
68
  )
65
69
  print("exit_code =", result.exit_code)