Skip to content

Commit c6f45f7

Browse files
committed
Add snapshot get/delete, image build list, and volume list filters for sandbox API parity
1 parent 80b5e8b commit c6f45f7

11 files changed

Lines changed: 163 additions & 14 deletions

File tree

hyperbrowser/client/managers/async_manager/sandbox.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
SandboxExposeResult,
1616
SandboxImageBuild,
1717
SandboxImageBuildCreateResult,
18+
SandboxImageBuildListParams,
19+
SandboxImageBuildListResponse,
1820
SandboxImageListParams,
1921
SandboxImageListResponse,
2022
SandboxImageInit,
@@ -25,8 +27,10 @@
2527
SandboxNetworkPolicy,
2628
SandboxNetworkUpdateResult,
2729
SandboxRuntimeSession,
30+
SandboxSnapshotDeleteResult,
2831
SandboxSnapshotListParams,
2932
SandboxSnapshotListResponse,
33+
SandboxSnapshotSummary,
3034
SandboxUnexposeResult,
3135
StartSandboxFromSnapshotParams,
3236
)
@@ -37,6 +41,7 @@
3741
CreateSandboxParams as CreateSandboxParamsDict,
3842
SandboxExecParams as SandboxExecParamsDict,
3943
SandboxExposeParams as SandboxExposeParamsDict,
44+
SandboxImageBuildListParams as SandboxImageBuildListParamsDict,
4045
SandboxImageInit as SandboxImageInitDict,
4146
SandboxImageListParams as SandboxImageListParamsDict,
4247
SandboxListParams as SandboxListParamsDict,
@@ -450,6 +455,14 @@ async def list_snapshots(
450455
)
451456
return SandboxSnapshotListResponse(**payload)
452457

458+
async def get_snapshot(self, snapshot: str) -> SandboxSnapshotSummary:
459+
payload = await self._request("GET", f"/snapshots/{snapshot}")
460+
return SandboxSnapshotSummary(**payload["snapshot"])
461+
462+
async def delete_snapshot(self, snapshot: str) -> SandboxSnapshotDeleteResult:
463+
payload = await self._request("DELETE", f"/snapshots/{snapshot}")
464+
return SandboxSnapshotDeleteResult(**payload)
465+
453466
async def stop(self, sandbox_id: str) -> BasicResponse:
454467
payload = await self._request("PUT", f"/sandbox/{sandbox_id}/stop")
455468
return BasicResponse(**payload)
@@ -491,6 +504,22 @@ async def cancel_image_build(self, build_id: str) -> SandboxImageBuild:
491504
payload = await self._request("POST", f"/images/builds/{build_id}/cancel")
492505
return SandboxImageBuild(**payload["build"])
493506

