Skip to main content
Esta página documenta squarecloud-api 5.0, una reescritura del SDK. ¿Vienes de la v4? Lee la guía de migración v4 → v5.

Requisitos

El paquete no tiene dependencias en tiempo de ejecución (solo la biblioteca estándar: http.client, json, ssl) y está completamente tipado (py.typed): las respuestas son TypedDict que tu editor y tu comprobador de tipos entienden.

Instalación

El paquete se instala como squarecloud-api y se importa como squarecloud. La versión instalada es squarecloud.__version__.

Clave de API y scopes

Crea una clave en squarecloud.app/account/security. El SDK la envía tal cual en el encabezado Authorization (sin el prefijo Bearer). Una clave puede limitarse a scopes (apps:read, apps:deploy, apps:control, ai:chat, …) y a aplicaciones o bases de datos concretas:
  • Una llamada fuera de esos límites lanza un SquareCloudAPIError con 403 MISSING_SCOPE o RESOURCE_NOT_ALLOWED.
  • Los métodos de listado (account.me(), apps.status_all(), …) solo devuelven los recursos que la clave puede ver.
  • Una clave desconocida, revocada o caducada da 401 ACCESS_DENIED.
Mantén la clave fuera de tu código fuente: léela del entorno (os.environ["SQUARECLOUD_API_KEY"]) o de un gestor de secretos.
Los ejemplos leen la clave de la variable de entorno SQUARECLOUD_API_KEY. Defínela en la terminal donde los ejecutes:

Crear el cliente

El SDK tiene dos clientes con los mismos grupos y métodos:
  • SquareCloud es síncrono y thread-safe: comparte una sola instancia entre hilos. Cada hilo reutiliza su propia conexión keep-alive.
  • AsyncSquareCloud es la misma API con await. Cada llamada ejecuta el cliente síncrono en asyncio.to_thread, así que el event loop nunca se bloquea.
Ambos imprimen el nombre de tu cuenta y el número de aplicaciones que la clave puede ver:
Salir del bloque with / async with cierra las conexiones del pool. Sin un bloque, llama a client.close() cuando termines. close() es un método normal (síncrono) en ambos clientes. Una clave vacía o compuesta solo por espacios lanza un ValueError en el constructor, antes de cualquier petición.

El cliente asíncrono

AsyncSquareCloud solo se diferencia de SquareCloud en tres puntos:
  • Todos los métodos devuelven una corrutina: await client.apps.status(app_id).
  • close() es síncrono: llámalo sin await.
  • apps.realtime(app_id) no se espera con await: devuelve un AsyncRealtime que consumes con async for (consulta Tiempo real).
Como cada llamada se ejecuta en un hilo de trabajo, puedes ejecutar llamadas de forma concurrente con asyncio.gather:
Cancelar una tarea en espera no detiene la petición que ya se está ejecutando en su hilo de trabajo: la llamada sigue completándose (o agotando el tiempo) en segundo plano.

Opciones

Las opciones son solo por palabra clave, y AsyncSquareCloud acepta las mismas.
El cliente guarda la clave solo en sus encabezados privados de petición: no hay ningún atributo client.api_key, y el logger del SDK nunca la escribe.

Módulos

El paquete exporta SquareCloud, AsyncSquareCloud, SquareCloudAPIError, BASE_URL, HTTPTransport, los protocolos Transport y Response, Realtime, AsyncRealtime y __version__. Los tipos de respuesta (App, RuntimeStats, Snapshot, …) están en squarecloud.types:

Convenciones

Primero el id, de vuelta datos planos

