−25%

στα Windows με ετήσια χρέωση, έως 31/10. Δείτε τα πακέτα

EQVPS
Ξεκινήστε

TypeScript SDK για sandboxes σε 5 λεπτά: από το npm i @eqvps/sdk στην πρώτη εκτέλεση

Εγκαταστήστε το @eqvps/sdk, ξεκινήστε ένα sandbox Firecracker από Node.js, Deno ή Bun, εκτελέστε μέσα του κώδικα Python, Node και shell, μεταφέρετε αρχεία και παρακολουθήστε ζωντανά μια μεγάλη εργασία. Έξι βήματα με κάθε γραμμή κώδικα.

Αυτός ο οδηγός βάζει σε λειτουργία ένα sandbox από JavaScript ή TypeScript. Θα ξεκινήσετε ένα απομονωμένο microVM Firecracker, θα τρέξετε κώδικα σε τρεις γλώσσες, θα μεταφέρετε αρχεία και θα παρακολουθήσετε την έξοδο μιας μεγάλης εργασίας. Κάθε βήμα είναι ένα σύντομο απόσπασμα.

Χρειάζεστε Node.js 18+ (ή Deno, ή Bun) και λογαριασμό EQVPS.

1. Αποκτήστε token

Το SDK πιστοποιείται με ένα συνηθισμένο token λογαριασμού. Η σελίδα σύνδεση λογαριασμού δείχνει πώς να το πάρετε από τον πίνακα ελέγχου, το API ή τον server MCP.

export EQVPS_API_KEY="your-token"

Ένας νέος λογαριασμός χωρίς υπόλοιπο παίρνει πίστωση 1 $ για sandboxes την πρώτη φορά που δημιουργεί sandbox. Αυτή καλύπτει τον οδηγό πολλές φορές.

2. Εγκαταστήστε το SDK

npm i @eqvps/sdk

Τα παραδείγματα χρησιμοποιούν ES modules και await στο ανώτερο επίπεδο. Αποθηκεύστε τα ως αρχεία .mjs ή ως .ts και τρέξτε τα με npx tsx.

3. Ξεκινήστε ένα sandbox και εκτελέστε κώδικα

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 του sandbox (sb_ και άλλοι 24 χαρακτήρες), μετά 0 3.12.x. Το Sandbox.with διαγράφει το sandbox όταν τελειώσει το 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);
});

Ένα script που αποτυγχάνει δεν πετά τίποτα. Ελέγξτε το r.ok, που είναι true όταν το exit_code είναι 0 και η εντολή δεν έφτασε το χρονικό της όριο.

4. Εντολές shell και πακέτα

Το exec δέχεται συμβολοσειρά shell ή πίνακα argv. Το sandbox έχει πρόσβαση στο διαδίκτυο, οπότε οι εγκαταστάσεις με 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);
});

Μια σύγχρονη κλήση διαρκεί το πολύ 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, έως τρεις φορές, όταν ο server στέλνει Retry-After. Το πιο συχνό 429 προκύπτει όταν τρέχουν περισσότερες από δύο εντολές ταυτόχρονα σε έναν λογαριασμό. Κάθε κλάση βρίσκεται στην αναφορά του SDK.

Κόστος του οδηγού

Κάθε παράδειγμα έζησε λίγα δευτερόλεπτα και χρεώθηκε το ελάχιστο των 60 δευτερολέπτων: 0,00055 $ στο small, 0,0011 $ στο standard. Η εργασία του βήματος 6 έτρεξε περίπου 100 δευτερόλεπτα στο standard, περίπου 0,002 $. Όλα μαζί μένουν πολύ κάτω από ένα σεντ. Ο πλήρης τιμοκατάλογος είναι στα όρια και χρέωση sandboxes.

Επόμενα βήματα

Συχνές ερωτήσεις

Ποια runtimes υποστηρίζει το @eqvps/sdk;

Node.js 18 και νεότερο, Deno και Bun. Δεν έχει εξαρτήσεις και χρησιμοποιεί το ενσωματωμένο fetch, οπότε τρέχει και σε browser, αλλά μη βάζετε το token του λογαριασμού σας σε κώδικα frontend.

Μπορεί το sandbox να τρέξει Python αν η εφαρμογή μου είναι σε TypeScript;

Ναι. Η γλώσσα της εφαρμογής σας και η γλώσσα του κώδικα στο sandbox είναι ανεξάρτητες. Το run δέχεται language python, node ή bash, και το exec τρέχει οποιαδήποτε εντολή shell.

Πώς είμαι σίγουρος ότι το sandbox θα διαγραφεί;

Χρησιμοποιήστε το Sandbox.with(options, fn), που διαγράφει το sandbox όταν το fn τελειώσει ή πετάξει σφάλμα. Με TypeScript 5.2 ή νεότερο μπορείτε επίσης να γράψετε await using sb = await Sandbox.create().

Τι επιστρέφει το run όταν ο κώδικας αποτυγχάνει;

Ένα ExecResult με μη μηδενικό exit_code και το σφάλμα στο stderr. Δεν πετιέται τίποτα. Τα exceptions είναι μόνο για σφάλματα API, όπως άκυρο token ή μηδενικό υπόλοιπο.

Σχόλια

Δεν υπάρχουν ακόμη σχόλια. Γίνετε ο πρώτος.

Αφήστε ένα σχόλιο

Τα σχόλια ελέγχονται πριν εμφανιστούν.