507+
async def list_image_builds(
508+
self,
509+
params: Optional[
510+
Union[SandboxImageBuildListParamsDict, SandboxImageBuildListParams]
511+
] = None,
512+
) -> SandboxImageBuildListResponse:
513+
payload = await self._request(
514+
"GET",
515+
"/images/builds",
516+
params=dump_request(
517+
params if params is not None else {},
518+
SandboxImageBuildListParams,
519+
),
520+
)
521+
return SandboxImageBuildListResponse(**payload)
522+
494523
async def wait_for_image_build(
495524
self,
496525
build_id: str,

hyperbrowser/client/managers/async_manager/volume.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
from typing import Union
1+
from typing import Optional, Union
22

33
from hyperbrowser.client._request import dump_request
4-
from hyperbrowser.models.volume import CreateVolumeParams, Volume, VolumeListResponse
4+
from hyperbrowser.models.volume import (
5+
CreateVolumeParams,
6+
Volume,
7+
VolumeListParams,
8+
VolumeListResponse,
9+
)
510
from hyperbrowser.types import CreateVolumeParams as CreateVolumeParamsDict
11+
from hyperbrowser.types import VolumeListParams as VolumeListParamsDict
612

713

814
class VolumeManager:
@@ -19,8 +25,17 @@ async def create(
1925
)
2026
return Volume(**response.data)
2127

22-
async def list(self) -> VolumeListResponse:
23-
response = await self._client.transport.get(self._client._build_url("/volume"))
28+
async def list(
29+
self,
30+
params: Optional[Union[VolumeListParamsDict, VolumeListParams]] = None,
31+
) -> VolumeListResponse:
32+
response = await self._client.transport.get(
33+
self._client._build_url("/volume"),
34+
params=dump_request(
35+
params if params is not None else {},
36+
VolumeListParams,
37+
),
38+
)
2439
return VolumeListResponse(**response.data)
2540

2641
async def get(self, volume_id: str) -> Volume:

hyperbrowser/client/managers/sync_manager/sandbox.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
SandboxExposeResult,
1414
SandboxImageBuild,
1515
SandboxImageBuildCreateResult,
16+
SandboxImageBuildListParams,
17+
SandboxImageBuildListResponse,
1618
SandboxImageListParams,
1719
SandboxImageListResponse,
1820
SandboxImageInit,
@@ -23,8 +25,10 @@
2325
SandboxNetworkPolicy,
2426
SandboxNetworkUpdateResult,
2527
SandboxRuntimeSession,
28+
SandboxSnapshotDeleteResult,
2629
SandboxSnapshotListParams,
2730
SandboxSnapshotListResponse,
31+
SandboxSnapshotSummary,
2832
SandboxUnexposeResult,
2933
StartSandboxFromSnapshotParams,
3034
)
@@ -35,6 +39,7 @@
3539
CreateSandboxParams as CreateSandboxParamsDict,
3640
SandboxExecParams as SandboxExecParamsDict,
3741
SandboxExposeParams as SandboxExposeParamsDict,
42+
SandboxImageBuildListParams as SandboxImageBuildListParamsDict,
3843
SandboxImageInit as SandboxImageInitDict,
3944
SandboxImageListParams as SandboxImageListParamsDict,
4045
SandboxListParams as SandboxListParamsDict,
@@ -442,6 +447,14 @@ def list_snapshots(
442447
)
443448
return SandboxSnapshotListResponse(**payload)
444449

450+
def get_snapshot(self, snapshot: str) -> SandboxSnapshotSummary:
451+
payload = self._request("GET", f"/snapshots/{snapshot}")
452+
return SandboxSnapshotSummary(**payload["snapshot"])
453+
454+
def delete_snapshot(self, snapshot: str) -> SandboxSnapshotDeleteResult:
455+
payload = self._request("DELETE", f"/snapshots/{snapshot}")
456+
return SandboxSnapshotDeleteResult(**payload)
457+
445458
def stop(self, sandbox_id: str) -> BasicResponse:
446459
payload = self._request("PUT", f"/sandbox/{sandbox_id}/stop")
447460
return BasicResponse(**payload)
@@ -483,6 +496,22 @@ def cancel_image_build(self, build_id: str) -> SandboxImageBuild:
483496
payload = self._request("POST", f"/images/builds/{build_id}/cancel")
484497
return SandboxImageBuild(**payload["build"])
485498

