@@ -1042,3 +1042,89 @@ their explicit-name behavior and continue to report build conflicts directly.
10421042## License
10431043
10441044This project is licensed under the MIT License - see the [ LICENSE] ( LICENSE ) file for details.
1045+
1046+ ### GPU sandboxes
1047+
1048+ Build a GPU-ready image from a remote Dockerfile context, then select a GPU when
1049+ creating the sandbox. GPU image publication happens after the ordinary build;
1050+ ` enable_gpu_builds=True ` makes the build helpers wait for ` gpu_image_ready ` and
1051+ keeps CPU-only images out of GPU cache reuse. Local/prebuilt Docker image imports
1052+ do not support GPU publication.
1053+
1054+ ``` python
1055+ from hyperbrowser import Hyperbrowser
1056+
1057+ client = Hyperbrowser()
1058+ image = client.sandboxes.get_or_build_image(
1059+ context_path = " ./gpu-image" , # Your CUDA-compatible Dockerfile and context
1060+ enable_gpu_builds = True ,
1061+ )
1062+ sandbox = client.sandboxes.create({
1063+ " image_name" : image.image_name,
1064+ " image_id" : image.image_id,
1065+ " gpu" : " H100" ,
1066+ " gpu_count" : 2 ,
1067+ " preempt" : False , # Require on-demand capacity; account enablement required
1068+ " region" : " us" ,
1069+ " cpu" : 8 ,
1070+ " memory_mib" : 32768 ,
1071+ " disk_mib" : 65536 ,
1072+ " exposed_ports" : [{" port" : 8000 , " auth" : True }],
1073+ })
1074+ try :
1075+ # create() can return status='provisioning', runtime=None, and token=None.
1076+ sandbox.wait_until_ready(timeout = 20 * 60 )
1077+ result = sandbox.exec(" nvidia-smi -L" )
1078+ print (result.stdout)
1079+ sandbox.update_network({" allow_out" : [" example.com" ], " deny_out" : []})
1080+ finally :
1081+ sandbox.stop()
1082+ ```
1083+
1084+ ` gpu_count ` defaults to one and accepts 1–8; the API checks that the requested
1085+ GPU, CPU, and memory combination is available. Omitted ` preempt ` (or ` True ` )
1086+ allows spot capacity. ` False ` requires on-demand capacity. GPU launches require
1087+ ` region="us" ` ; ` runtime_class="gvisor-cpu" ` is inferred by the API. The disk is
1088+ quota-limited ephemeral storage, from 12 GiB (the default) up to 512 GiB, subject
1089+ to your plan and host capacity. Snapshots, volume mounts, and startup secrets are
1090+ not supported for GPU launches.
1091+
1092+ ` wait_until_ready() ` returns the same handle, retries transient reads with
1093+ backoff, and reports failures with the sandbox ID and close reason. Its timeout
1094+ is independent of ` timeout_minutes ` , which controls the sandbox lifetime.
1095+ Timeout or cancellation stops only the wait. For synchronous cancellation, pass
1096+ a ` threading.Event ` as ` cancel_event ` ; it is checked between HTTP reads. Async
1097+ clients support the same methods with ` await ` , and the waiting task can be
1098+ cancelled. After cancelling a wait, use the saved ID to inspect or stop the
1099+ sandbox. ` get() ` and ` list() ` can also return provisioning sandboxes; the list
1100+ API's existing ` status="active" ` filter includes provisioning requests.
1101+
1102+ GPU handles expose ` gpu_type ` , ` gpu_count ` , ` preempt ` , ` runtime_class ` ,
1103+ ` capabilities ` , ` recording_enabled ` , and ` close_reason ` . Existing files, commands,
1104+ PTY, exposed-port authentication, and network-update methods work after readiness.
1105+ ` credits_used ` and termination details remain available through ` info() ` .
1106+
1107+ For a custom image that starts an X11 desktop and installs the receiver's input
1108+ and screenshot tools, use the sandbox runtime computer-action endpoint:
1109+
1110+ ``` python
1111+ screenshot = sandbox.computer_action({" action" : " screenshot" })
1112+ sandbox.computer_action({" action" : " click" , " x" : 300 , " y" : 200 })
1113+ sandbox.computer_action({" action" : " type_text" , " text" : " Hello" })
1114+ ```
1115+
1116+ These calls belong inside the sandbox's active lifetime (before ` stop() ` ). They
1117+ use the sandbox runtime token, including token refresh, and accept the existing
1118+ computer-action TypedDicts and legacy Pydantic request models. The image owns
1119+ display startup; runtime readiness does not imply desktop readiness. Set
1120+ ` enable_recording=True ` at creation to record a supported image's display and
1121+ retrieve the video through ` client.sessions.get_video_recording_url(sandbox.id) ` .
1122+
1123+ GPU cache lookup verifies the API's latest 100 completed builds. An older image
1124+ may be rebuilt when its GPU readiness cannot be verified from that window.
1125+ For live validation, set ` HYPERBROWSER_API_KEY ` and
1126+ ` HYPERBROWSER_GPU_IMAGE_NAME ` (an already published image containing ` nvidia-smi ` ),
1127+ then run ` pytest tests/sandbox/e2e/test_gpu.py ` . Optional ` HYPERBROWSER_GPU_TYPE ` ,
1128+ ` HYPERBROWSER_GPU_COUNT ` , and ` HYPERBROWSER_GPU_PREEMPT=false ` select the GPU
1129+ configuration; ` HYPERBROWSER_GPU_DESKTOP=1 ` also checks screenshots. These tests
1130+ create billable sandboxes and stop them in cleanup.
0 commit comments