SDK-ul e un strat subțire peste REST API-ul sandboxurilor. Te scutește de trei lucruri: construirea manuală a cererilor, reîncercarea când platforma e ocupată și uitarea ștergerii unui sandbox când codul tău aruncă o excepție. Tot ce e aici corespunde versiunii 0.2.0 a ambelor pachete.
Dacă n-ai creat niciodată un sandbox, ghidul de conectare în 5 minute îți dă întâi un token. Ce e un sandbox și ce conține e acoperit în Sandboxuri.
Instalare și configurare
pip install eqvps # Python 3.8+
npm i @eqvps/sdk # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=... # your EQVPS account token
Același program în ambele limbaje: creează un sandbox, rulează cod, șterge-l.
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
});
Crearea și găsirea sandboxurilor
Sandbox.create(...) pornește un sandbox, de obicei în aproximativ o secundă. Python primește argumente cu nume, TypeScript un singur obiect de opțiuni.
| Python | TypeScript | Implicit | Înseamnă |
|---|---|---|---|
mode | mode | "ephemeral" | "ephemeral" (la secundă) sau "persistent" (pe oră începută, își păstrează discul) |
tariff | tariff | "small" | micro, small, standard, plus, pro, max |
idle_timeout | idleTimeout | 300 | secunde fără activitate înainte ca un sandbox efemer să fie șters, până la 3600 |
ttl | ttl | — | durata maximă de viață în secunde: până la 86400 pentru efemere, 2592000 pentru persistente |
env | env | — | variabile de mediu pentru fiecare comandă, stocate criptat |
api_key, base_url | apiKey, baseUrl | variabilele de mediu | suprascriu EQVPS_API_KEY / EQVPS_API_URL |
timeout | timeoutMs | 70 s | timeoutul HTTP pe cerere |
max_retries | maxRetries | 3 | reîncercări la 429/503 |
Sandbox.connect(id) se atașează la un sandbox existent, de obicei unul persistent creat ieri. Sandbox.list() returnează toate sandboxurile contului, care rulează și puse pe pauză.
Proprietăți: id (sb_ + 24 de caractere hex), mode, tariff, state (running, starting, paused, pausing, resuming, deleting, deleted), env_keys / envKeys (doar numele, valorile nu se întorc niciodată) și info (obiectul brut). refresh() le reîncarcă.
kill() șterge sandboxul și oprește facturarea. Apelarea lui pe un sandbox care nu mai există nu e o eroare.
Rularea codului
run(code, language="python", timeout=30) trimite codul pe stdin către Python 3.12, Node.js 22 sau bash ("python", "node", "bash"). exec(command, cwd=None, stdin=None, timeout=30) rulează o comandă de shell: un șir trece prin bash -lc, o listă e executată ca argv, fără shell.
Amândouă returnează un ExecResult:
| Câmp | Înseamnă |
|---|---|
exit_code | codul de ieșire al procesului |
stdout, stderr | ieșirea, până la 1 MiB pe flux |
timed_out | comanda a atins timeoutul |
truncated | ieșirea a fost tăiată |
duration_ms | cât a rulat |
ok | exit_code == 0 și fără timeout |
Un apel sincron poate rula cel mult 55 de secunde. Ambele metode primesc și env pentru acel apel; suprascrie valorile setate la create.
Sarcinile lungi: sarcini de fundal
Trimite background=True (TypeScript: { background: true }) și primești imediat un Task. Nu are limita de 55 de secunde și poate rula până se încheie durata de viață a sandboxului. Până la 8 sarcini pe 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) });
| Metodă | Ce face |
|---|---|
task.logs() | stdout și stderr noi de la apelul anterior |
task.status() | starea, fără a consuma ieșirea: running, done, failed, killed, timeout |
task.wait(timeout, poll_interval=2, on_output) | interoghează până se încheie sarcina, returnează TaskResult |
task.kill() | oprește sarcina și procesele ei |
sb.task(id) / sb.tasks() | reatașare la o sarcină / listarea sarcinilor |
Dacă wait își atinge propriul timeout, aruncă SandboxTimeoutError, dar sarcina rulează mai departe. O sarcină care rulează împiedică și ștergerea unui sandbox efemer pentru inactivitate.
Fișiere și consum
upload(path, content, mode=None) scrie un fișier la o cale absolută și îi returnează mărimea. download(path) returnează octeți, download_text(path) / downloadText(path) un șir. Un transfer e limitat la 5 MB.
usage() returnează secundele de rulare, secundele de CPU folosite, octeții trimiși spre exterior, prețul pe oră, billed_usd și estimated_total_usd. tariffs() e o funcție simplă care nu are nevoie de cheie și returnează prețurile și limitele curente. Regulile de facturare sunt în Limitele și facturarea sandboxurilor.
Erori
Fiecare eroare API e o subclasă a EqvpsError, cu status (HTTP), code (șir stabil) și body. retry_after / retryAfter e setat când serverul îl trimite.
| Clasă | HTTP | code tipic | Ce faci |
|---|---|---|---|
AuthenticationError | 401 | unauthenticated | verifică tokenul |
InsufficientBalanceError | 402 | insufficient_balance | alimentează soldul |
NotFoundError | 404 | not_found | id greșit sau un fișier care nu există |
SandboxPausedError | 409 | sandbox_paused | pus pe pauză după ce s-a terminat soldul; își reia activitatea după alimentare |
SandboxDeletedError | 410 | sandbox_deleted | dispărut definitiv |
FileTooLargeError | 413 | file_too_large | ține transferurile sub 5 MB |
ValidationError | 422 | invalid_request | corectează parametrii |
RateLimitError | 429 | too_many_concurrent, too_many_tasks, rate_limited | așteaptă și reîncearcă |
BudgetExceededError | 429 | budget_exceeded | ai atins limita zilnică sau lunară pentru sandboxuri |
CapacityError | 503 | capacity | încearcă din nou în curând sau alege un tarif mai mic |
SandboxTimeoutError | — | request_timeout, wait_timeout | a expirat cererea HTTP (sau wait), nu comanda |
Două limite cauzează cele mai multe 429: un cont rulează 2 comenzi în același timp și ține până la 20 de sandboxuri. SDK-ul le reîncearcă atunci când serverul spune cât să aștepte; după trei încercări primești excepția.
Când te poți lipsi de SDK
Orice limbaj cu un client HTTP poate apela direct API-ul; endpointurile sunt în fișierul OpenAPI de la https://eqvps.com/openapi.json. Agenții din Claude, Cursor sau alți clienți MCP nu au nevoie deloc de cod: serverul MCP are aceleași unelte pentru sandboxuri. Iar dacă vrei doar să-l vezi funcționând, pagina sandboxurilor listează tarifele și proba de $1 pentru conturile noi.
Comentarii
Încă nu există comentarii. Fii primul.