499+
def list_image_builds(
500+
self,
501+
params: Optional[
502+
Union[SandboxImageBuildListParamsDict, SandboxImageBuildListParams]
503+
] = None,
504+
) -> SandboxImageBuildListResponse:
505+
payload = self._request(
506+
"GET",
507+
"/images/builds",
508+
params=dump_request(
509+
params if params is not None else {},
510+
SandboxImageBuildListParams,
511+
),
512+
)
513+
return SandboxImageBuildListResponse(**payload)
514+
486515
def wait_for_image_build(
487516
self,
488517
build_id: str,

hyperbrowser/client/managers/sync_manager/volume.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
1-
from typing import Union
1+
from typing import Optional, Union
22

33
from hyperbrowser.client._request import dump_request
4-
from hyperbrowser.models.volume import CreateVolumeParams, Volume, VolumeListResponse
4+
from hyperbrowser.models.volume import (
5+
CreateVolumeParams,
6+
Volume,
7+
VolumeListParams,
8+
VolumeListResponse,
9+
)
510
from hyperbrowser.types import CreateVolumeParams as CreateVolumeParamsDict
11+
from hyperbrowser.types import VolumeListParams as VolumeListParamsDict
612

713

814
class VolumeManager:
@@ -19,8 +25,17 @@ def create(
1925
)
2026
return Volume(**response.data)
2127

22-
def list(self) -> VolumeListResponse:
23-
response = self._client.transport.get(self._client._build_url("/volume"))
28+
def list(
29+
self,
30+
params: Optional[Union[VolumeListParamsDict, VolumeListParams]] = None,
31+
) -> VolumeListResponse:
32+
response = self._client.transport.get(
33+
self._client._build_url("/volume"),
34+
params=dump_request(
35+
params if params is not None else {},
36+
VolumeListParams,
37+
),
38+
)
2439
return VolumeListResponse(**response.data)
2540

2641
def get(self, volume_id: str) -> Volume:

hyperbrowser/models/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@
210210
ProfileListResponse,
211211
ProfileResponse,
212212
)
213-
from .volume import CreateVolumeParams, Volume, VolumeListResponse
213+
from .volume import CreateVolumeParams, Volume, VolumeListParams, VolumeListResponse
214214
from .scrape import (
215215
BatchScrapeJobResponse,
216216
BatchScrapeJobStatusResponse,
@@ -310,6 +310,7 @@
310310
SandboxImageListResponse,
311311
SandboxImageSummary,
312312
SandboxSnapshotStatus,
313+
SandboxSnapshotDeleteResult,
313314
SandboxSnapshotListResponse,
314315
SandboxSnapshotSummary,
315316
SandboxSnapshotListParams,
@@ -323,6 +324,8 @@
323324
SandboxImageBuildUpload,
324325
SandboxImageBuild,
325326
SandboxImageBuildCreateResult,
327+
SandboxImageBuildListParams,
328+
SandboxImageBuildListResponse,
326329
SandboxExposeParams,
327330
SandboxExposeResult,
328331
SandboxUnexposeResult,
@@ -530,6 +533,7 @@
530533
# volume
531534
"CreateVolumeParams",
532535
"Volume",
536+
"VolumeListParams",
533537
"VolumeListResponse",
534538
# scrape
535539
"BatchScrapeJobResponse",
@@ -604,6 +608,7 @@
604608
"SandboxImageListResponse",
605609
"SandboxImageSummary",
606610
"SandboxSnapshotStatus",
611+
"SandboxSnapshotDeleteResult",
607612
"SandboxSnapshotListResponse",
608613
"SandboxSnapshotSummary",
609614
"SandboxSnapshotListParams",
@@ -617,6 +622,8 @@
617622
"SandboxImageBuildUpload",
618623
"SandboxImageBuild",
619624
"SandboxImageBuildCreateResult",
625+
"SandboxImageBuildListParams",
626+
"SandboxImageBuildListResponse",
620627
"SandboxExposeParams",
621628
"SandboxExposeResult",
622629
"SandboxUnexposeResult",

hyperbrowser/models/sandbox.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,9 @@ class SandboxSnapshotSummary(SandboxBaseModel):
309309
image_name: str = Field(alias="imageName")
310310
image_id: str = Field(alias="imageId")
311311
status: SandboxSnapshotStatus
312+
vcpus: Optional[int] = None
313+
mem_mib: Optional[int] = Field(default=None, alias="memMiB")
314+
disk_size_mib: Optional[int] = Field(default=None, alias="diskSizeMiB")
312315
compatibility_tag: Optional[str] = Field(default=None, alias="compatibilityTag")
313316
metadata: Dict[str, object]
314317
uploaded: bool
@@ -334,6 +337,10 @@ class SandboxSnapshotListResponse(SandboxBaseModel):
334337
per_page: Optional[int] = Field(default=None, alias="perPage")
335338

336339

340+
class SandboxSnapshotDeleteResult(SandboxBaseModel):
341+
deleted: bool
342+
343+
337344
class SandboxMemorySnapshotParams(SandboxBaseModel):
338345
snapshot_name: Optional[str] = Field(
339346
default=None, serialization_alias="snapshotName"
@@ -423,6 +430,15 @@ class SandboxImageBuildCreateResult(SandboxBaseModel):
423430
upload: SandboxImageBuildUpload
424431

425432

433+
class SandboxImageBuildListParams(SandboxBaseModel):
434+
status: Optional[str] = None
435+
limit: Optional[int] = Field(default=None, ge=1)
436+
437+
438+
class SandboxImageBuildListResponse(SandboxBaseModel):
439+
builds: List[SandboxImageBuild]
440+
441+
426442
class SandboxExecParams(SandboxBaseModel):
427443
command: str
428444
args: Optional[List[str]] = None

hyperbrowser/models/volume.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ class CreateVolumeParams(VolumeBaseModel):
1313
name: str
1414

1515

16+
class VolumeListParams(VolumeBaseModel):
17+
page: Optional[int] = Field(default=None, ge=1)
18+
limit: Optional[int] = Field(default=None, ge=1)
19+
search: Optional[str] = None
20+
21+
1622
class Volume(VolumeBaseModel):
1723
id: str
1824
name: str
@@ -27,3 +33,6 @@ def parse_optional_int_fields(cls, value):
2733

2834
class VolumeListResponse(VolumeBaseModel):
2935
volumes: List[Volume]
36+
total_count: Optional[int] = Field(default=None, alias="totalCount")
37+
page: Optional[int] = None
38+
per_page: Optional[int] = Field(default=None, alias="perPage")

hyperbrowser/types/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
SandboxFileWriteEntry,
8282
SandboxFileWriteTextParams,
8383
SandboxImageBuildInputFormat,
84+
SandboxImageBuildListParams,
8485
SandboxImageInit,
8586
SandboxImageListParams,
8687
SandboxListParams,
@@ -132,7 +133,7 @@
132133
UpdateSessionScreenParams,
133134
UpdateSessionSolveCaptchasParams,
134135
)
135-
from .volume import CreateVolumeParams
136+
from .volume import CreateVolumeParams, VolumeListParams
136137
from .web import (
137138
FetchBrowserLocationOptions,
138139
FetchBrowserOptions,
@@ -235,6 +236,7 @@
235236
"SandboxFileWriteEntry",
236237
"SandboxFileWriteTextParams",
237238
"SandboxImageBuildInputFormat",
239+
"SandboxImageBuildListParams",
238240
"SandboxImageInit",
239241
"SandboxImageListParams",
240242
"SandboxListParams",
@@ -282,6 +284,7 @@
282284
"UpdateSessionScreenParams",
283285
"UpdateSessionSolveCaptchasParams",
284286
"CreateVolumeParams",
287+
"VolumeListParams",
285288
"FetchBrowserLocationOptions",
286289
"FetchBrowserOptions",
287290
"FetchCacheOptions",

hyperbrowser/types/sandbox.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,13 @@ class SandboxSnapshotListParams(TypedDict, total=False):
128128
page: Optional[int]
129129

130130

131+
class SandboxImageBuildListParams(TypedDict, total=False):
132+
"""Filters for listing sandbox image builds."""
133+
134+
status: Optional[str]
135+
limit: Optional[int]
136+
137+
131138
class SandboxMemorySnapshotParams(TypedDict, total=False):
132139
"""Parameters for creating a sandbox memory snapshot."""
133140

@@ -415,6 +422,7 @@ class SandboxTerminalKillParams(TypedDict, total=False):
415422
"SandboxFileWriteEntry",
416423
"SandboxFileWriteTextParams",
417424
"SandboxImageBuildInputFormat",
425+
"SandboxImageBuildListParams",
418426
"SandboxImageInit",
419427
"SandboxImageListParams",
420428
"SandboxListParams",

hyperbrowser/types/volume.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Optional
2+
13
from typing_extensions import TypedDict
24

35

@@ -7,4 +9,12 @@ class CreateVolumeParams(TypedDict):
79
name: str
810

911

10-
__all__ = ["CreateVolumeParams"]
12+
class VolumeListParams(TypedDict, total=False):
13+
"""Filters and pagination for listing sandbox volumes."""
14+
15+
page: Optional[int]
16+
limit: Optional[int]
17+
search: Optional[str]
18+
19+
20+
__all__ = ["CreateVolumeParams", "VolumeListParams"]

0 commit comments

Comments
 (0)