−25%

Windows 연간 결제, 10월 31일까지. 요금제 보기

EQVPS
시작하기

샌드박스 API 레퍼런스: Python과 TypeScript SDK

EQVPS 샌드박스 SDK의 모든 메서드를 한 페이지에: 매개변수, 기본값, 반환값, 그리고 11개 오류 클래스 전부를 Python과 TypeScript의 같은 예제와 함께.

최종 확인: 2026-10-10 · SDK 0.2.0 (PyPI eqvps, npm @eqvps/sdk)

SDK는 샌드박스 REST API를 얇게 감싼 것입니다. 요청을 직접 만드는 일, 플랫폼이 바쁠 때 재시도하는 일, 코드가 예외를 던졌을 때 샌드박스 삭제를 잊는 일, 이 세 가지를 덜어 줍니다. 이 페이지의 내용은 두 패키지의 0.2.0 버전에 해당합니다.

샌드박스를 만들어 본 적이 없다면 5분 연결 가이드에서 먼저 토큰을 받으세요. 샌드박스가 무엇이고 안에 무엇이 있는지는 샌드박스에 있습니다.

설치와 설정

pip install eqvps          # Python 3.8+
npm i @eqvps/sdk           # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=...   # your EQVPS account token

두 언어로 쓴 같은 프로그램: 샌드박스를 만들고, 코드를 실행하고, 삭제합니다.

from eqvps import Sandbox

with Sandbox.create(tariff="small") as sb:
    r = sb.run("print(2 + 2)")
    print(r.exit_code, r.stdout)   # 0 4
import { Sandbox } from "@eqvps/sdk";

await Sandbox.with({ tariff: "small" }, async (sb) => {
  const r = await sb.run("print(2 + 2)");
  console.log(r.exit_code, r.stdout); // 0 4
});

샌드박스 만들기와 찾기

Sandbox.create(...)는 샌드박스를 시작하며, 보통 약 1초가 걸립니다. Python은 키워드 인수를, TypeScript는 옵션 객체 하나를 받습니다.

PythonTypeScript기본값의미
modemode"ephemeral""ephemeral"(초 단위) 또는 "persistent"(시작된 시간 단위, 디스크 유지)
tarifftariff"small"micro, small, standard, plus, pro, max
idle_timeoutidleTimeout300임시 샌드박스가 삭제되기까지의 무활동 초, 최대 3600
ttlttl—최대 수명(초): 임시는 86400까지, 영구는 2592000까지
envenv—모든 명령에 적용되는 환경 변수, 암호화해 저장
api_key, base_urlapiKey, baseUrl환경 변수EQVPS_API_KEY / EQVPS_API_URL을 대체
timeouttimeoutMs70초요청별 HTTP 타임아웃
max_retriesmaxRetries3429/503 재시도 횟수

Sandbox.connect(id)는 기존 샌드박스에 연결합니다. 보통 어제 만든 영구 샌드박스입니다. Sandbox.list()는 계정의 모든 샌드박스(실행 중, 일시 중지)를 반환합니다.

속성: id(sb_ + 16진수 24자), mode, tariff, state(running, starting, paused, pausing, resuming, deleting, deleted), env_keys / envKeys(이름만, 값은 절대 돌려주지 않음), info(원본 객체). refresh()로 다시 불러옵니다.

kill()은 샌드박스를 삭제하고 과금을 멈춥니다. 이미 없는 샌드박스에 호출해도 오류가 아닙니다.

코드 실행

run(code, language="python", timeout=30)은 stdin으로 코드를 Python 3.12, Node.js 22, bash("python", "node", "bash")에 전달합니다. exec(command, cwd=None, stdin=None, timeout=30)은 셸 명령을 실행합니다. 문자열은 bash -lc를 거치고, 리스트는 셸 없이 argv로 실행됩니다.

둘 다 ExecResult를 반환합니다:

필드의미
exit_code프로세스 종료 코드
stdout, stderr출력, 스트림당 최대 1 MiB
timed_out명령이 타임아웃에 걸림
truncated출력이 잘림
duration_ms실행 시간
okexit_code == 0이고 타임아웃 없음

동기 호출은 최대 55초까지입니다. 두 메서드 모두 그 호출에만 적용되는 env도 받으며, 생성 시 설정한 값을 덮어씁니다.

긴 작업: 백그라운드 작업

background=True(TypeScript: { background: true })를 넘기면 바로 Task를 받습니다. 55초 제한이 없고 샌드박스 수명이 끝날 때까지 실행할 수 있습니다. 샌드박스당 최대 8개 작업입니다.

task = sb.exec("cd /root/app && python3 -m pytest -q", background=True)
result = task.wait(on_output=lambda out, err: print(out, end=""))
print(result.state, result.exit_code)   # done 0
const task = await sb.exec("cd /root/app && npm test", { background: true });
const result = await task.wait({ onOutput: (out) => process.stdout.write(out) });
메서드하는 일
task.logs()이전 호출 이후의 새 stdout과 stderr
task.status()출력을 소비하지 않고 상태 확인: running, done, failed, killed, timeout
task.wait(timeout, poll_interval=2, on_output)작업이 끝날 때까지 폴링하고 TaskResult 반환
task.kill()작업과 그 프로세스를 중지
sb.task(id) / sb.tasks()작업에 다시 연결 / 작업 목록