Todos los métodos reciben el id del recurso como primer argumento y devuelven datos planos: cada respuesta es un TypedDict, que en tiempo de ejecución es un dict normal (sin clases ni caché), así que se conservan los campos que la API añada más adelante. Los nombres de los campos son los de la propia API (created_at, version_id, lastModified, joinedAt, netIO, …), así que la referencia de la API se aplica tal cual.
  • Las mutaciones devuelven None, salvo que la API devuelva datos (envs.*, deploys.set_webhook, deploys.link_github_app, databases.reset_credentials y los métodos create).
  • Un resultado de tipo string nunca es None: es '' cuando la API no envía nada.
  • Las listas llegan completas en una sola llamada: no hay paginación.
  • Los modificadores opcionales son solo por palabra clave (status(app_id, raw=True), commit(app_id, file, path="/src")). La única excepción es el path opcional de files.list, que también puede pasarse por posición.
Los métodos son métodos enlazados normales, así que puedes guardar una referencia a ellos:

Aplicaciones de workspace

Todo app_id acepta también la forma compuesta <appId>-<workspaceId> para actuar sobre una aplicación compartida contigo a través de un workspace. workspaces.get() y workspaces.list() devuelven ids sin procesar; el id compuesto lo construyes tú:

Los ids se codifican

Los ids en la ruta de la URL se codifican con percent-encoding. Un id vacío, . o .. llegaría a otra ruta, así que falla localmente con INVALID_ID (estado 0) antes de enviar nada. Las rutas de workspace envían sus ids en el cuerpo: ahí, el INVALID_ID (400) viene del servidor.

Fechas

Los argumentos start y end (consulta Red) aceptan un string ISO 8601 (enviado tal cual) o un datetime (enviado en UTC). Un datetime naive se trata como hora local y se convierte a UTC, así que es preferible usar uno con zona horaria (datetime.now(UTC)). Las fechas de las respuestas se mantienen tal como las envía la API (strings ISO, o milisegundos Unix donde la API los usa).

Timeouts

timeout limita cada operación de socket: la conexión y cada lectura o escritura. Una respuesta que sigue enviando datos puede tardar más de timeout en total. Un timeout de 0 o menos desactiva todos los timeouts, incluidos los mínimos de 120 s. Las llamadas no se pueden cancelar una vez enviadas: el único stream que puedes detener a mitad es apps.realtime(), con close() desde cualquier hilo. Para una subida larga, mantén el timeout por defecto para que una conexión muerta se detecte al conectar, y ejecútala en un hilo o con AsyncSquareCloud si el resto de tu programa debe seguir funcionando.

Cuenta

client.account.me() devuelve el usuario autenticado junto con las aplicaciones y bases de datos que la clave puede ver.
client.account.snapshots(scope=...) lista todos los snapshots de la cuenta: consulta Snapshots.

Estado de la plataforma

client.service.status() devuelve el estado público de la plataforma. La ruta no necesita una clave válida, pero el cliente sigue exigiendo una que no esté vacía.
unknown significa que la propia comprobación no pudo ejecutarse: no es una prueba de una caída.

Avanzado

Transporte personalizado

transport= reemplaza la capa HTTP. Úsalo para proxies, trazas o tests. Un transporte es cualquier callable con esta firma:
El objeto devuelto necesita status, read(), readline() y close(): un http.client.HTTPResponse cumple los requisitos. Los reintentos, el mapeo de errores y el desempaquetado de {status, response} se quedan en el cliente, así que un transporte solo mueve bytes. HTTPTransport(timeout=30.0) es el transporte por defecto: una conexión keep-alive por hilo y host, respuestas comprimidas con gzip (salvo en los streams) y timeout como límite de conexión de las llamadas que no tienen timeout propio. Puedes envolverlo:
client.close() cierra las conexiones del transporte por defecto. Un transporte personalizado que tenga un método close() también se cierra.

Logging

El SDK registra cada petición en DEBUG en el logger squarecloud: método, ruta y estado, nunca cuerpos ni claves. Solo añade un NullHandler, así que no se imprime nada hasta que configures el logging:

Próximos pasos

Gestión de aplicaciones

Estado, ciclo de vida, logs y métricas.

Errores

Clase de error, reintentos y límites de tasa.

Introducción a la API

URL base, autenticación y una primera solicitud.

Inicio rápido de la CLI

Haz deploy y gestiona aplicaciones desde la terminal.