SDK to cienka warstwa nad REST API sandboxów. Oszczędza trzech rzeczy: ręcznego składania żądań, ponawiania ich, gdy platforma jest zajęta, i zapominania o usunięciu sandboxa, gdy kod rzuci wyjątek. Wszystko poniżej odpowiada wersji 0.2.0 obu pakietów.
Jeśli nigdy nie tworzyłeś sandboxa, przewodnik po połączeniu w 5 minut najpierw da ci token. Czym jest sandbox i co ma w środku, wyjaśnia strona Sandboxy.
Instalacja i konfiguracja
pip install eqvps # Python 3.8+
npm i @eqvps/sdk # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=... # your EQVPS account token
Ten sam program w obu językach: utwórz sandbox, uruchom kod, usuń go.
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
});
Tworzenie i wyszukiwanie sandboxów
Sandbox.create(...) uruchamia sandbox, zwykle w około sekundę. Python przyjmuje argumenty nazwane, TypeScript jeden obiekt opcji.
| Python | TypeScript | Domyślnie | Znaczenie |
|---|---|---|---|
mode | mode | "ephemeral" | "ephemeral" (za sekundę) lub "persistent" (za rozpoczętą godzinę, zachowuje dysk) |
tariff | tariff | "small" | micro, small, standard, plus, pro, max |
idle_timeout | idleTimeout | 300 | sekundy bez aktywności przed usunięciem efemerycznego sandboxa, do 3600 |
ttl | ttl | — | maksymalny czas życia w sekundach: do 86400 dla efemerycznego, 2592000 dla trwałego |
env | env | — | zmienne środowiskowe dla każdego polecenia, przechowywane w postaci zaszyfrowanej |
api_key, base_url | apiKey, baseUrl | zmienne środowiskowe | nadpisują EQVPS_API_KEY / EQVPS_API_URL |
timeout | timeoutMs | 70 s | limit czasu HTTP na żądanie |
max_retries | maxRetries | 3 | ponowienia przy 429/503 |
Sandbox.connect(id) podłącza się do istniejącego sandboxa, zwykle trwałego, utworzonego wczoraj. Sandbox.list() zwraca wszystkie sandboxy konta, działające i wstrzymane.
Właściwości: id (sb_ + 24 znaki szesnastkowe), mode, tariff, state (running, starting, paused, pausing, resuming, deleting, deleted), env_keys / envKeys (same nazwy, wartości nigdy nie wracają) i info (surowy obiekt). refresh() je odświeża.
kill() usuwa sandbox i zatrzymuje naliczanie. Wywołanie dla już usuniętego sandboxa nie jest błędem.
Uruchamianie kodu
run(code, language="python", timeout=30) przekazuje kod przez stdin do Pythona 3.12, Node.js 22 albo bash ("python", "node", "bash"). exec(command, cwd=None, stdin=None, timeout=30) wykonuje polecenie powłoki: napis idzie przez bash -lc, lista jest wykonywana jako argv bez powłoki.
Obie zwracają ExecResult:
| Pole | Znaczenie |
|---|---|
exit_code | kod wyjścia procesu |
stdout, stderr | wyjście, do 1 MiB na strumień |
timed_out | polecenie przekroczyło limit czasu |
truncated | wyjście zostało ucięte |
duration_ms | czas wykonania |
ok | exit_code == 0 i bez przekroczenia czasu |
Wywołanie synchroniczne trwa najwyżej 55 sekund. Obie metody przyjmują też env na jedno wywołanie; nadpisuje ono wartości ustawione przy tworzeniu.
Długie zadania: tryb w tle
Przekaż background=True (w TypeScripcie { background: true }), a od razu dostaniesz Task. Nie ma limitu 55 sekund i może działać do końca życia sandboxa. Do 8 zadań na 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) });
| Metoda | Co robi |
|---|---|
task.logs() | nowe stdout i stderr od poprzedniego wywołania |
task.status() | stan bez zużywania wyjścia: running, done, failed, killed, timeout |
task.wait(timeout, poll_interval=2, on_output) | odpytuje do zakończenia, zwraca TaskResult |
task.kill() | zatrzymuje zadanie i jego procesy |
sb.task(id) / sb.tasks() | ponowne podłączenie do zadania / lista zadań |
Jeśli wait przekroczy własny limit czasu, rzuca SandboxTimeoutError, ale zadanie działa dalej. Działające zadanie nie pozwala też usunąć efemerycznego sandboxa z powodu bezczynności.
Pliki i zużycie
upload(path, content, mode=None) zapisuje plik pod ścieżką bezwzględną i zwraca jego rozmiar. download(path) zwraca bajty, download_text(path) / downloadText(path) napis. Jeden transfer to maksymalnie 5 MB.
usage() zwraca sekundy działania, zużyte sekundy CPU, bajty wychodzące, cenę za godzinę, billed_usd i estimated_total_usd. tariffs() to zwykła funkcja bez klucza, zwraca aktualne ceny i limity. Zasady naliczania opisuje strona Limity i rozliczenia sandboxów.
Błędy
Każdy błąd API to podklasa EqvpsError z polami status (HTTP), code (stały napis) i body. retry_after / retryAfter jest ustawione, gdy serwer je przyśle.
| Klasa | HTTP | Typowy code | Co zrobić |
|---|---|---|---|
AuthenticationError | 401 | unauthenticated | sprawdzić token |
InsufficientBalanceError | 402 | insufficient_balance | doładować saldo |
NotFoundError | 404 | not_found | złe id albo plik nie istnieje |
SandboxPausedError | 409 | sandbox_paused | wstrzymany po wyczerpaniu salda; wznowi się po doładowaniu |
SandboxDeletedError | 410 | sandbox_deleted | usunięty na stałe |
FileTooLargeError | 413 | file_too_large | trzymać transfery poniżej 5 MB |
ValidationError | 422 | invalid_request | poprawić parametry |
RateLimitError | 429 | too_many_concurrent, too_many_tasks, rate_limited | poczekać i ponowić |
BudgetExceededError | 429 | budget_exceeded | osiągnięto dzienny lub miesięczny limit wydatków na sandboxy |
CapacityError | 503 | capacity | spróbować za chwilę albo wybrać mniejszą taryfę |
SandboxTimeoutError | — | request_timeout, wait_timeout | minął czas żądania HTTP (lub wait), a nie polecenia |
Większość 429 wywołują dwa limity: konto wykonuje 2 polecenia jednocześnie i trzyma do 20 sandboxów. SDK ponawia takie żądania, gdy serwer poda, ile czekać; po trzech próbach dostaniesz wyjątek.
Kiedy SDK jest zbędne
Każdy język z klientem HTTP może wywoływać API bezpośrednio; endpointy są opisane w pliku OpenAPI pod adresem https://eqvps.com/openapi.json. Agenci w Claude, Cursor i innych klientach MCP nie potrzebują żadnego kodu: serwer MCP ma te same narzędzia sandboxów. A jeśli chcesz tylko zobaczyć, jak to działa, na stronie sandboxów są taryfy i próbny $1 dla nowych kont.
Komentarze
Brak komentarzy. Bądź pierwszy.