CWSANDBOX_API_KEY에 설정된 CoreWeave API 액세스 토큰을 사용합니다. Forge API 키 인증은 시작하기를 참조하세요. CKS 요구 사항은 배치 모드를 참조하세요.
이 가이드에서는 샌드박스가 생성부터 종료까지 진행되는 과정과 각 단계의 상태, 시작 및 대기 방법, 정상적으로 중지하는 방법을 설명합니다. 생성 패턴을 선택하거나, 시작 시점을 제어하거나, SDK 코드에서 종료를 안정적으로 처리해야 할 때 이 가이드를 참고하세요.
라이프사이클 상태
모든 샌드박스는 시작, 실행, 종료 과정에서 일련의 상태를 거칩니다. SDK는 이러한 상태를SandboxStatus 값으로 나타냅니다.
PENDING과 CREATING은 일시적인 상태입니다. SDK는 이 상태를 자동으로 계속 폴링합니다.
TERMINATING은 일시적인 백엔드 상태로, wait_until_complete()와 stop().result()는
이 상태를 거쳐 종료 상태에 도달하도록 합니다. RUNNING은 안정적인 동작 상태입니다.
COMPLETED와 FAILED는 종료 상태입니다. SDK는 폴링 시 UNSPECIFIED를 COMPLETED로
매핑합니다.
생성 패턴
샌드박스는 두 가지 방식으로 생성할 수 있으며, 시작 RPC가 호출되는 시점이 다릅니다. 다음 섹션에서는 각 패턴과 선택 기준을 설명합니다.Sandbox.run(): 즉시 시작
Sandbox.run()은 샌드박스를 생성하고 내부적으로 start().result()를 호출하며,
백엔드가 요청을 수락할 때까지 대기합니다:
session.sandbox(): 지연 시작
session.sandbox()는 네트워크 호출 없이 샌드박스 객체를 생성합니다. 시작 RPC는
처음 사용할 때 실행됩니다:
메인 명령 수명
run() 또는 session.sandbox()에 전달된 메인 명령은 샌드박스의 메인 프로세스입니다.
메인 프로세스가 종료되면 어떻게 처리되는지는 종료 상태에 따라 달라집니다.
- 종료 상태 0: 샌드박스가
COMPLETED상태로 전환됩니다. - 0이 아닌 종료 상태: 플랫폼이 메인 프로세스의 컨테이너를 재시작합니다. 이미
RUNNING에 도달한 샌드박스는 재시작되는 동안에도RUNNING상태를 유지하고, 아직 도달하지 않은 샌드박스는CREATING상태를 유지합니다.wait_until_complete()는 재시작되는 동안에도timeout에 도달할 때까지 계속 대기합니다. - 재시작 한도 도달: 메인 프로세스가 0이 아닌 상태로 계속 종료되면, 재시작 한도(현재 6회)에
도달했을 때 샌드박스가
FAILED상태로 전환됩니다.
exec()을 사용하세요. 짧은 명령을 메인 프로세스로 만들지 마세요.
샌드박스 시작
샌드박스 객체가 존재한 후에는 명시적으로 시작하거나 SDK가 처음 사용할 때 시작하도록 할 수 있습니다. 다음 섹션에서는 두 가지 접근 방식과 컨텍스트 매니저가 어떻게 상호작용하는지 설명합니다.명시적 시작
start()는 시작 RPC를 전송하고 OperationRef[None]을 반환합니다:
자동 시작
대부분의 오퍼레이션은 샌드박스가 아직 시작되지 않았다면 자동으로 시작합니다. 일반적으로는 샌드박스를 생성한 후 바로 사용하면 됩니다.컨텍스트 관리자와 start
컨텍스트 관리자(with/async with)는 진입 시 start()를 호출하지만 wait()는 호출하지 않습니다.
첫 번째 오퍼레이션을 실행하기 전에 샌드박스가 RUNNING 상태여야 한다면 wait()를 명시적으로 호출하세요:
exec()가 내부적으로 RUNNING 상태가 될 때까지 기다리므로 이 부분이 문제가 되는 경우는 드뭅니다. wait()를 명시적으로
호출하면 시작 실패와 오퍼레이션 실패를 구분해서 처리하고 싶을 때 유용합니다.
샌드박스 대기
SDK는 샌드박스가 오퍼레이션을 수행할 준비가 될 때까지 기다릴지, 메인 명령이 완료될 때까지 기다릴지에 따라 두 가지 대기 방법을 제공합니다. 다음 섹션에서는 각 방법과 시작 timeout 및 오퍼레이션 timeout의 관계를 설명합니다.wait(): RUNNING 상태까지 대기
wait()는 샌드박스가 RUNNING, TERMINATING 또는 종료 상태에 도달할 때까지 폴링합니다:
wait()는 방법 체이닝을 위해 self를 반환합니다:
wait()가 이를 처리합니다:
wait_until_complete(): 종료 상태까지 대기
wait_until_complete()는 샌드박스가 종료 상태에 도달할 때까지 대기하며,
TERMINATING 상태에서도 자동으로 폴링을 계속합니다. 메인 명령이 작업을 수행하는 샌드박스에 사용하세요:
True인 raise_on_termination 매개변수는 이 클라이언트가 stop()을 호출한 후
wait_until_complete()가 SandboxTerminatedError를 발생시킬지 제어합니다.
외부 중지는 별도의 오류 없이 COMPLETED로 표시됩니다. 백엔드가 아직
종료 사유 메타데이터를 제공하지 않기 때문입니다. 반면 최대 수명에 도달한 샌드박스는
FAILED 상태로 종료되므로 wait_until_complete()가 SandboxFailedError를 발생시킵니다.
timeout 단계
시작 대기 시간과 오퍼레이션 timeout은 별개의 단계이며, 샌드박스의 최대 수명이 두 단계 모두를 제한합니다:- 시작 대기: RUNNING 상태에 도달하기 전 PENDING/CREATING 상태에서 소요되는 시간입니다.
wait()또는wait_until_complete()의timeout매개변수로 제어합니다. 일반적으로 백엔드 스케줄링에 따라 30~60초가 소요됩니다. - 오퍼레이션 timeout: 개별 실행, 조회 또는 쓰기에 허용되는 시간입니다.
exec()의timeout_seconds또는SandboxDefaults의request_timeout_seconds로 제어합니다. 시작 대기는 포함하지 않습니다. - 최대 수명: 샌드박스가 존재할 수 있는 총 실제 경과 시간으로, 시작 시점부터 계산하며
시작 대기를 포함합니다.
max_lifetime_seconds로 제어합니다. 설정하지 않으면 러너 정책의 기본값이 적용되며, 양수 기본값이 설정되어 있지 않으면 플랫폼의 대체 기본값인 10분이 적용됩니다.
max_lifetime_seconds를 예상되는 총 작업 시간보다 충분히 길게 설정하세요. 이 값은
샌드박스가 시작된 후에는 변경할 수 없습니다. 네 가지 timeout 설정과 상호 작용 방식은
timeout을 참조하세요. 30일 제한과
Serverless 및 CKS용 설정 예시는 장기 실행 샌드박스 실행을 참조하세요.
오퍼레이션 및 라이프사이클
exec(), read_file(), write_file() 등의 오퍼레이션은 필요한 경우 샌드박스를 자동으로 시작한 다음,
RUNNING 상태가 될 때까지 기다린 후 진행합니다:
timeout_seconds)은 샌드박스가 RUNNING 상태가 된 후에만 적용됩니다. 시작
시간은 timeout에 포함되지 않습니다.
샌드박스 중지 및 수명 종료
이 섹션에서는 샌드박스를 종료하는 방법, 중지 후 발생하는 동작, 그리고stop()과 delete()를 각각 언제 사용해야 하는지 설명합니다.
stop()
stop()은 중지 요청을 보내고 OperationRef[None]을 반환합니다. 샌드박스는
TERMINATING(유예 기간 동안 드레이닝) 상태를 거쳐 종료 상태에 도달합니다. 반환된
OperationRef는 중지 RPC가 성공했을 때가 아니라 백엔드가 종료 상태를
확인했을 때 완료됩니다:
stop()은 진행 중인 시작 요청을 처리합니다. 시작 요청이 아직 처리 중이면 시작이
완료될 때까지 기다린 후 중지합니다. 동시에 또는 반복해서 stop() Call을 수행하면 하나의 중지 오퍼레이션을 공유하며
중복된 중지 RPC를 보내지 않습니다. 따라서 stop() Call을 반복해도 안전하며 비용이 적게 듭니다.
중지 후 동작
stop()이 호출되면 샌드박스는 TERMINATING(유예 기간 동안
드레이닝하는 상태)을 거쳐 종료 상태(COMPLETED 또는 FAILED)에 도달합니다. stop()이
호출된 후에는 샌드박스를 사용할 수 없습니다. 이후 오퍼레이션은 SandboxNotRunningError를 발생시킵니다:
status 속성은 마지막 API 호출에서 캐시됩니다. 중지하기 전에 최신 데이터를 조회하려면
get_status()를 사용하세요:
컨텍스트 매니저 종료
컨텍스트 매니저는 종료 시stop()을 자동으로 호출합니다:
stop()와 delete() 비교
활성 상태로 사용 중인 샌드박스에는
stop()을 사용하세요. 샌드박스의 정리에는 delete()를 사용하세요.
Sandbox.list() 또는 Sandbox.from_id()를 통해 발견한 샌드박스:
내부 동작
SDK는 자체 asyncio 이벤트 루프가 있는 백그라운드 데몬 스레드에서 모든 gRPC 오퍼레이션을 실행합니다. 이 설계는 다음과 같이 동작합니다:- 동기 API (
.result())는 백그라운드 루프가 네트워크 호출을 처리하는 동안 호출 스레드를 차단합니다. - 비동기 API (
await)는 동일한 백그라운드 루프에 연결되므로 두 방식 모두 동일한 내부 구현을 사용합니다. - 백그라운드 루프는 처음 사용할 때 지연 시작됩니다. gRPC 채널도 지연 생성됩니다.
- 자동 시작은 각 오퍼레이션 전에
sandbox_id가 None인지 확인하고, None이면start()를 트리거하는 방식으로 동작합니다. - 프로세스가 종료되면 정리 핸들러(atexit + 시그널 핸들러)가 등록된 세션의 모든 샌드박스를 중지합니다. 정리 중 Ctrl+C를 한 번 더 누르면 즉시 강제 종료됩니다.
nest_asyncio 없이 작동합니다. 사용 방식은 동기 및 비동기 방식 비교 가이드를 참조하세요.