−25%

no Windows com pagamento anual, até 31/10. Ver planos

EQVPS
Começar

Referência da API de sandboxes: SDK Python e TypeScript

Todos os métodos do SDK de sandboxes da EQVPS em uma página: parâmetros, valores padrão, retornos e as 11 classes de erro, com o mesmo exemplo em Python e em TypeScript.

Última verificação: 2026-10-10 · SDK 0.2.0 (PyPI eqvps, npm @eqvps/sdk)

O SDK é uma camada fina sobre a API REST de sandboxes. Ele poupa você de três coisas: montar requisições à mão, repeti-las quando a plataforma está ocupada e esquecer de apagar uma sandbox quando o código lança uma exceção. Tudo aqui corresponde à versão 0.2.0 dos dois pacotes.

Se você nunca criou uma sandbox, o guia de conexão em 5 minutos entrega um token primeiro. O que é uma sandbox e o que tem dentro está em Sandboxes.

Instalar e configurar

pip install eqvps          # Python 3.8+
npm i @eqvps/sdk           # Node.js 18+, Deno, Bun
export EQVPS_API_KEY=...   # your EQVPS account token

O mesmo programa nas duas linguagens: criar uma sandbox, rodar código, apagá-la.

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
});

Criar e encontrar sandboxes

Sandbox.create(...) inicia uma sandbox, normalmente em cerca de um segundo. Python recebe argumentos nomeados; TypeScript, um objeto de opções.

PythonTypeScriptPadrãoSignificado
modemode"ephemeral""ephemeral" (por segundo) ou "persistent" (por hora iniciada, mantém o disco)
tarifftariff"small"micro, small, standard, plus, pro, max
idle_timeoutidleTimeout300segundos sem atividade antes de apagar uma sandbox efêmera, até 3600
ttlttl—vida máxima em segundos: até 86400 na efêmera, 2592000 na persistente
envenv—variáveis de ambiente para todos os comandos, guardadas criptografadas
api_key, base_urlapiKey, baseUrlvariáveis de ambientesubstituem EQVPS_API_KEY / EQVPS_API_URL
timeouttimeoutMs70 stempo limite HTTP por requisição
max_retriesmaxRetries3novas tentativas em 429/503

Sandbox.connect(id) se conecta a uma sandbox existente, em geral uma persistente que você criou ontem. Sandbox.list() devolve todas as sandboxes da conta, ativas e pausadas.

Propriedades: id (sb_ + 24 caracteres hexadecimais), mode, tariff, state (running, starting, paused, pausing, resuming, deleting, deleted), env_keys / envKeys (só os nomes; os valores nunca voltam) e info (o objeto bruto). refresh() recarrega tudo.

kill() apaga a sandbox e para a cobrança. Chamar em uma sandbox que já não existe não é erro.

Rodar código

run(code, language="python", timeout=30) manda o código pelo stdin para Python 3.12, Node.js 22 ou bash ("python", "node", "bash"). exec(command, cwd=None, stdin=None, timeout=30) executa um comando de shell: uma string passa por bash -lc, uma lista é executada como argv sem shell.

Os dois devolvem um ExecResult:

CampoSignificado
exit_codecódigo de saída do processo
stdout, stderrsaída, até 1 MiB por fluxo
timed_outo comando estourou o tempo
truncateda saída foi cortada
duration_msquanto tempo levou
okexit_code == 0 e sem estouro de tempo

Uma chamada síncrona roda por no máximo 55 segundos. Os dois métodos também aceitam env só para aquela chamada; ele substitui os valores definidos na criação.

Trabalhos longos: tarefas em segundo plano

Passe background=True (TypeScript: { background: true }) e você recebe uma Task na hora. Ela não tem o limite de 55 segundos e pode rodar até o fim da vida da sandbox. Até 8 tarefas por 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étodoO que faz
task.logs()stdout e stderr novos desde a chamada anterior
task.status()estado sem consumir a saída: running, done, failed, killed, timeout
task.wait(timeout, poll_interval=2, on_output)consulta até a tarefa terminar, devolve TaskResult
task.kill()para a tarefa e seus processos
sb.task(id) / sb.tasks()reconectar a uma tarefa / listar tarefas

