L'SDK è un sottile strato sopra l'API REST delle sandbox. Ti risparmia tre cose: costruire le richieste a mano, ripeterle quando la piattaforma è occupata e dimenticarti di eliminare una sandbox quando il codice solleva un'eccezione. Tutto ciò che segue corrisponde alla versione 0.2.0 di entrambi i pacchetti.
Se non hai mai creato una sandbox, la guida alla connessione in 5 minuti ti dà prima un token. Che cos'è una sandbox e cosa contiene è spiegato in Sandbox.
Installare e configurare
pip install eqvps # Python 3.8+
npm i @eqvps/sdk # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=... # your EQVPS account token
Lo stesso programma nei due linguaggi: crea una sandbox, esegui codice, eliminala.
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
});
Creare e trovare sandbox
Sandbox.create(...) avvia una sandbox, di solito in circa un secondo. Python accetta argomenti con nome, TypeScript un oggetto di opzioni.
| Python | TypeScript | Predefinito | Significato |
|---|---|---|---|
mode | mode | "ephemeral" | "ephemeral" (al secondo) o "persistent" (per ora iniziata, conserva il disco) |
tariff | tariff | "small" | micro, small, standard, plus, pro, max |
idle_timeout | idleTimeout | 300 | secondi di inattività prima che una sandbox effimera venga eliminata, fino a 3600 |
ttl | ttl | — | durata massima in secondi: fino a 86400 per le effimere, 2592000 per le persistenti |
env | env | — | variabili d'ambiente per ogni comando, salvate cifrate |
api_key, base_url | apiKey, baseUrl | variabili d'ambiente | sostituiscono EQVPS_API_KEY / EQVPS_API_URL |
timeout | timeoutMs | 70 s | timeout HTTP per richiesta |
max_retries | maxRetries | 3 | tentativi su 429/503 |
Sandbox.connect(id) si collega a una sandbox esistente, di solito una persistente creata ieri. Sandbox.list() restituisce tutte le sandbox dell'account, attive e in pausa.
Proprietà: id (sb_ + 24 caratteri esadecimali), mode, tariff, state (running, starting, paused, pausing, resuming, deleting, deleted), env_keys / envKeys (solo i nomi, i valori non tornano mai) e info (l'oggetto grezzo). refresh() li ricarica.
kill() elimina la sandbox e ferma la fatturazione. Chiamarlo su una sandbox già eliminata non è un errore.
Eseguire codice
run(code, language="python", timeout=30) invia il codice su stdin a Python 3.12, Node.js 22 o bash ("python", "node", "bash"). exec(command, cwd=None, stdin=None, timeout=30) esegue un comando di shell: una stringa passa per bash -lc, una lista viene eseguita come argv senza shell.
Entrambi restituiscono un ExecResult:
| Campo | Significato |
|---|---|
exit_code | codice di uscita del processo |
stdout, stderr | output, fino a 1 MiB per flusso |
timed_out | il comando ha raggiunto il timeout |
truncated | l'output è stato tagliato |
duration_ms | durata dell'esecuzione |
ok | exit_code == 0 e nessun timeout |
Una chiamata sincrona dura al massimo 55 secondi. Entrambi i metodi accettano anche env per quella sola chiamata; sostituisce i valori impostati alla creazione.
Lavori lunghi: task in background
Passa background=True (TypeScript: { background: true }) e ricevi subito un Task. Non ha il limite di 55 secondi e può durare fino alla fine della vita della sandbox. Fino a 8 task per sandbox.
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) });
| Metodo | Cosa fa |
|---|---|
task.logs() | nuovo stdout e stderr dalla chiamata precedente |
task.status() | stato senza consumare l'output: running, done, failed, killed, timeout |
task.wait(timeout, poll_interval=2, on_output) | interroga finché il task termina, restituisce TaskResult |
task.kill() | ferma il task e i suoi processi |
sb.task(id) / sb.tasks() | ricollegarsi a un task / elencare i task |
Se wait raggiunge il proprio timeout solleva SandboxTimeoutError, ma il task continua. Un task in corso impedisce anche che una sandbox effimera venga eliminata per inattività.
File e consumi
upload(path, content, mode=None) scrive un file in un percorso assoluto e ne restituisce la dimensione. download(path) restituisce byte, download_text(path) / downloadText(path) una stringa. Un trasferimento è limitato a 5 MB.
usage() restituisce i secondi di esecuzione, i secondi di CPU usati, i byte in uscita, il prezzo orario, billed_usd ed estimated_total_usd. tariffs() è una semplice funzione senza chiave che restituisce prezzi e limiti attuali. Le regole di fatturazione sono in Limiti e fatturazione delle sandbox.
Errori
Ogni errore dell'API è una sottoclasse di EqvpsError con status (HTTP), code (stringa stabile) e body. retry_after / retryAfter è valorizzato quando il server lo invia.
| Classe | HTTP | code tipico | Cosa fare |
|---|---|---|---|
AuthenticationError | 401 | unauthenticated | controllare il token |
InsufficientBalanceError | 402 | insufficient_balance | ricaricare il saldo |
NotFoundError | 404 | not_found | id sbagliato o file inesistente |
SandboxPausedError | 409 | sandbox_paused | in pausa perché il saldo è finito; riprende dopo una ricarica |
SandboxDeletedError | 410 | sandbox_deleted | eliminata per sempre |
FileTooLargeError | 413 | file_too_large | tenere i trasferimenti sotto i 5 MB |
ValidationError | 422 | invalid_request | correggere i parametri |
RateLimitError | 429 | too_many_concurrent, too_many_tasks, rate_limited | attendere e riprovare |
BudgetExceededError | 429 | budget_exceeded | raggiunto il limite giornaliero o mensile per le sandbox |
CapacityError | 503 | capacity | riprovare a breve o scegliere una tariffa più piccola |
SandboxTimeoutError | — | request_timeout, wait_timeout | è scaduta la richiesta HTTP (o wait), non il comando |
Due limiti causano la maggior parte dei 429: un account esegue 2 comandi alla volta e tiene fino a 20 sandbox. L'SDK ripete queste richieste quando il server dice quanto aspettare; dopo tre tentativi ricevi l'eccezione.
Quando fare a meno dell'SDK
Qualsiasi linguaggio con un client HTTP può chiamare l'API direttamente; gli endpoint sono nel file OpenAPI su https://eqvps.com/openapi.json. Gli agenti in Claude, Cursor o altri client MCP non hanno bisogno di codice: il server MCP ha gli stessi strumenti per le sandbox. E se vuoi solo vederlo in azione, la pagina delle sandbox mostra le tariffe e la prova da $1 per i nuovi account.
Commenti
Ancora nessun commento. Sii il primo.