wait가 자신의 타임아웃에 도달하면 SandboxTimeoutError를 던지지만 작업은 계속 실행됩니다. 실행 중인 작업이 있으면 임시 샌드박스가 무활동으로 삭제되지도 않습니다.

파일과 사용량

upload(path, content, mode=None)는 절대 경로에 파일을 쓰고 크기를 반환합니다. download(path)는 바이트를, download_text(path) / downloadText(path)는 문자열을 반환합니다. 한 번의 전송은 5 MB로 제한됩니다.

usage()는 실행 초, 사용한 CPU 초, 송신 바이트, 시간당 가격, billed_usd, estimated_total_usd를 반환합니다. tariffs()는 키가 필요 없는 일반 함수로 현재 가격과 한도를 반환합니다. 과금 규칙은 샌드박스 한도와 과금에 있습니다.

오류

모든 API 오류는 EqvpsError의 하위 클래스이며 status(HTTP), code(고정 문자열), body를 가집니다. 서버가 보내면 retry_after / retryAfter가 채워집니다.

클래스HTTP대표 code할 일
AuthenticationError401unauthenticated토큰 확인
InsufficientBalanceError402insufficient_balance잔액 충전
NotFoundError404not_foundid가 틀렸거나 파일이 없음
SandboxPausedError409sandbox_paused잔액이 떨어져 일시 중지됨, 충전하면 재개
SandboxDeletedError410sandbox_deleted영구 삭제됨
FileTooLargeError413file_too_large전송을 5 MB 미만으로 유지
ValidationError422invalid_request매개변수 수정
RateLimitError429too_many_concurrent, too_many_tasks, rate_limited기다렸다가 재시도
BudgetExceededError429budget_exceeded샌드박스 일일 또는 월간 지출 한도에 도달
CapacityError503capacity잠시 후 재시도하거나 더 작은 요금제 선택
SandboxTimeoutError—request_timeout, wait_timeout명령이 아니라 HTTP 요청(또는 wait)이 시간 초과됨

429의 대부분은 두 가지 한도에서 옵니다. 한 계정은 동시에 2개의 명령을 실행하고 최대 20개의 샌드박스를 보유할 수 있습니다. 서버가 대기 시간을 알려 주면 SDK가 재시도하고, 세 번 실패하면 예외가 발생합니다.

SDK가 필요 없을 때

HTTP 클라이언트가 있는 언어라면 어떤 언어로든 API를 직접 호출할 수 있습니다. 엔드포인트는 https://eqvps.com/openapi.json의 OpenAPI 파일에 있습니다. Claude, Cursor 등 MCP 클라이언트에서 동작하는 에이전트는 코드조차 필요 없습니다. MCP 서버에 같은 샌드박스 도구가 있습니다. 동작하는 모습만 보고 싶다면 샌드박스 페이지에 요금제와 신규 계정용 $1 체험이 있습니다.

자주 묻는 질문

SDK는 어떤 Python과 Node.js 버전을 지원하나요?

Python 패키지는 Python 3.8 이상이 필요하고 의존성이 없습니다. TypeScript 패키지도 의존성이 없으며 Node.js 18+, Deno, Bun, 그리고 fetch를 지원하는 브라우저에서 동작합니다.

SDK는 API 키를 어디서 가져오나요?

api_key / apiKey 인수나 EQVPS_API_KEY 환경 변수에서 가져옵니다. 키는 일반 EQVPS 계정 토큰입니다. EQVPS_API_URL은 API 주소를 바꾸는 용도로, 테스트할 때만 필요합니다.

SDK가 실패한 요청을 재시도하나요?

서버가 Retry-After를 보내면 429와 503을 최대 3번 재시도하고, 매번 최대 30초를 기다립니다. 이 상태는 아무것도 실행되기 전에 요청이 거부되었다는 뜻이라 run과 exec를 재시도해도 안전합니다. 네트워크 오류는 GET만 재시도하며, run, exec, upload는 절대 두 번 보내지 않습니다.

0이 아닌 종료 코드는 예외인가요?

아닙니다. run과 exec는 exit_code, stdout, stderr를 담은 결과를 반환합니다. result.ok나 result.exit_code를 확인하세요. 예외는 잔액 부족이나 잘못된 토큰 같은 API 오류에서만 발생합니다.

코드가 비정상 종료돼도 샌드박스가 삭제되게 하려면?

범위가 있는 형태를 쓰세요. Python은 with Sandbox.create() as sb, TypeScript는 Sandbox.with(options, fn) 또는 await using입니다. 블록이 끝나면 예외가 난 뒤에도 샌드박스가 삭제됩니다.

댓글

아직 댓글이 없습니다. 첫 번째가 되세요.

댓글 남기기

댓글은 표시되기 전에 검토됩니다.