−25%

Windows รายปี ถึง 31 ต.ค. ดูแพ็กเกจ

EQVPS
เริ่มต้นใช้งาน

TypeScript SDK สำหรับแซนด์บ็อกซ์ใน 5 นาที: จาก npm i @eqvps/sdk ถึงการรันครั้งแรก

ติดตั้ง @eqvps/sdk เปิดแซนด์บ็อกซ์ Firecracker จาก Node.js, Deno หรือ Bun รันโค้ด Python, Node และ shell ในนั้น ย้ายไฟล์ และดูเอาต์พุตของงานยาวแบบสด หกขั้นตอนพร้อมโค้ดทุกบรรทัด

คู่มือนี้รันแซนด์บ็อกซ์จาก JavaScript หรือ TypeScript คุณจะเปิด microVM ของ Firecracker ที่แยกขาด รันโค้ดสามภาษา ย้ายไฟล์ และติดตามเอาต์พุตของงานที่ใช้เวลานาน แต่ละขั้นตอนเป็นโค้ดสั้น ๆ

คุณต้องมี Node.js 18+ (หรือ Deno หรือ Bun) และบัญชี EQVPS

1. รับโทเค็น

SDK ยืนยันตัวตนด้วยโทเค็นบัญชีธรรมดา วิธีรับโทเค็นจากแดชบอร์ด, API หรือเซิร์ฟเวอร์ MCP อยู่ในหน้า เชื่อมต่อบัญชี

export EQVPS_API_KEY="your-token"

บัญชีใหม่ที่ไม่มียอดคงเหลือจะได้เครดิตแซนด์บ็อกซ์ $1 เมื่อสร้างแซนด์บ็อกซ์ครั้งแรก ซึ่งพอสำหรับคู่มือนี้หลายรอบ

2. ติดตั้ง SDK

npm i @eqvps/sdk

ตัวอย่างใช้ ES module และ await ระดับบนสุด บันทึกเป็นไฟล์ .mjs หรือเป็น .ts แล้วรันด้วย npx tsx

3. เปิดแซนด์บ็อกซ์และรันโค้ด

import { Sandbox } from "@eqvps/sdk";

await Sandbox.with({ tariff: "small" }, async (sb) => {
  console.log(sb.id);
  const r = await sb.run("import platform; print(platform.python_version())");
  console.log(r.exit_code, r.stdout);
});

เอาต์พุตคือ id ของแซนด์บ็อกซ์ (sb_ ตามด้วยอักขระอีก 24 ตัว) แล้วตามด้วย 0 3.12.x Sandbox.with ลบแซนด์บ็อกซ์เมื่อ callback ทำงานเสร็จ แม้ callback จะโยนข้อผิดพลาด

ภาษาเริ่มต้นคือ Python อีกสองภาษาห่างไปแค่ตัวเลือกเดียว:

await Sandbox.with({}, async (sb) => {
  const js = await sb.run("console.log(process.version)", { language: "node" });
  const sh = await sb.run("uname -r && nproc", { language: "bash" });
  console.log(js.stdout, sh.stdout);
});

สคริปต์ที่ล้มเหลวจะไม่โยนอะไรออกมา ให้ตรวจ r.ok ซึ่งเป็น true เมื่อ exit_code เป็น 0 และคำสั่งไม่ถึง timeout

4. คำสั่ง shell และแพ็กเกจ

exec รับสตริง shell หรืออาร์เรย์ argv แซนด์บ็อกซ์เข้าถึงอินเทอร์เน็ตได้ การติดตั้งด้วย npm และ pip จึงใช้ได้:

await Sandbox.with({ tariff: "small" }, async (sb) => {
  await sb.exec("mkdir -p /root/app && cd /root/app && npm init -y && npm i lodash", { timeout: 55 });
  const r = await sb.exec(["node", "-e", "console.log(require('/root/app/node_modules/lodash').VERSION)"]);
  console.log(r.stdout);
});

การเรียกแบบ synchronous ทำงานได้นานสุด 55 วินาที อะไรที่นานกว่านั้นให้ไปอยู่ในงานเบื้องหลัง (ขั้นตอนที่ 6)

5. ไฟล์

