คู่มือนี้รันแซนด์บ็อกซ์จาก 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
ขั้นต่อไป
- แบบเดียวกันด้วย Python: Python SDK สำหรับแซนด์บ็อกซ์ใน 5 นาที
- เชื่อมต่อโมเดลแล้วให้มันรันโค้ดของตัวเอง: งานแรกของเอเจนต์ในแซนด์บ็อกซ์
- แพ็กเกจและการทดลอง $1: หน้าแซนด์บ็อกซ์
ความคิดเห็น
ยังไม่มีความคิดเห็น เป็นคนแรกสิ