Skip to main content
Diese Seite dokumentiert squarecloud-api 5.0, eine Neuentwicklung des SDK. Du kommst von v4? Lies den Migrationsleitfaden v4 → v5.

Voraussetzungen

Das Paket hat keine Laufzeitabhängigkeiten (nur die Standardbibliothek: http.client, json, ssl) und ist vollständig typisiert (py.typed): Antworten sind TypedDicts, die dein Editor und dein Type Checker verstehen.

Installation

Das Paket wird als squarecloud-api installiert und als squarecloud importiert. Die installierte Version ist squarecloud.__version__.

API-Schlüssel und Scopes

Erstelle einen Schlüssel unter squarecloud.app/account/security. Das SDK sendet ihn unverändert im Header Authorization (ohne das Präfix Bearer). Ein Schlüssel kann auf Scopes (apps:read, apps:deploy, apps:control, ai:chat, …) und auf bestimmte Apps oder Datenbanken beschränkt werden:
  • Ein Aufruf außerhalb dieser Grenzen wirft einen SquareCloudAPIError mit 403 MISSING_SCOPE oder RESOURCE_NOT_ALLOWED.
  • Listenmethoden (account.me(), apps.status_all(), …) geben nur die Ressourcen zurück, die der Schlüssel sehen kann.
  • Ein unbekannter, widerrufener oder abgelaufener Schlüssel ergibt 401 ACCESS_DENIED.
Halte den Schlüssel aus deinem Quellcode heraus: Lies ihn aus der Umgebung (os.environ["SQUARECLOUD_API_KEY"]) oder aus einem Secret Manager.
Die Beispiele lesen den Schlüssel aus der Umgebungsvariable SQUARECLOUD_API_KEY. Setze sie in dem Terminal, in dem du sie ausführst:

Client erstellen

Das SDK hat zwei Clients mit denselben Gruppen und Methoden:
  • SquareCloud ist synchron und threadsicher: Teile eine Instanz zwischen Threads. Jeder Thread verwendet seine eigene Keep-Alive-Verbindung wieder.
  • AsyncSquareCloud ist dieselbe API mit await. Jeder Aufruf führt den synchronen Client in asyncio.to_thread aus, sodass die Event Loop nie blockiert wird.
Beide geben deinen Kontonamen und die Anzahl der Apps aus, die der Schlüssel sehen kann:
Das Verlassen des with- / async with-Blocks schließt die gepoolten Verbindungen. Ohne Block rufst du client.close() auf, wenn du fertig bist. close() ist bei beiden Clients eine normale (synchrone) Methode. Ein leerer oder nur aus Leerzeichen bestehender Schlüssel wirft im Konstruktor einen ValueError, noch vor jeder Anfrage.

Der asynchrone Client

AsyncSquareCloud unterscheidet sich von SquareCloud nur an drei Stellen:
  • Jede Methode gibt eine Coroutine zurück: await client.apps.status(app_id).
  • close() ist synchron: Rufe es ohne await auf.
  • apps.realtime(app_id) wird nicht mit await aufgerufen: Es gibt ein AsyncRealtime zurück, das du mit async for konsumierst (siehe Realtime).
Da jeder Aufruf in einem Worker-Thread läuft, kannst du Aufrufe mit asyncio.gather nebenläufig ausführen:
Das Abbrechen eines wartenden Tasks stoppt nicht die Anfrage, die bereits in seinem Worker-Thread läuft: Der Aufruf wird im Hintergrund trotzdem abgeschlossen (oder läuft in ein Timeout).

Optionen

Die Optionen sind reine Keyword-Argumente, und AsyncSquareCloud akzeptiert dieselben.
Der Client speichert den Schlüssel nur in seinen privaten Anfrage-Headern: Es gibt kein Attribut client.api_key, und der Logger des SDK schreibt ihn nie.

Module

Das Paket exportiert SquareCloud, AsyncSquareCloud, SquareCloudAPIError, BASE_URL, HTTPTransport, die Protokolle Transport und Response, Realtime, AsyncRealtime und __version__. Die Antworttypen (App, RuntimeStats, Snapshot, …) befinden sich in squarecloud.types:

Konventionen

Zuerst die ID, zurück kommen einfache Daten

Jede Methode nimmt die ID der Ressource als erstes Argument und gibt einfache Daten zurück: Jede Antwort ist ein TypedDict, zur Laufzeit also ein normales dict (keine Klassen, kein Cache), sodass Felder, die die API später hinzufügt, erhalten bleiben. Die Feldnamen sind die der API (created_at, version_id, lastModified, joinedAt, netIO, …), daher gilt die API-Referenz unverändert.
  • Mutationen geben None zurück, sofern die API keine Daten zurückgibt (envs.*, deploys.set_webhook, deploys.link_github_app, databases.reset_credentials und die create-Methoden).
  • Ein String-Ergebnis ist nie None: Es ist '', wenn die API keines sendet.
  • Listen kommen vollständig in einem Aufruf: Es gibt keine Paginierung.
  • Optionale Modifikatoren sind reine Keyword-Argumente (status(app_id, raw=True), commit(app_id, file, path="/src")). Die einzige Ausnahme ist der optionale path von files.list, der auch als Positionsargument übergeben werden kann.
