이 가이드는 아무것도 없는 상태에서 Python으로 동작하는 샌드박스까지 안내합니다. 격리된 Firecracker microVM을 띄우고, 그 안에서 코드를 실행하고, 패키지를 설치하고, 파일을 넣고 빼고, 오래 걸리는 작업을 백그라운드로 돌립니다. 각 단계는 붙여 넣기만 하면 되는 몇 줄입니다.
Python 3.8 이상과 EQVPS 계정이 필요합니다. SDK에는 의존성이 없습니다.
1. 토큰 받기
샌드박스 요금은 계정 잔액에서 나가므로 SDK에는 계정 토큰이 필요합니다. 계정 연결 페이지에 대시보드, API, MCP 서버라는 세 가지 발급 방법이 나와 있습니다. 받은 토큰은 환경 변수에 넣습니다.
export EQVPS_API_KEY="your-token"
아직 잔액이 없나요? 괜찮습니다. 새 계정이 잔액이 부족한 상태에서 처음 샌드박스를 만들면 14일간 유효한 1달러 샌드박스 크레딧을 받습니다.
2. SDK 설치
pip install eqvps
3. 샌드박스를 띄우고 코드 실행
아래 내용을 hello.py로 저장하고 실행합니다.
from eqvps import Sandbox
with Sandbox.create(tariff="small") as sb:
print(sb.id)
r = sb.run("import platform; print(platform.python_version())")
print(r.exit_code, r.stdout)
샌드박스 id(sb_와 24자)에 이어 0 3.12.x가 출력됩니다. 샌드박스는 약 1초 만에 시작되어 코드를 실행했고, with 블록이 끝나자 삭제되었습니다.
결과에 대해 알아 둘 점:
- 종료 코드가 0이고 타임아웃에 걸리지 않았을 때
r.ok가 true입니다. - 0이 아닌 종료 코드는 예외가 아닙니다. 그러니
r.ok를 직접 확인하세요. stdout과stderr는 각각 1 MiB까지이며, 출력이 잘렸는지는r.truncated로 알 수 있습니다.
4. 패키지 설치와 셸 명령 실행
샌드박스 안에서 여러분은 Python, Node.js, git, curl이 들어 있는 작은 Linux 시스템의 root입니다. exec는 어떤 셸 명령이든 실행합니다.
from eqvps import Sandbox
with Sandbox.create(tariff="small") as sb:
sb.exec("pip install --quiet requests", timeout=55)
r = sb.run("import requests; print(requests.get('https://example.com').status_code)")
print(r.stdout) # 200
기본 타임아웃은 30초이고, 동기 호출은 최대 55초까지입니다. 큰 설치는 백그라운드 작업으로 돌리세요(6단계).
5. 파일 넣고 빼기
from eqvps import Sandbox
with Sandbox.create() as sb:
sb.upload("/root/data.csv", "a,b\n1,2\n3,4\n")
sb.run("""
import csv
rows = list(csv.DictReader(open('/root/data.csv')))
open('/root/sum.txt', 'w').write(str(sum(int(r['b']) for r in rows)))
""")
print(sb.download_text("/root/sum.txt")) # 6
경로는 절대 경로여야 합니다. 한 번 전송할 수 있는 크기는 5 MB까지이며, download는 바이트를, download_text는 문자열을 반환합니다.
6. 긴 작업을 백그라운드로 실행
background=True를 넘기면 기다리지 않고 바로 작업 객체를 받습니다. 55초 제한도 없습니다.
from eqvps import Sandbox
with Sandbox.create(tariff="standard") as sb:
task = sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", background=True)
result = task.wait(on_output=lambda out, err: print(out, end=""))
print(result.state, result.exit_code) # done 0
task.wait()는 2초마다 상태를 확인하고 새 출력이 오는 대로 표시합니다. task.logs()를 직접 호출하거나 task.kill()로 멈출 수도 있습니다. 작업이 실행되는 동안에는 활동이 없다는 이유로 샌드박스가 삭제되지 않습니다.
든 비용
위의 각 with 블록은 몇 초만 존재했고 최소 60초로 과금되었습니다. small에서는 블록당 0.00055달러이므로 다섯 예제를 모두 합쳐도 약 3분의 1센트입니다. 모든 요금제의 가격, 영구 모드, 지출 한도는 샌드박스 한도와 과금에 있습니다.
문제가 생기면
API 오류는 잡을 수 있는 예외입니다.
from eqvps import Sandbox, InsufficientBalanceError, RateLimitError
try:
with Sandbox.create() as sb:
print(sb.run("print(1)").stdout)
except InsufficientBalanceError:
print("Top up the balance")
except RateLimitError as e:
print("Too many at once, retry in", e.retry_after)
서버가 대기 시간을 알려 주면 SDK는 429와 503 응답을 최대 3번까지 알아서 재시도합니다. 11가지 오류 클래스는 모두 SDK 레퍼런스에 정리되어 있습니다.
다음 단계
- 같은 단계를 JavaScript로: 5분 만에 시작하는 샌드박스 TypeScript SDK
- AI 모델이 코드를 쓰고 여기서 실행하게 하기: 샌드박스에서 첫 에이전트 작업
- 요금제, 체험 크레딧, 샌드박스 안에 있는 것: 샌드박스 페이지
댓글
아직 댓글이 없습니다. 첫 번째가 되세요.