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,1456 @@
1
+ # Generated Connect client code
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ import typing
7
+ from collections.abc import AsyncIterator, Iterable, Iterator
8
+
9
+ import aiohttp
10
+ import urllib3
11
+
12
+ try:
13
+ from connectrpc.client_async import AsyncConnectClient
14
+ from connectrpc.client_connect import ConnectProtocolError
15
+ from connectrpc.client_protocol import ConnectProtocol
16
+ from connectrpc.client_sync import ConnectClient
17
+ from connectrpc.headers import HeaderInput
18
+ from connectrpc.server import (
19
+ ClientRequest,
20
+ ClientStream,
21
+ ServerResponse,
22
+ ServerStream,
23
+ )
24
+ from connectrpc.server_sync import ConnectWSGI
25
+ from connectrpc.streams import AsyncStreamOutput, StreamInput, StreamOutput
26
+ from connectrpc.unary import ClientStreamingOutput, UnaryOutput
27
+ except ImportError:
28
+ # connectrpc not available, define dummy classes
29
+ class AsyncConnectClient:
30
+ pass
31
+
32
+ class ConnectProtocolError(Exception):
33
+ pass
34
+
35
+ class ConnectProtocol:
36
+ CONNECT_PROTOBUF = "connect_protobuf"
37
+
38
+ class ConnectClient:
39
+ pass
40
+
41
+ class HeaderInput:
42
+ pass
43
+
44
+ class ClientRequest:
45
+ pass
46
+
47
+ class ClientStream:
48
+ pass
49
+
50
+ class ServerResponse:
51
+ pass
52
+
53
+ class ServerStream:
54
+ pass
55
+
56
+ class ConnectWSGI:
57
+ pass
58
+
59
+ class AsyncStreamOutput:
60
+ pass
61
+
62
+ class StreamInput:
63
+ pass
64
+
65
+ class StreamOutput:
66
+ pass
67
+
68
+ class ClientStreamingOutput:
69
+ pass
70
+
71
+ class UnaryOutput:
72
+ pass
73
+
74
+
75
+ if typing.TYPE_CHECKING:
76
+ # wsgiref.types was added in Python 3.11.
77
+ if sys.version_info >= (3, 11):
78
+ from wsgiref.types import WSGIApplication
79
+ else:
80
+ from _typeshed.wsgi import WSGIApplication
81
+
82
+ from . import api_pb2
83
+
84
+
85
+ class FilesystemClient:
86
+ def __init__(
87
+ self,
88
+ base_url: str,
89
+ http_client: urllib3.PoolManager | None = None,
90
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
91
+ ):
92
+ self.base_url = base_url
93
+ self._connect_client = ConnectClient(http_client, protocol)
94
+
95
+ def call_stat(
96
+ self,
97
+ req: api_pb2.StatRequest,
98
+ extra_headers: HeaderInput | None = None,
99
+ timeout_seconds: float | None = None,
100
+ ) -> UnaryOutput[api_pb2.StatResponse]:
101
+ """Low-level method to call Stat, granting access to errors and metadata"""
102
+ url = self.base_url + "/sandboxagent.Filesystem/Stat"
103
+ return self._connect_client.call_unary(
104
+ url, req, api_pb2.StatResponse, extra_headers, timeout_seconds
105
+ )
106
+
107
+ def stat(
108
+ self,
109
+ req: api_pb2.StatRequest,
110
+ extra_headers: HeaderInput | None = None,
111
+ timeout_seconds: float | None = None,
112
+ ) -> api_pb2.StatResponse:
113
+ response = self.call_stat(req, extra_headers, timeout_seconds)
114
+ err = response.error()
115
+ if err is not None:
116
+ raise err
117
+ msg = response.message()
118
+ if msg is None:
119
+ raise ConnectProtocolError("missing response message")
120
+ return msg
121
+
122
+ def call_make_dir(
123
+ self,
124
+ req: api_pb2.MakeDirRequest,
125
+ extra_headers: HeaderInput | None = None,
126
+ timeout_seconds: float | None = None,
127
+ ) -> UnaryOutput[api_pb2.MakeDirResponse]:
128
+ """Low-level method to call MakeDir, granting access to errors and metadata"""
129
+ url = self.base_url + "/sandboxagent.Filesystem/MakeDir"
130
+ return self._connect_client.call_unary(
131
+ url, req, api_pb2.MakeDirResponse, extra_headers, timeout_seconds
132
+ )
133
+
134
+ def make_dir(
135
+ self,
136
+ req: api_pb2.MakeDirRequest,
137
+ extra_headers: HeaderInput | None = None,
138
+ timeout_seconds: float | None = None,
139
+ ) -> api_pb2.MakeDirResponse:
140
+ response = self.call_make_dir(req, extra_headers, timeout_seconds)
141
+ err = response.error()
142
+ if err is not None:
143
+ raise err
144
+ msg = response.message()
145
+ if msg is None:
146
+ raise ConnectProtocolError("missing response message")
147
+ return msg
148
+
149
+ def call_move(
150
+ self,
151
+ req: api_pb2.MoveRequest,
152
+ extra_headers: HeaderInput | None = None,
153
+ timeout_seconds: float | None = None,
154
+ ) -> UnaryOutput[api_pb2.MoveResponse]:
155
+ """Low-level method to call Move, granting access to errors and metadata"""
156
+ url = self.base_url + "/sandboxagent.Filesystem/Move"
157
+ return self._connect_client.call_unary(
158
+ url, req, api_pb2.MoveResponse, extra_headers, timeout_seconds
159
+ )
160
+
161
+ def move(
162
+ self,
163
+ req: api_pb2.MoveRequest,
164
+ extra_headers: HeaderInput | None = None,
165
+ timeout_seconds: float | None = None,
166
+ ) -> api_pb2.MoveResponse:
167
+ response = self.call_move(req, extra_headers, timeout_seconds)
168
+ err = response.error()
169
+ if err is not None:
170
+ raise err
171
+ msg = response.message()
172
+ if msg is None:
173
+ raise ConnectProtocolError("missing response message")
174
+ return msg
175
+
176
+ def call_list_dir(
177
+ self,
178
+ req: api_pb2.ListDirRequest,
179
+ extra_headers: HeaderInput | None = None,
180
+ timeout_seconds: float | None = None,
181
+ ) -> UnaryOutput[api_pb2.ListDirResponse]:
182
+ """Low-level method to call ListDir, granting access to errors and metadata"""
183
+ url = self.base_url + "/sandboxagent.Filesystem/ListDir"
184
+ return self._connect_client.call_unary(
185
+ url, req, api_pb2.ListDirResponse, extra_headers, timeout_seconds
186
+ )
187
+
188
+ def list_dir(
189
+ self,
190
+ req: api_pb2.ListDirRequest,
191
+ extra_headers: HeaderInput | None = None,
192
+ timeout_seconds: float | None = None,
193
+ ) -> api_pb2.ListDirResponse:
194
+ response = self.call_list_dir(req, extra_headers, timeout_seconds)
195
+ err = response.error()
196
+ if err is not None:
197
+ raise err
198
+ msg = response.message()
199
+ if msg is None:
200
+ raise ConnectProtocolError("missing response message")
201
+ return msg
202
+
203
+ def call_remove(
204
+ self,
205
+ req: api_pb2.RemoveRequest,
206
+ extra_headers: HeaderInput | None = None,
207
+ timeout_seconds: float | None = None,
208
+ ) -> UnaryOutput[api_pb2.RemoveResponse]:
209
+ """Low-level method to call Remove, granting access to errors and metadata"""
210
+ url = self.base_url + "/sandboxagent.Filesystem/Remove"
211
+ return self._connect_client.call_unary(
212
+ url, req, api_pb2.RemoveResponse, extra_headers, timeout_seconds
213
+ )
214
+
215
+ def remove(
216
+ self,
217
+ req: api_pb2.RemoveRequest,
218
+ extra_headers: HeaderInput | None = None,
219
+ timeout_seconds: float | None = None,
220
+ ) -> api_pb2.RemoveResponse:
221
+ response = self.call_remove(req, extra_headers, timeout_seconds)
222
+ err = response.error()
223
+ if err is not None:
224
+ raise err
225
+ msg = response.message()
226
+ if msg is None:
227
+ raise ConnectProtocolError("missing response message")
228
+ return msg
229
+
230
+ def watch_dir(
231
+ self,
232
+ req: api_pb2.WatchDirRequest,
233
+ extra_headers: HeaderInput | None = None,
234
+ timeout_seconds: float | None = None,
235
+ ) -> Iterator[api_pb2.WatchDirResponse]:
236
+ return self._watch_dir_iterator(req, extra_headers, timeout_seconds)
237
+
238
+ def _watch_dir_iterator(
239
+ self,
240
+ req: api_pb2.WatchDirRequest,
241
+ extra_headers: HeaderInput | None = None,
242
+ timeout_seconds: float | None = None,
243
+ ) -> Iterator[api_pb2.WatchDirResponse]:
244
+ stream_output = self.call_watch_dir(req, extra_headers)
245
+ err = stream_output.error()
246
+ if err is not None:
247
+ raise err
248
+ yield from stream_output
249
+ err = stream_output.error()
250
+ if err is not None:
251
+ raise err
252
+
253
+ def call_watch_dir(
254
+ self,
255
+ req: api_pb2.WatchDirRequest,
256
+ extra_headers: HeaderInput | None = None,
257
+ timeout_seconds: float | None = None,
258
+ ) -> StreamOutput[api_pb2.WatchDirResponse]:
259
+ """Low-level method to call WatchDir, granting access to errors and metadata"""
260
+ url = self.base_url + "/sandboxagent.Filesystem/WatchDir"
261
+ return self._connect_client.call_server_streaming(
262
+ url, req, api_pb2.WatchDirResponse, extra_headers, timeout_seconds
263
+ )
264
+
265
+ def call_create_watcher(
266
+ self,
267
+ req: api_pb2.CreateWatcherRequest,
268
+ extra_headers: HeaderInput | None = None,
269
+ timeout_seconds: float | None = None,
270
+ ) -> UnaryOutput[api_pb2.CreateWatcherResponse]:
271
+ """Low-level method to call CreateWatcher, granting access to errors and metadata"""
272
+ url = self.base_url + "/sandboxagent.Filesystem/CreateWatcher"
273
+ return self._connect_client.call_unary(
274
+ url, req, api_pb2.CreateWatcherResponse, extra_headers, timeout_seconds
275
+ )
276
+
277
+ def create_watcher(
278
+ self,
279
+ req: api_pb2.CreateWatcherRequest,
280
+ extra_headers: HeaderInput | None = None,
281
+ timeout_seconds: float | None = None,
282
+ ) -> api_pb2.CreateWatcherResponse:
283
+ response = self.call_create_watcher(req, extra_headers, timeout_seconds)
284
+ err = response.error()
285
+ if err is not None:
286
+ raise err
287
+ msg = response.message()
288
+ if msg is None:
289
+ raise ConnectProtocolError("missing response message")
290
+ return msg
291
+
292
+ def call_get_watcher_events(
293
+ self,
294
+ req: api_pb2.GetWatcherEventsRequest,
295
+ extra_headers: HeaderInput | None = None,
296
+ timeout_seconds: float | None = None,
297
+ ) -> UnaryOutput[api_pb2.GetWatcherEventsResponse]:
298
+ """Low-level method to call GetWatcherEvents, granting access to errors and metadata"""
299
+ url = self.base_url + "/sandboxagent.Filesystem/GetWatcherEvents"
300
+ return self._connect_client.call_unary(
301
+ url, req, api_pb2.GetWatcherEventsResponse, extra_headers, timeout_seconds
302
+ )
303
+
304
+ def get_watcher_events(
305
+ self,
306
+ req: api_pb2.GetWatcherEventsRequest,
307
+ extra_headers: HeaderInput | None = None,
308
+ timeout_seconds: float | None = None,
309
+ ) -> api_pb2.GetWatcherEventsResponse:
310
+ response = self.call_get_watcher_events(req, extra_headers, timeout_seconds)
311
+ err = response.error()
312
+ if err is not None:
313
+ raise err
314
+ msg = response.message()
315
+ if msg is None:
316
+ raise ConnectProtocolError("missing response message")
317
+ return msg
318
+
319
+ def call_remove_watcher(
320
+ self,
321
+ req: api_pb2.RemoveWatcherRequest,
322
+ extra_headers: HeaderInput | None = None,
323
+ timeout_seconds: float | None = None,
324
+ ) -> UnaryOutput[api_pb2.RemoveWatcherResponse]:
325
+ """Low-level method to call RemoveWatcher, granting access to errors and metadata"""
326
+ url = self.base_url + "/sandboxagent.Filesystem/RemoveWatcher"
327
+ return self._connect_client.call_unary(
328
+ url, req, api_pb2.RemoveWatcherResponse, extra_headers, timeout_seconds
329
+ )
330
+
331
+ def remove_watcher(
332
+ self,
333
+ req: api_pb2.RemoveWatcherRequest,
334
+ extra_headers: HeaderInput | None = None,
335
+ timeout_seconds: float | None = None,
336
+ ) -> api_pb2.RemoveWatcherResponse:
337
+ response = self.call_remove_watcher(req, extra_headers, timeout_seconds)
338
+ err = response.error()
339
+ if err is not None:
340
+ raise err
341
+ msg = response.message()
342
+ if msg is None:
343
+ raise ConnectProtocolError("missing response message")
344
+ return msg
345
+
346
+
347
+ class AsyncFilesystemClient:
348
+ def __init__(
349
+ self,
350
+ base_url: str,
351
+ http_client: aiohttp.ClientSession,
352
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
353
+ ):
354
+ self.base_url = base_url
355
+ self._connect_client = AsyncConnectClient(http_client, protocol)
356
+
357
+ async def call_stat(
358
+ self,
359
+ req: api_pb2.StatRequest,
360
+ extra_headers: HeaderInput | None = None,
361
+ timeout_seconds: float | None = None,
362
+ ) -> UnaryOutput[api_pb2.StatResponse]:
363
+ """Low-level method to call Stat, granting access to errors and metadata"""
364
+ url = self.base_url + "/sandboxagent.Filesystem/Stat"
365
+ return await self._connect_client.call_unary(
366
+ url, req, api_pb2.StatResponse, extra_headers, timeout_seconds
367
+ )
368
+
369
+ async def stat(
370
+ self,
371
+ req: api_pb2.StatRequest,
372
+ extra_headers: HeaderInput | None = None,
373
+ timeout_seconds: float | None = None,
374
+ ) -> api_pb2.StatResponse:
375
+ response = await self.call_stat(req, extra_headers, timeout_seconds)
376
+ err = response.error()
377
+ if err is not None:
378
+ raise err
379
+ msg = response.message()
380
+ if msg is None:
381
+ raise ConnectProtocolError("missing response message")
382
+ return msg
383
+
384
+ async def call_make_dir(
385
+ self,
386
+ req: api_pb2.MakeDirRequest,
387
+ extra_headers: HeaderInput | None = None,
388
+ timeout_seconds: float | None = None,
389
+ ) -> UnaryOutput[api_pb2.MakeDirResponse]:
390
+ """Low-level method to call MakeDir, granting access to errors and metadata"""
391
+ url = self.base_url + "/sandboxagent.Filesystem/MakeDir"
392
+ return await self._connect_client.call_unary(
393
+ url, req, api_pb2.MakeDirResponse, extra_headers, timeout_seconds
394
+ )
395
+
396
+ async def make_dir(
397
+ self,
398
+ req: api_pb2.MakeDirRequest,
399
+ extra_headers: HeaderInput | None = None,
400
+ timeout_seconds: float | None = None,
401
+ ) -> api_pb2.MakeDirResponse:
402
+ response = await self.call_make_dir(req, extra_headers, timeout_seconds)
403
+ err = response.error()
404
+ if err is not None:
405
+ raise err
406
+ msg = response.message()
407
+ if msg is None:
408
+ raise ConnectProtocolError("missing response message")
409
+ return msg
410
+
411
+ async def call_move(
412
+ self,
413
+ req: api_pb2.MoveRequest,
414
+ extra_headers: HeaderInput | None = None,
415
+ timeout_seconds: float | None = None,
416
+ ) -> UnaryOutput[api_pb2.MoveResponse]:
417
+ """Low-level method to call Move, granting access to errors and metadata"""
418
+ url = self.base_url + "/sandboxagent.Filesystem/Move"
419
+ return await self._connect_client.call_unary(
420
+ url, req, api_pb2.MoveResponse, extra_headers, timeout_seconds
421
+ )
422
+
423
+ async def move(
424
+ self,
425
+ req: api_pb2.MoveRequest,
426
+ extra_headers: HeaderInput | None = None,
427
+ timeout_seconds: float | None = None,
428
+ ) -> api_pb2.MoveResponse:
429
+ response = await self.call_move(req, extra_headers, timeout_seconds)
430
+ err = response.error()
431
+ if err is not None:
432
+ raise err
433
+ msg = response.message()
434
+ if msg is None:
435
+ raise ConnectProtocolError("missing response message")
436
+ return msg
437
+
438
+ async def call_list_dir(
439
+ self,
440
+ req: api_pb2.ListDirRequest,
441
+ extra_headers: HeaderInput | None = None,
442
+ timeout_seconds: float | None = None,
443
+ ) -> UnaryOutput[api_pb2.ListDirResponse]:
444
+ """Low-level method to call ListDir, granting access to errors and metadata"""
445
+ url = self.base_url + "/sandboxagent.Filesystem/ListDir"
446
+ return await self._connect_client.call_unary(
447
+ url, req, api_pb2.ListDirResponse, extra_headers, timeout_seconds
448
+ )
449
+
450
+ async def list_dir(
451
+ self,
452
+ req: api_pb2.ListDirRequest,
453
+ extra_headers: HeaderInput | None = None,
454
+ timeout_seconds: float | None = None,
455
+ ) -> api_pb2.ListDirResponse:
456
+ response = await self.call_list_dir(req, extra_headers, timeout_seconds)
457
+ err = response.error()
458
+ if err is not None:
459
+ raise err
460
+ msg = response.message()
461
+ if msg is None:
462
+ raise ConnectProtocolError("missing response message")
463
+ return msg
464
+
465
+ async def call_remove(
466
+ self,
467
+ req: api_pb2.RemoveRequest,
468
+ extra_headers: HeaderInput | None = None,
469
+ timeout_seconds: float | None = None,
470
+ ) -> UnaryOutput[api_pb2.RemoveResponse]:
471
+ """Low-level method to call Remove, granting access to errors and metadata"""
472
+ url = self.base_url + "/sandboxagent.Filesystem/Remove"
473
+ return await self._connect_client.call_unary(
474
+ url, req, api_pb2.RemoveResponse, extra_headers, timeout_seconds
475
+ )
476
+
477
+ async def remove(
478
+ self,
479
+ req: api_pb2.RemoveRequest,
480
+ extra_headers: HeaderInput | None = None,
481
+ timeout_seconds: float | None = None,
482
+ ) -> api_pb2.RemoveResponse:
483
+ response = await self.call_remove(req, extra_headers, timeout_seconds)
484
+ err = response.error()
485
+ if err is not None:
486
+ raise err
487
+ msg = response.message()
488
+ if msg is None:
489
+ raise ConnectProtocolError("missing response message")
490
+ return msg
491
+
492
+ def watch_dir(
493
+ self,
494
+ req: api_pb2.WatchDirRequest,
495
+ extra_headers: HeaderInput | None = None,
496
+ timeout_seconds: float | None = None,
497
+ ) -> AsyncIterator[api_pb2.WatchDirResponse]:
498
+ return self._watch_dir_iterator(req, extra_headers, timeout_seconds)
499
+
500
+ async def _watch_dir_iterator(
501
+ self,
502
+ req: api_pb2.WatchDirRequest,
503
+ extra_headers: HeaderInput | None = None,
504
+ timeout_seconds: float | None = None,
505
+ ) -> AsyncIterator[api_pb2.WatchDirResponse]:
506
+ stream_output = await self.call_watch_dir(req, extra_headers)
507
+ err = stream_output.error()
508
+ if err is not None:
509
+ raise err
510
+ async with stream_output as stream:
511
+ async for response in stream:
512
+ yield response
513
+ err = stream.error()
514
+ if err is not None:
515
+ raise err
516
+
517
+ async def call_watch_dir(
518
+ self,
519
+ req: api_pb2.WatchDirRequest,
520
+ extra_headers: HeaderInput | None = None,
521
+ timeout_seconds: float | None = None,
522
+ ) -> AsyncStreamOutput[api_pb2.WatchDirResponse]:
523
+ """Low-level method to call WatchDir, granting access to errors and metadata"""
524
+ url = self.base_url + "/sandboxagent.Filesystem/WatchDir"
525
+ return await self._connect_client.call_server_streaming(
526
+ url, req, api_pb2.WatchDirResponse, extra_headers, timeout_seconds
527
+ )
528
+
529
+ async def call_create_watcher(
530
+ self,
531
+ req: api_pb2.CreateWatcherRequest,
532
+ extra_headers: HeaderInput | None = None,
533
+ timeout_seconds: float | None = None,
534
+ ) -> UnaryOutput[api_pb2.CreateWatcherResponse]:
535
+ """Low-level method to call CreateWatcher, granting access to errors and metadata"""
536
+ url = self.base_url + "/sandboxagent.Filesystem/CreateWatcher"
537
+ return await self._connect_client.call_unary(
538
+ url, req, api_pb2.CreateWatcherResponse, extra_headers, timeout_seconds
539
+ )
540
+
541
+ async def create_watcher(
542
+ self,
543
+ req: api_pb2.CreateWatcherRequest,
544
+ extra_headers: HeaderInput | None = None,
545
+ timeout_seconds: float | None = None,
546
+ ) -> api_pb2.CreateWatcherResponse:
547
+ response = await self.call_create_watcher(req, extra_headers, timeout_seconds)
548
+ err = response.error()
549
+ if err is not None:
550
+ raise err
551
+ msg = response.message()
552
+ if msg is None:
553
+ raise ConnectProtocolError("missing response message")
554
+ return msg
555
+
556
+ async def call_get_watcher_events(
557
+ self,
558
+ req: api_pb2.GetWatcherEventsRequest,
559
+ extra_headers: HeaderInput | None = None,
560
+ timeout_seconds: float | None = None,
561
+ ) -> UnaryOutput[api_pb2.GetWatcherEventsResponse]:
562
+ """Low-level method to call GetWatcherEvents, granting access to errors and metadata"""
563
+ url = self.base_url + "/sandboxagent.Filesystem/GetWatcherEvents"
564
+ return await self._connect_client.call_unary(
565
+ url, req, api_pb2.GetWatcherEventsResponse, extra_headers, timeout_seconds
566
+ )
567
+
568
+ async def get_watcher_events(
569
+ self,
570
+ req: api_pb2.GetWatcherEventsRequest,
571
+ extra_headers: HeaderInput | None = None,
572
+ timeout_seconds: float | None = None,
573
+ ) -> api_pb2.GetWatcherEventsResponse:
574
+ response = await self.call_get_watcher_events(
575
+ req, extra_headers, timeout_seconds
576
+ )
577
+ err = response.error()
578
+ if err is not None:
579
+ raise err
580
+ msg = response.message()
581
+ if msg is None:
582
+ raise ConnectProtocolError("missing response message")
583
+ return msg
584
+
585
+ async def call_remove_watcher(
586
+ self,
587
+ req: api_pb2.RemoveWatcherRequest,
588
+ extra_headers: HeaderInput | None = None,
589
+ timeout_seconds: float | None = None,
590
+ ) -> UnaryOutput[api_pb2.RemoveWatcherResponse]:
591
+ """Low-level method to call RemoveWatcher, granting access to errors and metadata"""
592
+ url = self.base_url + "/sandboxagent.Filesystem/RemoveWatcher"
593
+ return await self._connect_client.call_unary(
594
+ url, req, api_pb2.RemoveWatcherResponse, extra_headers, timeout_seconds
595
+ )
596
+
597
+ async def remove_watcher(
598
+ self,
599
+ req: api_pb2.RemoveWatcherRequest,
600
+ extra_headers: HeaderInput | None = None,
601
+ timeout_seconds: float | None = None,
602
+ ) -> api_pb2.RemoveWatcherResponse:
603
+ response = await self.call_remove_watcher(req, extra_headers, timeout_seconds)
604
+ err = response.error()
605
+ if err is not None:
606
+ raise err
607
+ msg = response.message()
608
+ if msg is None:
609
+ raise ConnectProtocolError("missing response message")
610
+ return msg
611
+
612
+
613
+ @typing.runtime_checkable
614
+ class FilesystemProtocol(typing.Protocol):
615
+ def stat(
616
+ self, req: ClientRequest[api_pb2.StatRequest]
617
+ ) -> ServerResponse[api_pb2.StatResponse]: ...
618
+ def make_dir(
619
+ self, req: ClientRequest[api_pb2.MakeDirRequest]
620
+ ) -> ServerResponse[api_pb2.MakeDirResponse]: ...
621
+ def move(
622
+ self, req: ClientRequest[api_pb2.MoveRequest]
623
+ ) -> ServerResponse[api_pb2.MoveResponse]: ...
624
+ def list_dir(
625
+ self, req: ClientRequest[api_pb2.ListDirRequest]
626
+ ) -> ServerResponse[api_pb2.ListDirResponse]: ...
627
+ def remove(
628
+ self, req: ClientRequest[api_pb2.RemoveRequest]
629
+ ) -> ServerResponse[api_pb2.RemoveResponse]: ...
630
+ def watch_dir(
631
+ self, req: ClientRequest[api_pb2.WatchDirRequest]
632
+ ) -> ServerStream[api_pb2.WatchDirResponse]: ...
633
+ def create_watcher(
634
+ self, req: ClientRequest[api_pb2.CreateWatcherRequest]
635
+ ) -> ServerResponse[api_pb2.CreateWatcherResponse]: ...
636
+ def get_watcher_events(
637
+ self, req: ClientRequest[api_pb2.GetWatcherEventsRequest]
638
+ ) -> ServerResponse[api_pb2.GetWatcherEventsResponse]: ...
639
+ def remove_watcher(
640
+ self, req: ClientRequest[api_pb2.RemoveWatcherRequest]
641
+ ) -> ServerResponse[api_pb2.RemoveWatcherResponse]: ...
642
+
643
+
644
+ FILESYSTEM_PATH_PREFIX = "/sandboxagent.Filesystem"
645
+
646
+
647
+ def wsgi_filesystem(implementation: FilesystemProtocol) -> WSGIApplication:
648
+ app = ConnectWSGI()
649
+ app.register_unary_rpc(
650
+ "/sandboxagent.Filesystem/Stat", implementation.stat, api_pb2.StatRequest
651
+ )
652
+ app.register_unary_rpc(
653
+ "/sandboxagent.Filesystem/MakeDir",
654
+ implementation.make_dir,
655
+ api_pb2.MakeDirRequest,
656
+ )
657
+ app.register_unary_rpc(
658
+ "/sandboxagent.Filesystem/Move", implementation.move, api_pb2.MoveRequest
659
+ )
660
+ app.register_unary_rpc(
661
+ "/sandboxagent.Filesystem/ListDir",
662
+ implementation.list_dir,
663
+ api_pb2.ListDirRequest,
664
+ )
665
+ app.register_unary_rpc(
666
+ "/sandboxagent.Filesystem/Remove", implementation.remove, api_pb2.RemoveRequest
667
+ )
668
+ app.register_server_streaming_rpc(
669
+ "/sandboxagent.Filesystem/WatchDir",
670
+ implementation.watch_dir,
671
+ api_pb2.WatchDirRequest,
672
+ )
673
+ app.register_unary_rpc(
674
+ "/sandboxagent.Filesystem/CreateWatcher",
675
+ implementation.create_watcher,
676
+ api_pb2.CreateWatcherRequest,
677
+ )
678
+ app.register_unary_rpc(
679
+ "/sandboxagent.Filesystem/GetWatcherEvents",
680
+ implementation.get_watcher_events,
681
+ api_pb2.GetWatcherEventsRequest,
682
+ )
683
+ app.register_unary_rpc(
684
+ "/sandboxagent.Filesystem/RemoveWatcher",
685
+ implementation.remove_watcher,
686
+ api_pb2.RemoveWatcherRequest,
687
+ )
688
+ return app
689
+
690
+
691
+ class ProcessClient:
692
+ def __init__(
693
+ self,
694
+ base_url: str,
695
+ http_client: urllib3.PoolManager | None = None,
696
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
697
+ ):
698
+ self.base_url = base_url
699
+ self._connect_client = ConnectClient(http_client, protocol)
700
+
701
+ def call_list(
702
+ self,
703
+ req: api_pb2.ListRequest,
704
+ extra_headers: HeaderInput | None = None,
705
+ timeout_seconds: float | None = None,
706
+ ) -> UnaryOutput[api_pb2.ListResponse]:
707
+ """Low-level method to call List, granting access to errors and metadata"""
708
+ url = self.base_url + "/sandboxagent.Process/List"
709
+ return self._connect_client.call_unary(
710
+ url, req, api_pb2.ListResponse, extra_headers, timeout_seconds
711
+ )
712
+
713
+ def list(
714
+ self,
715
+ req: api_pb2.ListRequest,
716
+ extra_headers: HeaderInput | None = None,
717
+ timeout_seconds: float | None = None,
718
+ ) -> api_pb2.ListResponse:
719
+ response = self.call_list(req, extra_headers, timeout_seconds)
720
+ err = response.error()
721
+ if err is not None:
722
+ raise err
723
+ msg = response.message()
724
+ if msg is None:
725
+ raise ConnectProtocolError("missing response message")
726
+ return msg
727
+
728
+ def connect(
729
+ self,
730
+ req: api_pb2.ConnectRequest,
731
+ extra_headers: HeaderInput | None = None,
732
+ timeout_seconds: float | None = None,
733
+ ) -> Iterator[api_pb2.ConnectResponse]:
734
+ return self._connect_iterator(req, extra_headers, timeout_seconds)
735
+
736
+ def _connect_iterator(
737
+ self,
738
+ req: api_pb2.ConnectRequest,
739
+ extra_headers: HeaderInput | None = None,
740
+ timeout_seconds: float | None = None,
741
+ ) -> Iterator[api_pb2.ConnectResponse]:
742
+ stream_output = self.call_connect(req, extra_headers)
743
+ err = stream_output.error()
744
+ if err is not None:
745
+ raise err
746
+ yield from stream_output
747
+ err = stream_output.error()
748
+ if err is not None:
749
+ raise err
750
+
751
+ def call_connect(
752
+ self,
753
+ req: api_pb2.ConnectRequest,
754
+ extra_headers: HeaderInput | None = None,
755
+ timeout_seconds: float | None = None,
756
+ ) -> StreamOutput[api_pb2.ConnectResponse]:
757
+ """Low-level method to call Connect, granting access to errors and metadata"""
758
+ url = self.base_url + "/sandboxagent.Process/Connect"
759
+ return self._connect_client.call_server_streaming(
760
+ url, req, api_pb2.ConnectResponse, extra_headers, timeout_seconds
761
+ )
762
+
763
+ def start(
764
+ self,
765
+ req: api_pb2.StartRequest,
766
+ extra_headers: HeaderInput | None = None,
767
+ timeout_seconds: float | None = None,
768
+ ) -> Iterator[api_pb2.StartResponse]:
769
+ return self._start_iterator(req, extra_headers, timeout_seconds)
770
+
771
+ def _start_iterator(
772
+ self,
773
+ req: api_pb2.StartRequest,
774
+ extra_headers: HeaderInput | None = None,
775
+ timeout_seconds: float | None = None,
776
+ ) -> Iterator[api_pb2.StartResponse]:
777
+ stream_output = self.call_start(req, extra_headers)
778
+ err = stream_output.error()
779
+ if err is not None:
780
+ raise err
781
+ yield from stream_output
782
+ err = stream_output.error()
783
+ if err is not None:
784
+ raise err
785
+
786
+ def call_start(
787
+ self,
788
+ req: api_pb2.StartRequest,
789
+ extra_headers: HeaderInput | None = None,
790
+ timeout_seconds: float | None = None,
791
+ ) -> StreamOutput[api_pb2.StartResponse]:
792
+ """Low-level method to call Start, granting access to errors and metadata"""
793
+ url = self.base_url + "/sandboxagent.Process/Start"
794
+ return self._connect_client.call_server_streaming(
795
+ url, req, api_pb2.StartResponse, extra_headers, timeout_seconds
796
+ )
797
+
798
+ def call_update(
799
+ self,
800
+ req: api_pb2.UpdateRequest,
801
+ extra_headers: HeaderInput | None = None,
802
+ timeout_seconds: float | None = None,
803
+ ) -> UnaryOutput[api_pb2.UpdateResponse]:
804
+ """Low-level method to call Update, granting access to errors and metadata"""
805
+ url = self.base_url + "/sandboxagent.Process/Update"
806
+ return self._connect_client.call_unary(
807
+ url, req, api_pb2.UpdateResponse, extra_headers, timeout_seconds
808
+ )
809
+
810
+ def update(
811
+ self,
812
+ req: api_pb2.UpdateRequest,
813
+ extra_headers: HeaderInput | None = None,
814
+ timeout_seconds: float | None = None,
815
+ ) -> api_pb2.UpdateResponse:
816
+ response = self.call_update(req, extra_headers, timeout_seconds)
817
+ err = response.error()
818
+ if err is not None:
819
+ raise err
820
+ msg = response.message()
821
+ if msg is None:
822
+ raise ConnectProtocolError("missing response message")
823
+ return msg
824
+
825
+ def call_stream_input(
826
+ self,
827
+ reqs: Iterable[api_pb2.StreamInputRequest],
828
+ extra_headers: HeaderInput | None = None,
829
+ timeout_seconds: float | None = None,
830
+ ) -> ClientStreamingOutput[api_pb2.StreamInputResponse]:
831
+ """Low-level method to call StreamInput, granting access to errors and metadata"""
832
+ url = self.base_url + "/sandboxagent.Process/StreamInput"
833
+ return self._connect_client.call_client_streaming(
834
+ url, reqs, api_pb2.StreamInputResponse, extra_headers, timeout_seconds
835
+ )
836
+
837
+ def stream_input(
838
+ self,
839
+ reqs: Iterable[api_pb2.StreamInputRequest],
840
+ extra_headers: HeaderInput | None = None,
841
+ timeout_seconds: float | None = None,
842
+ ) -> api_pb2.StreamInputResponse:
843
+ client_stream_output = self.call_stream_input(reqs, extra_headers)
844
+ err = client_stream_output.error()
845
+ if err is not None:
846
+ raise err
847
+ msg = client_stream_output.message()
848
+ if msg is None:
849
+ raise RuntimeError("ClientStreamOutput has empty error and message")
850
+ return msg
851
+
852
+ def call_send_input(
853
+ self,
854
+ req: api_pb2.SendInputRequest,
855
+ extra_headers: HeaderInput | None = None,
856
+ timeout_seconds: float | None = None,
857
+ ) -> UnaryOutput[api_pb2.SendInputResponse]:
858
+ """Low-level method to call SendInput, granting access to errors and metadata"""
859
+ url = self.base_url + "/sandboxagent.Process/SendInput"
860
+ return self._connect_client.call_unary(
861
+ url, req, api_pb2.SendInputResponse, extra_headers, timeout_seconds
862
+ )
863
+
864
+ def send_input(
865
+ self,
866
+ req: api_pb2.SendInputRequest,
867
+ extra_headers: HeaderInput | None = None,
868
+ timeout_seconds: float | None = None,
869
+ ) -> api_pb2.SendInputResponse:
870
+ response = self.call_send_input(req, extra_headers, timeout_seconds)
871
+ err = response.error()
872
+ if err is not None:
873
+ raise err
874
+ msg = response.message()
875
+ if msg is None:
876
+ raise ConnectProtocolError("missing response message")
877
+ return msg
878
+
879
+ def call_send_signal(
880
+ self,
881
+ req: api_pb2.SendSignalRequest,
882
+ extra_headers: HeaderInput | None = None,
883
+ timeout_seconds: float | None = None,
884
+ ) -> UnaryOutput[api_pb2.SendSignalResponse]:
885
+ """Low-level method to call SendSignal, granting access to errors and metadata"""
886
+ url = self.base_url + "/sandboxagent.Process/SendSignal"
887
+ return self._connect_client.call_unary(
888
+ url, req, api_pb2.SendSignalResponse, extra_headers, timeout_seconds
889
+ )
890
+
891
+ def send_signal(
892
+ self,
893
+ req: api_pb2.SendSignalRequest,
894
+ extra_headers: HeaderInput | None = None,
895
+ timeout_seconds: float | None = None,
896
+ ) -> api_pb2.SendSignalResponse:
897
+ response = self.call_send_signal(req, extra_headers, timeout_seconds)
898
+ err = response.error()
899
+ if err is not None:
900
+ raise err
901
+ msg = response.message()
902
+ if msg is None:
903
+ raise ConnectProtocolError("missing response message")
904
+ return msg
905
+
906
+
907
+ class AsyncProcessClient:
908
+ def __init__(
909
+ self,
910
+ base_url: str,
911
+ http_client: aiohttp.ClientSession,
912
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
913
+ ):
914
+ self.base_url = base_url
915
+ self._connect_client = AsyncConnectClient(http_client, protocol)
916
+
917
+ async def call_list(
918
+ self,
919
+ req: api_pb2.ListRequest,
920
+ extra_headers: HeaderInput | None = None,
921
+ timeout_seconds: float | None = None,
922
+ ) -> UnaryOutput[api_pb2.ListResponse]:
923
+ """Low-level method to call List, granting access to errors and metadata"""
924
+ url = self.base_url + "/sandboxagent.Process/List"
925
+ return await self._connect_client.call_unary(
926
+ url, req, api_pb2.ListResponse, extra_headers, timeout_seconds
927
+ )
928
+
929
+ async def list(
930
+ self,
931
+ req: api_pb2.ListRequest,
932
+ extra_headers: HeaderInput | None = None,
933
+ timeout_seconds: float | None = None,
934
+ ) -> api_pb2.ListResponse:
935
+ response = await self.call_list(req, extra_headers, timeout_seconds)
936
+ err = response.error()
937
+ if err is not None:
938
+ raise err
939
+ msg = response.message()
940
+ if msg is None:
941
+ raise ConnectProtocolError("missing response message")
942
+ return msg
943
+
944
+ def connect(
945
+ self,
946
+ req: api_pb2.ConnectRequest,
947
+ extra_headers: HeaderInput | None = None,
948
+ timeout_seconds: float | None = None,
949
+ ) -> AsyncIterator[api_pb2.ConnectResponse]:
950
+ return self._connect_iterator(req, extra_headers, timeout_seconds)
951
+
952
+ async def _connect_iterator(
953
+ self,
954
+ req: api_pb2.ConnectRequest,
955
+ extra_headers: HeaderInput | None = None,
956
+ timeout_seconds: float | None = None,
957
+ ) -> AsyncIterator[api_pb2.ConnectResponse]:
958
+ stream_output = await self.call_connect(req, extra_headers)
959
+ err = stream_output.error()
960
+ if err is not None:
961
+ raise err
962
+ async with stream_output as stream:
963
+ async for response in stream:
964
+ yield response
965
+ err = stream.error()
966
+ if err is not None:
967
+ raise err
968
+
969
+ async def call_connect(
970
+ self,
971
+ req: api_pb2.ConnectRequest,
972
+ extra_headers: HeaderInput | None = None,
973
+ timeout_seconds: float | None = None,
974
+ ) -> AsyncStreamOutput[api_pb2.ConnectResponse]:
975
+ """Low-level method to call Connect, granting access to errors and metadata"""
976
+ url = self.base_url + "/sandboxagent.Process/Connect"
977
+ return await self._connect_client.call_server_streaming(
978
+ url, req, api_pb2.ConnectResponse, extra_headers, timeout_seconds
979
+ )
980
+
981
+ def start(
982
+ self,
983
+ req: api_pb2.StartRequest,
984
+ extra_headers: HeaderInput | None = None,
985
+ timeout_seconds: float | None = None,
986
+ ) -> AsyncIterator[api_pb2.StartResponse]:
987
+ return self._start_iterator(req, extra_headers, timeout_seconds)
988
+
989
+ async def _start_iterator(
990
+ self,
991
+ req: api_pb2.StartRequest,
992
+ extra_headers: HeaderInput | None = None,
993
+ timeout_seconds: float | None = None,
994
+ ) -> AsyncIterator[api_pb2.StartResponse]:
995
+ stream_output = await self.call_start(req, extra_headers)
996
+ err = stream_output.error()
997
+ if err is not None:
998
+ raise err
999
+ async with stream_output as stream:
1000
+ async for response in stream:
1001
+ yield response
1002
+ err = stream.error()
1003
+ if err is not None:
1004
+ raise err
1005
+
1006
+ async def call_start(
1007
+ self,
1008
+ req: api_pb2.StartRequest,
1009
+ extra_headers: HeaderInput | None = None,
1010
+ timeout_seconds: float | None = None,
1011
+ ) -> AsyncStreamOutput[api_pb2.StartResponse]:
1012
+ """Low-level method to call Start, granting access to errors and metadata"""
1013
+ url = self.base_url + "/sandboxagent.Process/Start"
1014
+ return await self._connect_client.call_server_streaming(
1015
+ url, req, api_pb2.StartResponse, extra_headers, timeout_seconds
1016
+ )
1017
+
1018
+ async def call_update(
1019
+ self,
1020
+ req: api_pb2.UpdateRequest,
1021
+ extra_headers: HeaderInput | None = None,
1022
+ timeout_seconds: float | None = None,
1023
+ ) -> UnaryOutput[api_pb2.UpdateResponse]:
1024
+ """Low-level method to call Update, granting access to errors and metadata"""
1025
+ url = self.base_url + "/sandboxagent.Process/Update"
1026
+ return await self._connect_client.call_unary(
1027
+ url, req, api_pb2.UpdateResponse, extra_headers, timeout_seconds
1028
+ )
1029
+
1030
+ async def update(
1031
+ self,
1032
+ req: api_pb2.UpdateRequest,
1033
+ extra_headers: HeaderInput | None = None,
1034
+ timeout_seconds: float | None = None,
1035
+ ) -> api_pb2.UpdateResponse:
1036
+ response = await self.call_update(req, extra_headers, timeout_seconds)
1037
+ err = response.error()
1038
+ if err is not None:
1039
+ raise err
1040
+ msg = response.message()
1041
+ if msg is None:
1042
+ raise ConnectProtocolError("missing response message")
1043
+ return msg
1044
+
1045
+ async def call_stream_input(
1046
+ self,
1047
+ reqs: StreamInput[api_pb2.StreamInputRequest],
1048
+ extra_headers: HeaderInput | None = None,
1049
+ timeout_seconds: float | None = None,
1050
+ ) -> ClientStreamingOutput[api_pb2.StreamInputResponse]:
1051
+ """Low-level method to call StreamInput, granting access to errors and metadata"""
1052
+ url = self.base_url + "/sandboxagent.Process/StreamInput"
1053
+ return await self._connect_client.call_client_streaming(
1054
+ url, reqs, api_pb2.StreamInputResponse, extra_headers, timeout_seconds
1055
+ )
1056
+
1057
+ async def stream_input(
1058
+ self,
1059
+ reqs: StreamInput[api_pb2.StreamInputRequest],
1060
+ extra_headers: HeaderInput | None = None,
1061
+ timeout_seconds: float | None = None,
1062
+ ) -> api_pb2.StreamInputResponse:
1063
+ client_stream_output = await self.call_stream_input(reqs, extra_headers)
1064
+ err = client_stream_output.error()
1065
+ if err is not None:
1066
+ raise err
1067
+ msg = client_stream_output.message()
1068
+ if msg is None:
1069
+ raise RuntimeError("ClientStreamOutput has empty error and message")
1070
+ return msg
1071
+
1072
+ async def call_send_input(
1073
+ self,
1074
+ req: api_pb2.SendInputRequest,
1075
+ extra_headers: HeaderInput | None = None,
1076
+ timeout_seconds: float | None = None,
1077
+ ) -> UnaryOutput[api_pb2.SendInputResponse]:
1078
+ """Low-level method to call SendInput, granting access to errors and metadata"""
1079
+ url = self.base_url + "/sandboxagent.Process/SendInput"
1080
+ return await self._connect_client.call_unary(
1081
+ url, req, api_pb2.SendInputResponse, extra_headers, timeout_seconds
1082
+ )
1083
+
1084
+ async def send_input(
1085
+ self,
1086
+ req: api_pb2.SendInputRequest,
1087
+ extra_headers: HeaderInput | None = None,
1088
+ timeout_seconds: float | None = None,
1089
+ ) -> api_pb2.SendInputResponse:
1090
+ response = await self.call_send_input(req, extra_headers, timeout_seconds)
1091
+ err = response.error()
1092
+ if err is not None:
1093
+ raise err
1094
+ msg = response.message()
1095
+ if msg is None:
1096
+ raise ConnectProtocolError("missing response message")
1097
+ return msg
1098
+
1099
+ async def call_send_signal(
1100
+ self,
1101
+ req: api_pb2.SendSignalRequest,
1102
+ extra_headers: HeaderInput | None = None,
1103
+ timeout_seconds: float | None = None,
1104
+ ) -> UnaryOutput[api_pb2.SendSignalResponse]:
1105
+ """Low-level method to call SendSignal, granting access to errors and metadata"""
1106
+ url = self.base_url + "/sandboxagent.Process/SendSignal"
1107
+ return await self._connect_client.call_unary(
1108
+ url, req, api_pb2.SendSignalResponse, extra_headers, timeout_seconds
1109
+ )
1110
+
1111
+ async def send_signal(
1112
+ self,
1113
+ req: api_pb2.SendSignalRequest,
1114
+ extra_headers: HeaderInput | None = None,
1115
+ timeout_seconds: float | None = None,
1116
+ ) -> api_pb2.SendSignalResponse:
1117
+ response = await self.call_send_signal(req, extra_headers, timeout_seconds)
1118
+ err = response.error()
1119
+ if err is not None:
1120
+ raise err
1121
+ msg = response.message()
1122
+ if msg is None:
1123
+ raise ConnectProtocolError("missing response message")
1124
+ return msg
1125
+
1126
+
1127
+ @typing.runtime_checkable
1128
+ class ProcessProtocol(typing.Protocol):
1129
+ def list(
1130
+ self, req: ClientRequest[api_pb2.ListRequest]
1131
+ ) -> ServerResponse[api_pb2.ListResponse]: ...
1132
+ def connect(
1133
+ self, req: ClientRequest[api_pb2.ConnectRequest]
1134
+ ) -> ServerStream[api_pb2.ConnectResponse]: ...
1135
+ def start(
1136
+ self, req: ClientRequest[api_pb2.StartRequest]
1137
+ ) -> ServerStream[api_pb2.StartResponse]: ...
1138
+ def update(
1139
+ self, req: ClientRequest[api_pb2.UpdateRequest]
1140
+ ) -> ServerResponse[api_pb2.UpdateResponse]: ...
1141
+ def stream_input(
1142
+ self, req: ClientStream[api_pb2.StreamInputRequest]
1143
+ ) -> ServerResponse[api_pb2.StreamInputResponse]: ...
1144
+ def send_input(
1145
+ self, req: ClientRequest[api_pb2.SendInputRequest]
1146
+ ) -> ServerResponse[api_pb2.SendInputResponse]: ...
1147
+ def send_signal(
1148
+ self, req: ClientRequest[api_pb2.SendSignalRequest]
1149
+ ) -> ServerResponse[api_pb2.SendSignalResponse]: ...
1150
+
1151
+
1152
+ PROCESS_PATH_PREFIX = "/sandboxagent.Process"
1153
+
1154
+
1155
+ def wsgi_process(implementation: ProcessProtocol) -> WSGIApplication:
1156
+ app = ConnectWSGI()
1157
+ app.register_unary_rpc(
1158
+ "/sandboxagent.Process/List", implementation.list, api_pb2.ListRequest
1159
+ )
1160
+ app.register_server_streaming_rpc(
1161
+ "/sandboxagent.Process/Connect", implementation.connect, api_pb2.ConnectRequest
1162
+ )
1163
+ app.register_server_streaming_rpc(
1164
+ "/sandboxagent.Process/Start", implementation.start, api_pb2.StartRequest
1165
+ )
1166
+ app.register_unary_rpc(
1167
+ "/sandboxagent.Process/Update", implementation.update, api_pb2.UpdateRequest
1168
+ )
1169
+ app.register_client_streaming_rpc(
1170
+ "/sandboxagent.Process/StreamInput",
1171
+ implementation.stream_input,
1172
+ api_pb2.StreamInputRequest,
1173
+ )
1174
+ app.register_unary_rpc(
1175
+ "/sandboxagent.Process/SendInput",
1176
+ implementation.send_input,
1177
+ api_pb2.SendInputRequest,
1178
+ )
1179
+ app.register_unary_rpc(
1180
+ "/sandboxagent.Process/SendSignal",
1181
+ implementation.send_signal,
1182
+ api_pb2.SendSignalRequest,
1183
+ )
1184
+ return app
1185
+
1186
+
1187
+ class ExecutionServiceClient:
1188
+ def __init__(
1189
+ self,
1190
+ base_url: str,
1191
+ http_client: urllib3.PoolManager | None = None,
1192
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
1193
+ ):
1194
+ self.base_url = base_url
1195
+ self._connect_client = ConnectClient(http_client, protocol)
1196
+
1197
+ def execute(
1198
+ self,
1199
+ req: api_pb2.ExecuteRequest,
1200
+ extra_headers: HeaderInput | None = None,
1201
+ timeout_seconds: float | None = None,
1202
+ ) -> Iterator[api_pb2.ExecuteResponse]:
1203
+ return self._execute_iterator(req, extra_headers, timeout_seconds)
1204
+
1205
+ def _execute_iterator(
1206
+ self,
1207
+ req: api_pb2.ExecuteRequest,
1208
+ extra_headers: HeaderInput | None = None,
1209
+ timeout_seconds: float | None = None,
1210
+ ) -> Iterator[api_pb2.ExecuteResponse]:
1211
+ stream_output = self.call_execute(req, extra_headers)
1212
+ err = stream_output.error()
1213
+ if err is not None:
1214
+ raise err
1215
+ yield from stream_output
1216
+ err = stream_output.error()
1217
+ if err is not None:
1218
+ raise err
1219
+
1220
+ def call_execute(
1221
+ self,
1222
+ req: api_pb2.ExecuteRequest,
1223
+ extra_headers: HeaderInput | None = None,
1224
+ timeout_seconds: float | None = None,
1225
+ ) -> StreamOutput[api_pb2.ExecuteResponse]:
1226
+ """Low-level method to call Execute, granting access to errors and metadata"""
1227
+ url = self.base_url + "/sandboxagent.ExecutionService/Execute"
1228
+ return self._connect_client.call_server_streaming(
1229
+ url, req, api_pb2.ExecuteResponse, extra_headers, timeout_seconds
1230
+ )
1231
+
1232
+
1233
+ class AsyncExecutionServiceClient:
1234
+ def __init__(
1235
+ self,
1236
+ base_url: str,
1237
+ http_client: aiohttp.ClientSession,
1238
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
1239
+ ):
1240
+ self.base_url = base_url
1241
+ self._connect_client = AsyncConnectClient(http_client, protocol)
1242
+
1243
+ def execute(
1244
+ self,
1245
+ req: api_pb2.ExecuteRequest,
1246
+ extra_headers: HeaderInput | None = None,
1247
+ timeout_seconds: float | None = None,
1248
+ ) -> AsyncIterator[api_pb2.ExecuteResponse]:
1249
+ return self._execute_iterator(req, extra_headers, timeout_seconds)
1250
+
1251
+ async def _execute_iterator(
1252
+ self,
1253
+ req: api_pb2.ExecuteRequest,
1254
+ extra_headers: HeaderInput | None = None,
1255
+ timeout_seconds: float | None = None,
1256
+ ) -> AsyncIterator[api_pb2.ExecuteResponse]:
1257
+ stream_output = await self.call_execute(req, extra_headers)
1258
+ err = stream_output.error()
1259
+ if err is not None:
1260
+ raise err
1261
+ async with stream_output as stream:
1262
+ async for response in stream:
1263
+ yield response
1264
+ err = stream.error()
1265
+ if err is not None:
1266
+ raise err
1267
+
1268
+ async def call_execute(
1269
+ self,
1270
+ req: api_pb2.ExecuteRequest,
1271
+ extra_headers: HeaderInput | None = None,
1272
+ timeout_seconds: float | None = None,
1273
+ ) -> AsyncStreamOutput[api_pb2.ExecuteResponse]:
1274
+ """Low-level method to call Execute, granting access to errors and metadata"""
1275
+ url = self.base_url + "/sandboxagent.ExecutionService/Execute"
1276
+ return await self._connect_client.call_server_streaming(
1277
+ url, req, api_pb2.ExecuteResponse, extra_headers, timeout_seconds
1278
+ )
1279
+
1280
+
1281
+ @typing.runtime_checkable
1282
+ class ExecutionServiceProtocol(typing.Protocol):
1283
+ def execute(
1284
+ self, req: ClientRequest[api_pb2.ExecuteRequest]
1285
+ ) -> ServerStream[api_pb2.ExecuteResponse]: ...
1286
+
1287
+
1288
+ EXECUTION_SERVICE_PATH_PREFIX = "/sandboxagent.ExecutionService"
1289
+
1290
+
1291
+ def wsgi_execution_service(implementation: ExecutionServiceProtocol) -> WSGIApplication:
1292
+ app = ConnectWSGI()
1293
+ app.register_server_streaming_rpc(
1294
+ "/sandboxagent.ExecutionService/Execute",
1295
+ implementation.execute,
1296
+ api_pb2.ExecuteRequest,
1297
+ )
1298
+ return app
1299
+
1300
+
1301
+ class ContextServiceClient:
1302
+ def __init__(
1303
+ self,
1304
+ base_url: str,
1305
+ http_client: urllib3.PoolManager | None = None,
1306
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
1307
+ ):
1308
+ self.base_url = base_url
1309
+ self._connect_client = ConnectClient(http_client, protocol)
1310
+
1311
+ def call_create_context(
1312
+ self,
1313
+ req: api_pb2.CreateContextRequest,
1314
+ extra_headers: HeaderInput | None = None,
1315
+ timeout_seconds: float | None = None,
1316
+ ) -> UnaryOutput[api_pb2.Context]:
1317
+ """Low-level method to call CreateContext, granting access to errors and metadata"""
1318
+ url = self.base_url + "/sandboxagent.ContextService/CreateContext"
1319
+ return self._connect_client.call_unary(
1320
+ url, req, api_pb2.Context, extra_headers, timeout_seconds
1321
+ )
1322
+
1323
+ def create_context(
1324
+ self,
1325
+ req: api_pb2.CreateContextRequest,
1326
+ extra_headers: HeaderInput | None = None,
1327
+ timeout_seconds: float | None = None,
1328
+ ) -> api_pb2.Context:
1329
+ response = self.call_create_context(req, extra_headers, timeout_seconds)
1330
+ err = response.error()
1331
+ if err is not None:
1332
+ raise err
1333
+ msg = response.message()
1334
+ if msg is None:
1335
+ raise ConnectProtocolError("missing response message")
1336
+ return msg
1337
+
1338
+ def call_destroy_context(
1339
+ self,
1340
+ req: api_pb2.DestroyContextRequest,
1341
+ extra_headers: HeaderInput | None = None,
1342
+ timeout_seconds: float | None = None,
1343
+ ) -> UnaryOutput[api_pb2.DestroyContextResponse]:
1344
+ """Low-level method to call DestroyContext, granting access to errors and metadata"""
1345
+ url = self.base_url + "/sandboxagent.ContextService/DestroyContext"
1346
+ return self._connect_client.call_unary(
1347
+ url, req, api_pb2.DestroyContextResponse, extra_headers, timeout_seconds
1348
+ )
1349
+
1350
+ def destroy_context(
1351
+ self,
1352
+ req: api_pb2.DestroyContextRequest,
1353
+ extra_headers: HeaderInput | None = None,
1354
+ timeout_seconds: float | None = None,
1355
+ ) -> api_pb2.DestroyContextResponse:
1356
+ response = self.call_destroy_context(req, extra_headers, timeout_seconds)
1357
+ err = response.error()
1358
+ if err is not None:
1359
+ raise err
1360
+ msg = response.message()
1361
+ if msg is None:
1362
+ raise ConnectProtocolError("missing response message")
1363
+ return msg
1364
+
1365
+
1366
+ class AsyncContextServiceClient:
1367
+ def __init__(
1368
+ self,
1369
+ base_url: str,
1370
+ http_client: aiohttp.ClientSession,
1371
+ protocol: ConnectProtocol = ConnectProtocol.CONNECT_PROTOBUF,
1372
+ ):
1373
+ self.base_url = base_url
1374
+ self._connect_client = AsyncConnectClient(http_client, protocol)
1375
+
1376
+ async def call_create_context(
1377
+ self,
1378
+ req: api_pb2.CreateContextRequest,
1379
+ extra_headers: HeaderInput | None = None,
1380
+ timeout_seconds: float | None = None,
1381
+ ) -> UnaryOutput[api_pb2.Context]:
1382
+ """Low-level method to call CreateContext, granting access to errors and metadata"""
1383
+ url = self.base_url + "/sandboxagent.ContextService/CreateContext"
1384
+ return await self._connect_client.call_unary(
1385
+ url, req, api_pb2.Context, extra_headers, timeout_seconds
1386
+ )
1387
+
1388
+ async def create_context(
1389
+ self,
1390
+ req: api_pb2.CreateContextRequest,
1391
+ extra_headers: HeaderInput | None = None,
1392
+ timeout_seconds: float | None = None,
1393
+ ) -> api_pb2.Context:
1394
+ response = await self.call_create_context(req, extra_headers, timeout_seconds)
1395
+ err = response.error()
1396
+ if err is not None:
1397
+ raise err
1398
+ msg = response.message()
1399
+ if msg is None:
1400
+ raise ConnectProtocolError("missing response message")
1401
+ return msg
1402
+
1403
+ async def call_destroy_context(
1404
+ self,
1405
+ req: api_pb2.DestroyContextRequest,
1406
+ extra_headers: HeaderInput | None = None,
1407
+ timeout_seconds: float | None = None,
1408
+ ) -> UnaryOutput[api_pb2.DestroyContextResponse]:
1409
+ """Low-level method to call DestroyContext, granting access to errors and metadata"""
1410
+ url = self.base_url + "/sandboxagent.ContextService/DestroyContext"
1411
+ return await self._connect_client.call_unary(
1412
+ url, req, api_pb2.DestroyContextResponse, extra_headers, timeout_seconds
1413
+ )
1414
+
1415
+ async def destroy_context(
1416
+ self,
1417
+ req: api_pb2.DestroyContextRequest,
1418
+ extra_headers: HeaderInput | None = None,
1419
+ timeout_seconds: float | None = None,
1420
+ ) -> api_pb2.DestroyContextResponse:
1421
+ response = await self.call_destroy_context(req, extra_headers, timeout_seconds)
1422
+ err = response.error()
1423
+ if err is not None:
1424
+ raise err
1425
+ msg = response.message()
1426
+ if msg is None:
1427
+ raise ConnectProtocolError("missing response message")
1428
+ return msg
1429
+
1430
+
1431
+ @typing.runtime_checkable
1432
+ class ContextServiceProtocol(typing.Protocol):
1433
+ def create_context(
1434
+ self, req: ClientRequest[api_pb2.CreateContextRequest]
1435
+ ) -> ServerResponse[api_pb2.Context]: ...
1436
+ def destroy_context(
1437
+ self, req: ClientRequest[api_pb2.DestroyContextRequest]
1438
+ ) -> ServerResponse[api_pb2.DestroyContextResponse]: ...
1439
+
1440
+
1441
+ CONTEXT_SERVICE_PATH_PREFIX = "/sandboxagent.ContextService"
1442
+
1443
+
1444
+ def wsgi_context_service(implementation: ContextServiceProtocol) -> WSGIApplication:
1445
+ app = ConnectWSGI()
1446
+ app.register_unary_rpc(
1447
+ "/sandboxagent.ContextService/CreateContext",
1448
+ implementation.create_context,
1449
+ api_pb2.CreateContextRequest,
1450
+ )
1451
+ app.register_unary_rpc(
1452
+ "/sandboxagent.ContextService/DestroyContext",
1453
+ implementation.destroy_context,
1454
+ api_pb2.DestroyContextRequest,
1455
+ )
1456
+ return app