Die Methoden sind normale gebundene Methoden, du kannst also eine Referenz auf sie behalten:

Workspace-Apps

Jede app_id akzeptiert auch die zusammengesetzte Form <appId>-<workspaceId>, um auf eine App zuzugreifen, die über einen Workspace mit dir geteilt wird. workspaces.get() und workspaces.list() geben die reinen IDs zurück; die zusammengesetzte ID baust du selbst:

IDs werden kodiert

IDs im URL-Pfad werden prozentkodiert. Eine ID, die leer, . oder .. ist, würde eine andere Route erreichen und schlägt daher lokal mit INVALID_ID (Status 0) fehl, bevor etwas gesendet wird. Workspace-Routen senden ihre IDs stattdessen im Body: Dort kommt INVALID_ID (400) vom Server.

Datumsangaben

Die Argumente start und end (siehe Netzwerk) akzeptieren einen ISO-8601-String (unverändert gesendet) oder ein datetime (in UTC gesendet). Ein naives datetime wird als lokale Zeit behandelt und in UTC umgerechnet, verwende also besser zeitzonenbewusste (datetime.now(UTC)). Datumsangaben in Antworten bleiben so, wie die API sie sendet (ISO-Strings oder Unix-Millisekunden, wo die API diese verwendet).

Timeouts

timeout begrenzt jede Socket-Operation: den Verbindungsaufbau und jedes Lesen oder Schreiben. Eine Antwort, die weiter Daten sendet, kann insgesamt länger als timeout dauern. Ein timeout von 0 oder weniger deaktiviert jedes Timeout, einschließlich der Mindestwerte von 120 s. Einmal gesendete Aufrufe lassen sich nicht abbrechen: Der einzige Stream, den du mittendrin stoppen kannst, ist apps.realtime(), mit close() aus einem beliebigen Thread. Behalte bei einem langen Upload das Standard-Timeout bei, damit eine tote Verbindung beim Verbindungsaufbau erkannt wird, und führe ihn in einem Thread oder mit AsyncSquareCloud aus, wenn der Rest deines Programms weiterlaufen muss.

Konto

client.account.me() gibt den authentifizierten Benutzer sowie die Apps und Datenbanken zurück, die der Schlüssel sehen kann.
client.account.snapshots(scope=...) listet jeden Snapshot des Kontos auf: siehe Snapshots.

Plattformstatus

client.service.status() gibt den öffentlichen Plattformstatus zurück. Die Route benötigt keinen gültigen Schlüssel, der Client verlangt aber trotzdem einen nicht leeren.
unknown bedeutet, dass die Prüfung selbst nicht ausgeführt werden konnte: Es ist kein Beleg für einen Ausfall.

Erweitert

Eigener Transport

transport= ersetzt die HTTP-Schicht. Verwende es für Proxys, Tracing oder Tests. Ein Transport ist jedes Callable mit dieser Signatur:
Das zurückgegebene Objekt braucht status, read(), readline() und close(): Eine http.client.HTTPResponse erfüllt das. Wiederholungen, die Zuordnung von Fehlern und das Entpacken von {status, response} bleiben im Client, ein Transport transportiert also nur Bytes. HTTPTransport(timeout=30.0) ist der Standard-Transport: eine Keep-Alive-Verbindung pro Thread und Host, gzip-komprimierte Antworten (außer bei Streams) und timeout als Grenze für den Verbindungsaufbau der Aufrufe ohne eigenes Timeout. Du kannst ihn umhüllen:
client.close() schließt die Verbindungen des Standard-Transports. Ein eigener Transport, der eine Methode close() hat, wird ebenfalls geschlossen.

Logging

Das SDK protokolliert jede Anfrage auf DEBUG im Logger squarecloud: Methode, Pfad und Status, nie Bodys oder Schlüssel. Es hängt nur einen NullHandler an, daher wird nichts ausgegeben, bis du das Logging konfigurierst:

Nächste Schritte

Anwendungen verwalten

Status, Lebenszyklus, Logs und Metriken.

Fehler

Fehlerklasse, Wiederholungen und Rate Limits.

Einführung in die API

Basis-URL, Authentifizierung und eine erste Anfrage.

CLI-Schnellstart

Apps im Terminal deployen und verwalten.