await Sandbox.with({}, async (sb) => {
  await sb.upload("/root/input.json", JSON.stringify({ values: [3, 5, 8] }));
  await sb.run("import json; d = json.load(open('/root/input.json')); open('/root/out.txt', 'w').write(str(sum(d['values'])))");
  console.log(await sb.downloadText("/root/out.txt"));   // 16
});

upload รับสตริงหรือ Uint8Array ส่วน download คืนค่าเป็น Uint8Array และ downloadText คืนค่าเป็นสตริง การโอนแต่ละครั้งจำกัดที่ 5 MB

6. งานยาวพร้อมเอาต์พุตสด

await Sandbox.with({ tariff: "standard" }, async (sb) => {
  const task = await sb.exec("for i in 1 2 3 4 5; do echo step $i; sleep 20; done", { background: true });
  const res = await task.wait({ onOutput: (out) => process.stdout.write(out) });
  console.log(res.state, res.exit_code);   // done 0
});

งานจะคืนค่าทันทีและไม่มีขีดจำกัด 55 วินาที wait ตรวจทุก 2 วินาทีโดยค่าเริ่มต้น (เปลี่ยนได้ด้วย pollIntervalMs) task.kill() หยุดงาน ส่วน sb.task(id) เชื่อมต่อกลับจากโปรเซสอื่นได้

ข้อผิดพลาด

import { Sandbox, InsufficientBalanceError, RateLimitError } from "@eqvps/sdk";

try {
  await Sandbox.with({}, async (sb) => console.log((await sb.run("print(1)")).stdout));
} catch (e) {
  if (e instanceof InsufficientBalanceError) console.log("Top up the balance");
  else if (e instanceof RateLimitError) console.log("Busy, retry in", e.retryAfter);
  else throw e;
}

SDK จะลอง 429 และ 503 ซ้ำเองสูงสุดสามครั้งเมื่อเซิร์ฟเวอร์ส่ง Retry-After มา 429 ที่พบบ่อยที่สุดเกิดจากการรันคำสั่งพร้อมกันเกินสองคำสั่งในบัญชีเดียว คลาสทั้งหมดอยู่ใน คู่มือ SDK

ค่าใช้จ่ายของคู่มือนี้

แต่ละตัวอย่างมีอายุไม่กี่วินาทีและถูกคิดเงินขั้นต่ำ 60 วินาที: $0.00055 บน small และ $0.0011 บน standard งานในขั้นตอนที่ 6 รันราว 100 วินาทีบน standard ประมาณ $0.002 รวมทั้งหมดยังต่ำกว่าหนึ่งเซนต์มาก รายการราคาทั้งหมดอยู่ใน ขีดจำกัดและการคิดเงินของ sandbox

ขั้นต่อไป

คำถามที่พบบ่อย

@eqvps/sdk รองรับรันไทม์อะไรบ้าง

Node.js 18 ขึ้นไป, Deno และ Bun ไม่มี dependency และใช้ fetch ในตัว จึงรันในเบราว์เซอร์ได้ด้วย แต่อย่าใส่โทเค็นบัญชีไว้ในโค้ดฝั่ง frontend

ถ้าแอปของฉันเขียนด้วย TypeScript แซนด์บ็อกซ์รัน Python ได้ไหม

ได้ ภาษาของแอปกับภาษาของโค้ดในแซนด์บ็อกซ์ไม่เกี่ยวกัน run รับค่า language เป็น python, node หรือ bash และ exec รันคำสั่ง shell อะไรก็ได้

จะแน่ใจได้อย่างไรว่าแซนด์บ็อกซ์ถูกลบ

ใช้ Sandbox.with(options, fn) ซึ่งลบแซนด์บ็อกซ์เมื่อ fn ทำงานเสร็จหรือโยนข้อผิดพลาด ใน TypeScript 5.2 ขึ้นไปยังเขียน await using sb = await Sandbox.create() ได้ด้วย

run คืนค่าอะไรเมื่อโค้ดล้มเหลว

ExecResult ที่มี exit_code ไม่ใช่ศูนย์และมีข้อผิดพลาดใน stderr ไม่มีการโยน exception โดย exception มีเฉพาะข้อผิดพลาดของ API เช่น โทเค็นไม่ถูกต้องหรือยอดคงเหลือเป็นศูนย์

ความคิดเห็น

ยังไม่มีความคิดเห็น เป็นคนแรกสิ

แสดงความคิดเห็น

ความคิดเห็นจะถูกตรวจสอบก่อนแสดง