Se o wait estourar o próprio tempo, ele lança SandboxTimeoutError, mas a tarefa continua rodando. Uma tarefa em andamento também impede que uma sandbox efêmera seja apagada por inatividade.

Arquivos e consumo

upload(path, content, mode=None) grava um arquivo em um caminho absoluto e devolve o tamanho. download(path) devolve bytes; download_text(path) / downloadText(path), uma string. Uma transferência é limitada a 5 MB.

usage() devolve os segundos em execução, os segundos de CPU usados, os bytes de saída, o preço por hora, billed_usd e estimated_total_usd. tariffs() é uma função simples que não precisa de chave e devolve preços e limites atuais. As regras de cobrança estão em Limites e cobrança de sandboxes.

Erros

Todo erro da API é uma subclasse de EqvpsError com status (HTTP), code (string estável) e body. retry_after / retryAfter vem preenchido quando o servidor o envia.

ClasseHTTPcode típicoO que fazer
AuthenticationError401unauthenticatedconferir o token
InsufficientBalanceError402insufficient_balancerecarregar o saldo
NotFoundError404not_foundid errado ou arquivo inexistente
SandboxPausedError409sandbox_pausedpausada porque o saldo acabou; volta após a recarga
SandboxDeletedError410sandbox_deletedapagada de vez
FileTooLargeError413file_too_largemanter as transferências abaixo de 5 MB
ValidationError422invalid_requestcorrigir os parâmetros
RateLimitError429too_many_concurrent, too_many_tasks, rate_limitedesperar e tentar de novo
BudgetExceededError429budget_exceededo limite diário ou mensal de sandboxes foi atingido
CapacityError503capacitytentar de novo em instantes ou escolher um plano menor
SandboxTimeoutError—request_timeout, wait_timeoutestourou o tempo da requisição HTTP (ou do wait), não do comando

Dois limites causam a maioria dos 429: uma conta executa 2 comandos ao mesmo tempo e mantém até 20 sandboxes. O SDK repete essas requisições quando o servidor diz quanto esperar; depois de três tentativas, você recebe a exceção.

Quando dispensar o SDK

Qualquer linguagem com um cliente HTTP pode chamar a API diretamente; os endpoints estão no arquivo OpenAPI em https://eqvps.com/openapi.json. Agentes no Claude, Cursor ou outros clientes MCP não precisam de código nenhum: o servidor MCP tem as mesmas ferramentas de sandbox. E se você só quer ver funcionando, a página de sandboxes mostra os planos e o teste de $1 para contas novas.

Perguntas frequentes

Quais versões de Python e Node.js o SDK suporta?

O pacote Python precisa do Python 3.8 ou mais recente e não tem dependências. O pacote TypeScript também não tem dependências e roda em Node.js 18+, Deno, Bun e em navegadores com fetch.

De onde o SDK pega minha chave de API?

Do argumento api_key / apiKey ou da variável de ambiente EQVPS_API_KEY. A chave é um token comum de conta EQVPS. EQVPS_API_URL troca o endereço da API; só é preciso para testes.

O SDK tenta de novo as requisições que falham?

Tenta de novo 429 e 503 até 3 vezes quando o servidor manda Retry-After, esperando no máximo 30 segundos de cada vez. Esses status significam que a requisição foi recusada antes de qualquer execução, então repetir run e exec é seguro. Erros de rede só são repetidos em GET; run, exec e upload nunca são enviados duas vezes.

Um código de saída diferente de zero é uma exceção?

Não. run e exec devolvem um resultado com exit_code, stdout e stderr. Confira result.ok ou result.exit_code. Exceções só acontecem em erros da API, como saldo vazio ou token inválido.

Como garantir que a sandbox seja apagada se meu código quebrar?

Use a forma com escopo: with Sandbox.create() as sb em Python, Sandbox.with(options, fn) ou await using em TypeScript. A sandbox é apagada quando o bloco termina, inclusive depois de uma exceção.

Comentários

Nenhum comentário ainda. Seja o primeiro.

Deixe um comentário

Os comentários são moderados antes de aparecerem.