Le SDK est une fine couche au-dessus de l'API REST des sandboxes. Il vous épargne trois choses : construire les requêtes à la main, les relancer quand la plateforme est occupée et oublier de supprimer une sandbox quand votre code lève une exception. Tout ce qui suit correspond à la version 0.2.0 des deux paquets.
Si vous n'avez jamais créé de sandbox, le guide de connexion en 5 minutes vous donne d'abord un jeton. Ce qu'est une sandbox et ce qu'elle contient est expliqué dans Sandboxes.
Installer et configurer
pip install eqvps # Python 3.8+
npm i @eqvps/sdk # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=... # your EQVPS account token
Le même programme dans les deux langages : créer une sandbox, exécuter du code, la supprimer.
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
});
Créer et retrouver des sandboxes
Sandbox.create(...) démarre une sandbox, en général en une seconde environ. Python prend des arguments nommés, TypeScript un objet d'options.
| Python | TypeScript | Défaut | Signification |
|---|---|---|---|
mode | mode | "ephemeral" | "ephemeral" (à la seconde) ou "persistent" (à l'heure entamée, garde son disque) |
tariff | tariff | "small" | micro, small, standard, plus, pro, max |
idle_timeout | idleTimeout | 300 | secondes sans activité avant la suppression d'une sandbox éphémère, jusqu'à 3600 |
ttl | ttl | — | durée de vie maximale en secondes : jusqu'à 86400 en éphémère, 2592000 en persistante |
env | env | — | variables d'environnement pour chaque commande, stockées chiffrées |
api_key, base_url | apiKey, baseUrl | variables d'environnement | remplacent EQVPS_API_KEY / EQVPS_API_URL |
timeout | timeoutMs | 70 s | délai HTTP par requête |
max_retries | maxRetries | 3 | nouvelles tentatives sur 429/503 |
Sandbox.connect(id) se rattache à une sandbox existante, souvent une persistante créée la veille. Sandbox.list() renvoie toutes les sandboxes du compte, actives et en pause.
Propriétés : id (sb_ + 24 caractères hexadécimaux), mode, tariff, state (running, starting, paused, pausing, resuming, deleting, deleted), env_keys / envKeys (les noms seulement, les valeurs ne reviennent jamais) et info (l'objet brut). refresh() les recharge.
kill() supprime la sandbox et arrête la facturation. L'appeler sur une sandbox déjà supprimée n'est pas une erreur.
Exécuter du code
run(code, language="python", timeout=30) envoie le code sur stdin à Python 3.12, Node.js 22 ou bash ("python", "node", "bash"). exec(command, cwd=None, stdin=None, timeout=30) exécute une commande shell : une chaîne passe par bash -lc, une liste est exécutée comme argv sans shell.
Les deux renvoient un ExecResult :
| Champ | Signification |
|---|---|
exit_code | code de sortie du processus |
stdout, stderr | sortie, jusqu'à 1 Mio par flux |
timed_out | la commande a atteint son délai |
truncated | la sortie a été coupée |
duration_ms | durée d'exécution |
ok | exit_code == 0 et pas de dépassement |
Un appel synchrone dure 55 secondes au plus. Les deux méthodes acceptent aussi env pour cet appel seulement ; il remplace les valeurs définies à la création.
Tâches longues : l'arrière-plan
Passez background=True (TypeScript : { background: true }) et vous obtenez tout de suite une Task. Elle n'a pas de limite de 55 secondes et peut tourner jusqu'à la fin de vie de la sandbox. Jusqu'à 8 tâches par 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) });
| Méthode | Ce qu'elle fait |
|---|---|
task.logs() | nouveaux stdout et stderr depuis l'appel précédent |
task.status() | état sans consommer la sortie : running, done, failed, killed, timeout |
task.wait(timeout, poll_interval=2, on_output) | interroge jusqu'à la fin, renvoie TaskResult |
task.kill() | arrête la tâche et ses processus |
sb.task(id) / sb.tasks() | se rattacher à une tâche / lister les tâches |
Si wait atteint son propre délai, il lève SandboxTimeoutError, mais la tâche continue. Une tâche en cours empêche aussi qu'une sandbox éphémère soit supprimée pour inactivité.
Fichiers et consommation
upload(path, content, mode=None) écrit un fichier à un chemin absolu et renvoie sa taille. download(path) renvoie des octets, download_text(path) / downloadText(path) une chaîne. Un transfert est limité à 5 Mo.
usage() renvoie les secondes de fonctionnement, les secondes CPU consommées, les octets sortants, le prix horaire, billed_usd et estimated_total_usd. tariffs() est une simple fonction sans clé qui renvoie les prix et limites actuels. Les règles de facturation sont dans Limites et facturation des sandboxes.
Erreurs
Chaque erreur d'API est une sous-classe de EqvpsError avec status (HTTP), code (chaîne stable) et body. retry_after / retryAfter est renseigné quand le serveur l'envoie.
| Classe | HTTP | code typique | Que faire |
|---|---|---|---|
AuthenticationError | 401 | unauthenticated | vérifier le jeton |
InsufficientBalanceError | 402 | insufficient_balance | recharger le solde |
NotFoundError | 404 | not_found | mauvais id, ou fichier inexistant |
SandboxPausedError | 409 | sandbox_paused | en pause après l'épuisement du solde ; reprend après une recharge |
SandboxDeletedError | 410 | sandbox_deleted | supprimée définitivement |
FileTooLargeError | 413 | file_too_large | garder les transferts sous 5 Mo |
ValidationError | 422 | invalid_request | corriger les paramètres |
RateLimitError | 429 | too_many_concurrent, too_many_tasks, rate_limited | attendre et réessayer |
BudgetExceededError | 429 | budget_exceeded | votre limite quotidienne ou mensuelle pour les sandboxes est atteinte |
CapacityError | 503 | capacity | réessayer sous peu ou choisir un tarif plus petit |
SandboxTimeoutError | — | request_timeout, wait_timeout | la requête HTTP (ou wait) a expiré, pas la commande |
Deux limites provoquent la plupart des 429 : un compte exécute 2 commandes en même temps et garde jusqu'à 20 sandboxes. Le SDK relance ces requêtes quand le serveur indique combien attendre ; après trois essais, vous recevez l'exception.
Quand se passer du SDK
Tout langage doté d'un client HTTP peut appeler l'API directement ; les points d'accès sont décrits dans le fichier OpenAPI à https://eqvps.com/openapi.json. Les agents dans Claude, Cursor ou d'autres clients MCP n'ont besoin d'aucun code : le serveur MCP propose les mêmes outils de sandbox. Et pour simplement voir comment ça marche, la page des sandboxes liste les tarifs et l'essai à $1 pour les nouveaux comptes.
Commentaires
Pas encore de commentaires. Soyez le premier.