scalebox-sdk 0.1.25__py3-none-any.whl → 1.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scalebox/__init__.py +2 -2
- scalebox/api/__init__.py +3 -1
- scalebox/api/client/api/sandboxes/get_sandboxes.py +1 -1
- scalebox/api/client/api/sandboxes/post_sandboxes_sandbox_id_connect.py +193 -0
- scalebox/api/client/models/connect_sandbox.py +59 -0
- scalebox/api/client/models/error.py +2 -2
- scalebox/api/client/models/listed_sandbox.py +24 -3
- scalebox/api/client/models/new_sandbox.py +10 -0
- scalebox/api/client/models/sandbox.py +13 -0
- scalebox/api/client/models/sandbox_detail.py +24 -0
- scalebox/cli.py +125 -125
- scalebox/client/aclient.py +57 -57
- scalebox/client/client.py +102 -102
- scalebox/code_interpreter/__init__.py +12 -12
- scalebox/code_interpreter/charts.py +230 -230
- scalebox/code_interpreter/code_interpreter_async.py +3 -1
- scalebox/code_interpreter/code_interpreter_sync.py +3 -1
- scalebox/code_interpreter/constants.py +3 -3
- scalebox/code_interpreter/exceptions.py +13 -13
- scalebox/code_interpreter/models.py +485 -485
- scalebox/connection_config.py +36 -1
- scalebox/csx_connect/__init__.py +1 -1
- scalebox/csx_connect/client.py +485 -485
- scalebox/csx_desktop/main.py +651 -651
- scalebox/exceptions.py +83 -83
- scalebox/generated/api.py +61 -61
- scalebox/generated/api_pb2.py +203 -203
- scalebox/generated/api_pb2.pyi +956 -956
- scalebox/generated/api_pb2_connect.py +1407 -1407
- scalebox/generated/rpc.py +50 -50
- scalebox/sandbox/main.py +146 -139
- scalebox/sandbox/sandbox_api.py +105 -91
- scalebox/sandbox/signature.py +40 -40
- scalebox/sandbox/utils.py +34 -34
- scalebox/sandbox_async/main.py +226 -44
- scalebox/sandbox_async/sandbox_api.py +124 -3
- scalebox/sandbox_sync/main.py +205 -130
- scalebox/sandbox_sync/sandbox_api.py +119 -3
- scalebox/test/CODE_INTERPRETER_TESTS_READY.md +323 -323
- scalebox/test/README.md +329 -329
- scalebox/test/bedrock_openai_adapter.py +73 -0
- scalebox/test/code_interpreter_test.py +34 -34
- scalebox/test/code_interpreter_test_sync.py +34 -34
- scalebox/test/run_stress_code_interpreter_sync.py +178 -0
- scalebox/test/simple_upload_example.py +131 -0
- scalebox/test/stabitiy_test.py +323 -0
- scalebox/test/test_browser_use.py +27 -0
- scalebox/test/test_browser_use_scalebox.py +62 -0
- scalebox/test/test_code_interpreter_execcode.py +289 -211
- scalebox/test/test_code_interpreter_sync_comprehensive.py +116 -69
- scalebox/test/test_connect_pause_async.py +300 -0
- scalebox/test/test_connect_pause_sync.py +300 -0
- scalebox/test/test_csx_desktop_examples.py +3 -3
- scalebox/test/test_desktop_sandbox_sf.py +112 -0
- scalebox/test/test_download_url.py +41 -0
- scalebox/test/test_existing_sandbox.py +1037 -0
- scalebox/test/test_sandbox_async_comprehensive.py +5 -3
- scalebox/test/test_sandbox_object_storage_example.py +151 -0
- scalebox/test/test_sandbox_object_storage_example_async.py +159 -0
- scalebox/test/test_sandbox_sync_comprehensive.py +1 -1
- scalebox/test/test_sf.py +141 -0
- scalebox/test/test_watch_dir_async.py +58 -0
- scalebox/test/testacreate.py +1 -1
- scalebox/test/testagetinfo.py +1 -3
- scalebox/test/testcomputeuse.py +243 -243
- scalebox/test/testsandbox_api.py +5 -5
- scalebox/test/testsandbox_async.py +17 -47
- scalebox/test/testsandbox_sync.py +19 -15
- scalebox/test/upload_100mb_example.py +377 -0
- scalebox/utils/httpcoreclient.py +297 -297
- scalebox/utils/httpxclient.py +403 -403
- scalebox/version.py +2 -2
- {scalebox_sdk-0.1.25.dist-info → scalebox_sdk-1.0.2.dist-info}/METADATA +1 -1
- {scalebox_sdk-0.1.25.dist-info → scalebox_sdk-1.0.2.dist-info}/RECORD +78 -60
- {scalebox_sdk-0.1.25.dist-info → scalebox_sdk-1.0.2.dist-info}/WHEEL +1 -1
- {scalebox_sdk-0.1.25.dist-info → scalebox_sdk-1.0.2.dist-info}/entry_points.txt +0 -0
- {scalebox_sdk-0.1.25.dist-info → scalebox_sdk-1.0.2.dist-info}/licenses/LICENSE +0 -0
- {scalebox_sdk-0.1.25.dist-info → scalebox_sdk-1.0.2.dist-info}/top_level.txt +0 -0
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
import urllib.parse
|
|
3
|
-
from typing import Dict, List, Optional
|
|
3
|
+
from typing import Dict, List, Optional, Unpack, TYPE_CHECKING
|
|
4
4
|
|
|
5
5
|
from packaging.version import Version
|
|
6
6
|
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from . import AsyncSandbox
|
|
9
|
+
|
|
10
|
+
from ..api.client.api.sandboxes import post_sandboxes_sandbox_id_pause, post_sandboxes_sandbox_id_connect
|
|
11
|
+
from ..api.client.models.connect_sandbox import ConnectSandbox
|
|
7
12
|
from ..api import AsyncApiClient, SandboxCreateResponse, handle_api_exception
|
|
8
13
|
from ..api.client.api.sandboxes import (
|
|
9
14
|
delete_sandboxes_sandbox_id,
|
|
@@ -14,8 +19,8 @@ from ..api.client.api.sandboxes import (
|
|
|
14
19
|
post_sandboxes_sandbox_id_timeout,
|
|
15
20
|
)
|
|
16
21
|
from ..api.client.models import Error, NewSandbox, PostSandboxesSandboxIDTimeoutBody
|
|
17
|
-
from ..connection_config import ConnectionConfig, ProxyTypes
|
|
18
|
-
from ..exceptions import SandboxException, TemplateException
|
|
22
|
+
from ..connection_config import ConnectionConfig, ProxyTypes, ApiParams
|
|
23
|
+
from ..exceptions import SandboxException, TemplateException, NotFoundException
|
|
19
24
|
from ..sandbox.sandbox_api import (
|
|
20
25
|
ListedSandbox,
|
|
21
26
|
SandboxApiBase,
|
|
@@ -97,6 +102,9 @@ class SandboxApi(SandboxApiBase):
|
|
|
97
102
|
memory_mb=sandbox.memory_mb,
|
|
98
103
|
started_at=sandbox.started_at,
|
|
99
104
|
end_at=sandbox.end_at,
|
|
105
|
+
object_storage=sandbox.object_storage,
|
|
106
|
+
uptime=sandbox.uptime,
|
|
107
|
+
timeout=sandbox.timeout,
|
|
100
108
|
)
|
|
101
109
|
for sandbox in res.parsed
|
|
102
110
|
]
|
|
@@ -160,6 +168,9 @@ class SandboxApi(SandboxApiBase):
|
|
|
160
168
|
end_at=res.parsed.end_at,
|
|
161
169
|
envd_version=res.parsed.envd_version,
|
|
162
170
|
_envd_access_token=res.parsed.envd_access_token,
|
|
171
|
+
object_storage=res.parsed.object_storage,
|
|
172
|
+
uptime=res.parsed.uptime,
|
|
173
|
+
timeout=res.parsed.timeout,
|
|
163
174
|
)
|
|
164
175
|
|
|
165
176
|
@classmethod
|
|
@@ -256,6 +267,8 @@ class SandboxApi(SandboxApiBase):
|
|
|
256
267
|
headers: Optional[Dict[str, str]] = None,
|
|
257
268
|
proxy: Optional[ProxyTypes] = None,
|
|
258
269
|
allow_internet_access: Optional[bool] = True,
|
|
270
|
+
object_storage: Optional[Dict[str, str]] = None,
|
|
271
|
+
net_proxy_country:Optional[str] = None,
|
|
259
272
|
) -> SandboxCreateResponse:
|
|
260
273
|
config = ConnectionConfig(
|
|
261
274
|
api_key=api_key,
|
|
@@ -279,6 +292,8 @@ class SandboxApi(SandboxApiBase):
|
|
|
279
292
|
secure=secure or False,
|
|
280
293
|
allow_internet_access=allow_internet_access,
|
|
281
294
|
is_async=False,
|
|
295
|
+
object_storage=object_storage,
|
|
296
|
+
net_proxy_country=net_proxy_country,
|
|
282
297
|
),
|
|
283
298
|
client=api_client,
|
|
284
299
|
)
|
|
@@ -301,6 +316,8 @@ class SandboxApi(SandboxApiBase):
|
|
|
301
316
|
sandbox_domain=res.parsed.domain,
|
|
302
317
|
envd_version=res.parsed.envd_version,
|
|
303
318
|
envd_access_token=res.parsed.envd_access_token,
|
|
319
|
+
object_storage=res.parsed.object_storage,
|
|
320
|
+
network_proxy=res.parsed.network_proxy,
|
|
304
321
|
)
|
|
305
322
|
|
|
306
323
|
@classmethod
|
|
@@ -363,3 +380,107 @@ class SandboxApi(SandboxApiBase):
|
|
|
363
380
|
)
|
|
364
381
|
for metric in res.parsed
|
|
365
382
|
]
|
|
383
|
+
|
|
384
|
+
@classmethod
|
|
385
|
+
async def _cls_pause(
|
|
386
|
+
cls,
|
|
387
|
+
sandbox_id: str,
|
|
388
|
+
**opts: Unpack[ApiParams],
|
|
389
|
+
) -> str:
|
|
390
|
+
config = ConnectionConfig(**opts)
|
|
391
|
+
|
|
392
|
+
async with AsyncApiClient(
|
|
393
|
+
config,
|
|
394
|
+
limits=SandboxApiBase._limits,
|
|
395
|
+
) as api_client:
|
|
396
|
+
res = await post_sandboxes_sandbox_id_pause.asyncio_detailed(
|
|
397
|
+
sandbox_id,
|
|
398
|
+
client=api_client,
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
if res.status_code == 404:
|
|
402
|
+
raise NotFoundException(f"Sandbox {sandbox_id} not found")
|
|
403
|
+
|
|
404
|
+
if res.status_code == 409:
|
|
405
|
+
return sandbox_id
|
|
406
|
+
|
|
407
|
+
if res.status_code >= 300:
|
|
408
|
+
raise handle_api_exception(res)
|
|
409
|
+
|
|
410
|
+
# Check if res.parse is Error
|
|
411
|
+
if isinstance(res.parsed, Error):
|
|
412
|
+
raise SandboxException(f"{res.parsed.message}: Request failed")
|
|
413
|
+
|
|
414
|
+
return sandbox_id
|
|
415
|
+
|
|
416
|
+
@classmethod
|
|
417
|
+
async def _cls_connect(
|
|
418
|
+
cls,
|
|
419
|
+
sandbox_id: str,
|
|
420
|
+
timeout: Optional[int] = None,
|
|
421
|
+
**opts: Unpack[ApiParams],
|
|
422
|
+
) -> "AsyncSandbox":
|
|
423
|
+
timeout = timeout or SandboxApiBase.default_sandbox_timeout
|
|
424
|
+
|
|
425
|
+
# Sandbox is not running, resume it
|
|
426
|
+
config = ConnectionConfig(**opts)
|
|
427
|
+
|
|
428
|
+
async with AsyncApiClient(
|
|
429
|
+
config,
|
|
430
|
+
limits=SandboxApiBase._limits,
|
|
431
|
+
) as api_client:
|
|
432
|
+
res = await post_sandboxes_sandbox_id_connect.asyncio_detailed(
|
|
433
|
+
sandbox_id,
|
|
434
|
+
client=api_client,
|
|
435
|
+
body=ConnectSandbox(timeout=timeout),
|
|
436
|
+
)
|
|
437
|
+
|
|
438
|
+
if res.status_code == 404:
|
|
439
|
+
raise NotFoundException(f"Paused sandbox {sandbox_id} not found")
|
|
440
|
+
|
|
441
|
+
if res.status_code >= 300:
|
|
442
|
+
raise handle_api_exception(res)
|
|
443
|
+
|
|
444
|
+
# Check if res.parse is Error
|
|
445
|
+
if isinstance(res.parsed, Error):
|
|
446
|
+
raise SandboxException(f"{res.parsed.message}: Request failed")
|
|
447
|
+
|
|
448
|
+
# Extract information from API response and create a full AsyncSandbox instance
|
|
449
|
+
# Use delayed import to avoid circular dependency
|
|
450
|
+
from . import AsyncSandbox
|
|
451
|
+
|
|
452
|
+
response = res.parsed
|
|
453
|
+
if response is None:
|
|
454
|
+
raise SandboxException("Connect response is None")
|
|
455
|
+
|
|
456
|
+
connection_headers = {"Authorization": "Bearer root"}
|
|
457
|
+
|
|
458
|
+
# Extract fields from API response
|
|
459
|
+
sandbox_domain = response.domain if hasattr(response, 'domain') and response.domain is not None else None
|
|
460
|
+
envd_version = response.envd_version if hasattr(response, 'envd_version') else None
|
|
461
|
+
envd_access_token = None
|
|
462
|
+
if hasattr(response, 'envd_access_token'):
|
|
463
|
+
from ..api.client.types import Unset
|
|
464
|
+
if response.envd_access_token is not None and not isinstance(response.envd_access_token, Unset):
|
|
465
|
+
envd_access_token = response.envd_access_token
|
|
466
|
+
connection_headers["X-Access-Token"] = envd_access_token
|
|
467
|
+
|
|
468
|
+
connection_config = ConnectionConfig(
|
|
469
|
+
api_key=config.api_key,
|
|
470
|
+
domain=config.domain,
|
|
471
|
+
debug=config.debug,
|
|
472
|
+
request_timeout=config.request_timeout,
|
|
473
|
+
headers=connection_headers,
|
|
474
|
+
proxy=config.proxy,
|
|
475
|
+
)
|
|
476
|
+
|
|
477
|
+
# Create and return a full AsyncSandbox instance
|
|
478
|
+
sandbox = AsyncSandbox(
|
|
479
|
+
sandbox_id=sandbox_id,
|
|
480
|
+
sandbox_domain=sandbox_domain,
|
|
481
|
+
envd_version=envd_version,
|
|
482
|
+
envd_access_token=envd_access_token,
|
|
483
|
+
connection_config=connection_config,
|
|
484
|
+
)
|
|
485
|
+
|
|
486
|
+
return sandbox
|
scalebox/sandbox_sync/main.py
CHANGED
|
@@ -8,10 +8,11 @@ import httpx
|
|
|
8
8
|
import urllib3
|
|
9
9
|
from httpx import Timeout
|
|
10
10
|
from packaging.version import Version
|
|
11
|
+
from typing_extensions import Self, Unpack
|
|
11
12
|
from urllib3 import Retry
|
|
12
13
|
|
|
13
14
|
from ..api.client.types import Unset
|
|
14
|
-
from ..connection_config import ConnectionConfig, ProxyTypes
|
|
15
|
+
from ..connection_config import ConnectionConfig, ProxyTypes,ApiParams
|
|
15
16
|
from ..exceptions import SandboxException, request_timeout_error
|
|
16
17
|
from ..generated.api import ENVD_API_HEALTH_ROUTE, handle_envd_api_exception
|
|
17
18
|
from ..sandbox.main import SandboxSetup
|
|
@@ -101,6 +102,17 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
101
102
|
"""
|
|
102
103
|
return self._sandbox_domain
|
|
103
104
|
|
|
105
|
+
@property
|
|
106
|
+
def object_storage(self) -> Optional[Dict[str, str]]:
|
|
107
|
+
"""
|
|
108
|
+
Object storage configuration returned during sandbox creation (if any).
|
|
109
|
+
Only synchronous sandboxes currently expose this field.
|
|
110
|
+
"""
|
|
111
|
+
return self._object_storage
|
|
112
|
+
|
|
113
|
+
def network_proxy(self) -> Optional[Dict[str, any]]:
|
|
114
|
+
return self._network_proxy
|
|
115
|
+
|
|
104
116
|
@property
|
|
105
117
|
def envd_api_url(self) -> str:
|
|
106
118
|
return self._envd_api_url
|
|
@@ -153,104 +165,19 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
153
165
|
"""
|
|
154
166
|
super().__init__()
|
|
155
167
|
self._connection_config = opts["connection_config"]
|
|
156
|
-
|
|
168
|
+
self._object_storage = opts["object_storage"]
|
|
157
169
|
self._sandbox_id = opts["sandbox_id"]
|
|
170
|
+
self._network_proxy = opts["network_proxy"]
|
|
158
171
|
self._sandbox_domain = opts["sandbox_domain"] or self.connection_config.domain
|
|
159
172
|
debug = self._connection_config.debug
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
# if debug:
|
|
163
|
-
# self._sandbox_id = "debug_sandbox_id"
|
|
164
|
-
# self._sandbox_domain = None
|
|
165
|
-
# self._envd_version = None
|
|
166
|
-
# self._envd_access_token = None
|
|
167
|
-
# elif sandbox_id is not None:
|
|
168
|
-
# response = SandboxApi._cls_get_info(
|
|
169
|
-
# sandbox_id,
|
|
170
|
-
# api_key=api_key,
|
|
171
|
-
# domain=domain,
|
|
172
|
-
# debug=debug,
|
|
173
|
-
# request_timeout=request_timeout,
|
|
174
|
-
# proxy=proxy,
|
|
175
|
-
# )
|
|
176
|
-
#
|
|
177
|
-
# self._sandbox_id = sandbox_id
|
|
178
|
-
# self._sandbox_domain = response.sandbox_domain
|
|
179
|
-
# self._envd_version = response.envd_version
|
|
180
|
-
# self._envd_access_token = response._envd_access_token
|
|
181
|
-
#
|
|
182
|
-
# if response._envd_access_token is not None and not isinstance(
|
|
183
|
-
# response._envd_access_token, Unset
|
|
184
|
-
# ):
|
|
185
|
-
# connection_headers["X-Access-Token"] = response._envd_access_token
|
|
186
|
-
# else:
|
|
187
|
-
# template = template or self.default_template
|
|
188
|
-
# timeout = timeout or self.default_sandbox_timeout
|
|
189
|
-
# response = SandboxApi._create_sandbox(
|
|
190
|
-
# template=template,
|
|
191
|
-
# api_key=api_key,
|
|
192
|
-
# timeout=timeout,
|
|
193
|
-
# metadata=metadata,
|
|
194
|
-
# env_vars=envs,
|
|
195
|
-
# domain=domain,
|
|
196
|
-
# debug=debug,
|
|
197
|
-
# request_timeout=request_timeout,
|
|
198
|
-
# secure=secure or False,
|
|
199
|
-
# proxy=proxy,
|
|
200
|
-
# allow_internet_access=allow_internet_access,
|
|
201
|
-
# )
|
|
202
|
-
#
|
|
203
|
-
# self._sandbox_id = response.sandbox_id
|
|
204
|
-
# self._sandbox_domain = response.sandbox_domain
|
|
205
|
-
# self._envd_version = response.envd_version
|
|
206
|
-
#
|
|
207
|
-
# if response.envd_access_token is not None and not isinstance(
|
|
208
|
-
# response.envd_access_token, Unset
|
|
209
|
-
# ):
|
|
210
|
-
# self._envd_access_token = response.envd_access_token
|
|
211
|
-
# connection_headers["X-Access-Token"] = response.envd_access_token
|
|
212
|
-
# else:
|
|
213
|
-
# self._envd_access_token = None
|
|
214
|
-
# self._transport = TransportWithLogger(limits=self._limits, proxy=proxy)
|
|
215
|
-
# self._connection_config = ConnectionConfig(
|
|
216
|
-
# api_key=api_key,
|
|
217
|
-
# domain=domain,
|
|
218
|
-
# debug=debug,
|
|
219
|
-
# request_timeout=request_timeout,
|
|
220
|
-
# headers=connection_headers,
|
|
221
|
-
# proxy=proxy,
|
|
222
|
-
# )
|
|
173
|
+
self.__envd_access_token=opts["envd_access_token"]
|
|
223
174
|
|
|
224
175
|
self._sandbox_domain = self._sandbox_domain or self._connection_config.domain
|
|
225
|
-
# self._envd_api_url = f"{'http' if self.connection_config.debug else 'https'}://{self.get_host(self.envd_port)}"
|
|
226
176
|
if debug:
|
|
227
177
|
self._envd_api_url = f"http://{self.get_host(8888)}"
|
|
228
|
-
# elif self._sandbox_id is not None:
|
|
229
|
-
# response = SandboxApi._cls_get_info(
|
|
230
|
-
# self._sandbox_id,
|
|
231
|
-
# api_key=self._api_key(),
|
|
232
|
-
# domain=self._sandbox_domain,
|
|
233
|
-
# debug=debug,
|
|
234
|
-
# request_timeout=self.request_timeout,
|
|
235
|
-
# proxy=self.proxy,
|
|
236
|
-
# )
|
|
237
|
-
#
|
|
238
|
-
# self._sandbox_id = self._sandbox_id
|
|
239
|
-
# self._sandbox_domain = response.sandbox_domain
|
|
240
|
-
# self._envd_version = response.envd_version
|
|
241
|
-
# self._envd_access_token = response._envd_access_token
|
|
242
|
-
#
|
|
243
|
-
# if response._envd_access_token is not None and not isinstance(
|
|
244
|
-
# response._envd_access_token, Unset
|
|
245
|
-
# ):
|
|
246
|
-
# self._connection_config["X-Access-Token"] = response._envd_access_token
|
|
247
|
-
# self._envd_api_url = f"http://{self.get_host(self.envd_port)}"
|
|
248
178
|
else:
|
|
249
179
|
self._envd_api_url = f"https://{self.get_host(self.envd_port)}"
|
|
250
180
|
self._transport = TransportWithLogger(limits=self._limits, proxy=self._connection_config.proxy)
|
|
251
|
-
# self._envd_api_url = f"http://localhost:8088"
|
|
252
|
-
# self._envd_api_url = f"http://{self.get_host(self.envd_port)}"
|
|
253
|
-
# self._envd_api_url = f"http://localhost:31000"
|
|
254
181
|
self._envd_api = httpx.Client(
|
|
255
182
|
base_url=self._envd_api_url,
|
|
256
183
|
transport=self._transport,
|
|
@@ -317,6 +244,7 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
317
244
|
timeout: Optional[int] = None,
|
|
318
245
|
metadata: Optional[Dict[str, str]] = None,
|
|
319
246
|
envs: Optional[Dict[str, str]] = None,
|
|
247
|
+
object_storage:Optional[Dict[str, str]] = None,
|
|
320
248
|
api_key: Optional[str] = None,
|
|
321
249
|
domain: Optional[str] = None,
|
|
322
250
|
debug: Optional[bool] = None,
|
|
@@ -325,6 +253,7 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
325
253
|
proxy: Optional[ProxyTypes] = None,
|
|
326
254
|
secure: Optional[bool] = None,
|
|
327
255
|
allow_internet_access: Optional[bool] = True,
|
|
256
|
+
net_proxy_country: Optional[str] = None
|
|
328
257
|
):
|
|
329
258
|
"""
|
|
330
259
|
Create a new sandbox.
|
|
@@ -350,6 +279,7 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
350
279
|
"Cannot set metadata or timeout when connecting to an existing sandbox. "
|
|
351
280
|
"Use Sandbox.connect method instead.",
|
|
352
281
|
)
|
|
282
|
+
network_proxy = {}
|
|
353
283
|
connection_headers = {"Authorization": "Bearer root", }
|
|
354
284
|
if debug:
|
|
355
285
|
sandbox_id = "debug_sandbox_id"
|
|
@@ -369,6 +299,8 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
369
299
|
sandbox_domain = response.sandbox_domain
|
|
370
300
|
envd_version = response.envd_version
|
|
371
301
|
envd_access_token = response._envd_access_token
|
|
302
|
+
object_storage = response.object_storage
|
|
303
|
+
network_proxy = response.network_proxy
|
|
372
304
|
|
|
373
305
|
if response._envd_access_token is not None and not isinstance(
|
|
374
306
|
response._envd_access_token, Unset
|
|
@@ -387,12 +319,16 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
387
319
|
secure=secure,
|
|
388
320
|
proxy=proxy,
|
|
389
321
|
allow_internet_access=allow_internet_access,
|
|
322
|
+
object_storage=object_storage,
|
|
323
|
+
net_proxy_country=net_proxy_country
|
|
390
324
|
)
|
|
391
325
|
|
|
392
326
|
sandbox_id = response.sandbox_id
|
|
393
327
|
sandbox_domain = response.sandbox_domain
|
|
394
328
|
envd_version = response.envd_version
|
|
395
329
|
envd_access_token = response.envd_access_token
|
|
330
|
+
object_storage = response.object_storage
|
|
331
|
+
network_proxy = response.network_proxy
|
|
396
332
|
|
|
397
333
|
if envd_access_token is not None and not isinstance(
|
|
398
334
|
envd_access_token, Unset
|
|
@@ -414,6 +350,8 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
414
350
|
envd_version=envd_version,
|
|
415
351
|
envd_access_token=envd_access_token,
|
|
416
352
|
connection_config=connection_config,
|
|
353
|
+
object_storage=object_storage,
|
|
354
|
+
network_proxy=network_proxy
|
|
417
355
|
)
|
|
418
356
|
|
|
419
357
|
timeout = 10.0
|
|
@@ -429,7 +367,7 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
429
367
|
time.sleep(interval)
|
|
430
368
|
elapsed += interval
|
|
431
369
|
else:
|
|
432
|
-
print("connect "+sandbox_domain+ENVD_API_HEALTH_ROUTE +" timeout
|
|
370
|
+
print("connect "+sandbox_domain+ENVD_API_HEALTH_ROUTE +" timeout 10s")
|
|
433
371
|
return sanbox
|
|
434
372
|
|
|
435
373
|
def is_running(self, request_timeout: Optional[float] = None) -> bool:
|
|
@@ -468,64 +406,155 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
468
406
|
|
|
469
407
|
return True
|
|
470
408
|
|
|
409
|
+
@overload
|
|
410
|
+
def connect(
|
|
411
|
+
self,
|
|
412
|
+
timeout: Optional[int] = None,
|
|
413
|
+
**opts: Unpack[ApiParams],
|
|
414
|
+
) -> Self:
|
|
415
|
+
"""
|
|
416
|
+
Connect to a sandbox. If the sandbox is paused, it will be automatically resumed.
|
|
417
|
+
Sandbox must be either running or be paused.
|
|
418
|
+
|
|
419
|
+
With sandbox ID you can connect to the same sandbox from different places or environments (serverless functions, etc).
|
|
420
|
+
|
|
421
|
+
:param timeout: Timeout for the sandbox in **seconds**
|
|
422
|
+
For running sandboxes, the timeout will update only if the new timeout is longer than the existing one.
|
|
423
|
+
:return: A running sandbox instance
|
|
424
|
+
|
|
425
|
+
@example
|
|
426
|
+
```python
|
|
427
|
+
sandbox = Sandbox.create()
|
|
428
|
+
sandbox.beta_pause()
|
|
429
|
+
|
|
430
|
+
# Another code block
|
|
431
|
+
same_sandbox = sandbox.connect()
|
|
432
|
+
|
|
433
|
+
:return: A running sandbox instance
|
|
434
|
+
"""
|
|
435
|
+
...
|
|
436
|
+
|
|
437
|
+
@overload
|
|
471
438
|
@classmethod
|
|
472
439
|
def connect(
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
proxy: Optional[ProxyTypes] = None,
|
|
479
|
-
):
|
|
440
|
+
cls,
|
|
441
|
+
sandbox_id: str,
|
|
442
|
+
timeout: Optional[int] = None,
|
|
443
|
+
**opts: Unpack[ApiParams],
|
|
444
|
+
) -> Self:
|
|
480
445
|
"""
|
|
481
|
-
|
|
446
|
+
Connect to a sandbox. If the sandbox is paused, it will be automatically resumed.
|
|
447
|
+
Sandbox must be either running or be paused.
|
|
448
|
+
|
|
482
449
|
With sandbox ID you can connect to the same sandbox from different places or environments (serverless functions, etc).
|
|
483
450
|
|
|
484
451
|
:param sandbox_id: Sandbox ID
|
|
485
|
-
:param
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
:return: sandbox instance for the existing sandbox
|
|
452
|
+
:param timeout: Timeout for the sandbox in **seconds**.
|
|
453
|
+
For running sandboxes, the timeout will update only if the new timeout is longer than the existing one.
|
|
454
|
+
:return: A running sandbox instance
|
|
489
455
|
|
|
490
456
|
@example
|
|
491
457
|
```python
|
|
492
|
-
sandbox = Sandbox()
|
|
493
|
-
|
|
458
|
+
sandbox = Sandbox.create()
|
|
459
|
+
Sandbox.beta_pause(sandbox.sandbox_id)
|
|
494
460
|
|
|
495
461
|
# Another code block
|
|
496
|
-
same_sandbox = Sandbox.connect(sandbox_id)
|
|
462
|
+
same_sandbox = Sandbox.connect(sandbox.sandbox_id)
|
|
497
463
|
```
|
|
498
464
|
"""
|
|
499
|
-
|
|
465
|
+
...
|
|
500
466
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
467
|
+
@class_method_variant("_cls_connect")
|
|
468
|
+
def connect(
|
|
469
|
+
self,
|
|
470
|
+
timeout: Optional[int] = None,
|
|
471
|
+
**opts: Unpack[ApiParams],
|
|
472
|
+
) -> Self:
|
|
473
|
+
"""
|
|
474
|
+
Connect to a sandbox. If the sandbox is paused, it will be automatically resumed.
|
|
475
|
+
Sandbox must be either running or be paused.
|
|
508
476
|
|
|
509
|
-
|
|
510
|
-
response._envd_access_token, Unset
|
|
511
|
-
):
|
|
512
|
-
connection_headers["X-Access-Token"] = response._envd_access_token
|
|
513
|
-
connection_config = ConnectionConfig(
|
|
514
|
-
api_key=api_key,
|
|
515
|
-
domain=domain,
|
|
516
|
-
debug=debug,
|
|
517
|
-
headers=connection_headers,
|
|
518
|
-
proxy=proxy,
|
|
519
|
-
)
|
|
477
|
+
With sandbox ID you can connect to the same sandbox from different places or environments (serverless functions, etc).
|
|
520
478
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
479
|
+
:param timeout: Timeout for the sandbox in **seconds**.
|
|
480
|
+
For running sandboxes, the timeout will update only if the new timeout is longer than the existing one.
|
|
481
|
+
:return: A running sandbox instance
|
|
482
|
+
|
|
483
|
+
@example
|
|
484
|
+
```python
|
|
485
|
+
sandbox = Sandbox.create()
|
|
486
|
+
sandbox.beta_pause()
|
|
487
|
+
|
|
488
|
+
# Another code block
|
|
489
|
+
same_sandbox = sandbox.connect()
|
|
490
|
+
```
|
|
491
|
+
"""
|
|
492
|
+
SandboxApi._cls_connect(
|
|
493
|
+
sandbox_id=self.sandbox_id,
|
|
494
|
+
timeout=timeout,
|
|
495
|
+
**opts,
|
|
527
496
|
)
|
|
528
497
|
|
|
498
|
+
return self
|
|
499
|
+
|
|
500
|
+
# @classmethod
|
|
501
|
+
# def connect(
|
|
502
|
+
# cls,
|
|
503
|
+
# sandbox_id: str,
|
|
504
|
+
# api_key: Optional[str] = None,
|
|
505
|
+
# domain: Optional[str] = None,
|
|
506
|
+
# debug: Optional[bool] = None,
|
|
507
|
+
# proxy: Optional[ProxyTypes] = None,
|
|
508
|
+
# ):
|
|
509
|
+
# """
|
|
510
|
+
# Connects to an existing Sandbox.
|
|
511
|
+
# With sandbox ID you can connect to the same sandbox from different places or environments (serverless functions, etc).
|
|
512
|
+
#
|
|
513
|
+
# :param sandbox_id: Sandbox ID
|
|
514
|
+
# :param api_key: Scalebox API Key to use for authentication, defaults to `SBX_API_KEY` environment variable
|
|
515
|
+
# :param proxy: Proxy to use for the request and for the **requests made to the returned sandbox**
|
|
516
|
+
#
|
|
517
|
+
# :return: sandbox instance for the existing sandbox
|
|
518
|
+
#
|
|
519
|
+
# @example
|
|
520
|
+
# ```python
|
|
521
|
+
# sandbox = Sandbox()
|
|
522
|
+
# sandbox_id = sandbox.sandbox_id
|
|
523
|
+
#
|
|
524
|
+
# # Another code block
|
|
525
|
+
# same_sandbox = Sandbox.connect(sandbox_id)
|
|
526
|
+
# ```
|
|
527
|
+
# """
|
|
528
|
+
# connection_headers = {"Authorization": "Bearer root"}
|
|
529
|
+
#
|
|
530
|
+
# response = SandboxApi._cls_get_info(
|
|
531
|
+
# sandbox_id,
|
|
532
|
+
# api_key=api_key,
|
|
533
|
+
# domain=domain,
|
|
534
|
+
# debug=debug,
|
|
535
|
+
# proxy=proxy,
|
|
536
|
+
# )
|
|
537
|
+
#
|
|
538
|
+
# if response._envd_access_token is not None and not isinstance(
|
|
539
|
+
# response._envd_access_token, Unset
|
|
540
|
+
# ):
|
|
541
|
+
# connection_headers["X-Access-Token"] = response._envd_access_token
|
|
542
|
+
# connection_config = ConnectionConfig(
|
|
543
|
+
# api_key=api_key,
|
|
544
|
+
# domain=domain,
|
|
545
|
+
# debug=debug,
|
|
546
|
+
# headers=connection_headers,
|
|
547
|
+
# proxy=proxy,
|
|
548
|
+
# )
|
|
549
|
+
#
|
|
550
|
+
# return cls(
|
|
551
|
+
# sandbox_id=sandbox_id,
|
|
552
|
+
# sandbox_domain=response.sandbox_domain,
|
|
553
|
+
# envd_version=response.envd_version,
|
|
554
|
+
# envd_access_token=response._envd_access_token,
|
|
555
|
+
# connection_config=connection_config,
|
|
556
|
+
# )
|
|
557
|
+
|
|
529
558
|
def __enter__(self):
|
|
530
559
|
return self
|
|
531
560
|
|
|
@@ -787,3 +816,49 @@ class Sandbox(SandboxSetup, SandboxApi):
|
|
|
787
816
|
end=end,
|
|
788
817
|
**config_dict,
|
|
789
818
|
)
|
|
819
|
+
|
|
820
|
+
@overload
|
|
821
|
+
def beta_pause(
|
|
822
|
+
self,
|
|
823
|
+
**opts: Unpack[ApiParams],
|
|
824
|
+
) -> None:
|
|
825
|
+
"""
|
|
826
|
+
[BETA] This feature is in beta and may change in the future.
|
|
827
|
+
|
|
828
|
+
Pause the sandbox.
|
|
829
|
+
"""
|
|
830
|
+
...
|
|
831
|
+
|
|
832
|
+
@overload
|
|
833
|
+
@classmethod
|
|
834
|
+
def beta_pause(
|
|
835
|
+
cls,
|
|
836
|
+
sandbox_id: str,
|
|
837
|
+
**opts: Unpack[ApiParams],
|
|
838
|
+
) -> None:
|
|
839
|
+
"""
|
|
840
|
+
[BETA] This feature is in beta and may change in the future.
|
|
841
|
+
|
|
842
|
+
Pause the sandbox specified by sandbox ID.
|
|
843
|
+
|
|
844
|
+
:param sandbox_id: Sandbox ID
|
|
845
|
+
"""
|
|
846
|
+
...
|
|
847
|
+
|
|
848
|
+
@class_method_variant("_cls_pause")
|
|
849
|
+
def beta_pause(
|
|
850
|
+
self,
|
|
851
|
+
**opts: Unpack[ApiParams],
|
|
852
|
+
) -> None:
|
|
853
|
+
"""
|
|
854
|
+
[BETA] This feature is in beta and may change in the future.
|
|
855
|
+
|
|
856
|
+
Pause the sandbox.
|
|
857
|
+
|
|
858
|
+
:return: Sandbox ID that can be used to resume the sandbox
|
|
859
|
+
"""
|
|
860
|
+
|
|
861
|
+
SandboxApi._cls_pause(
|
|
862
|
+
sandbox_id=self.sandbox_id,
|
|
863
|
+
**opts,
|
|
864
|
+
)
|