Skip to main content
Cette page documente squarecloud-api 5.0, une réécriture du SDK. Vous venez de la v4 ? Lisez le guide de migration v4 → v5.

Prérequis

Le paquet n’a aucune dépendance d’exécution (uniquement la bibliothèque standard : http.client, json, ssl) et est entièrement typé (py.typed) : les réponses sont des TypedDict que votre éditeur et votre vérificateur de types comprennent.

Installation

Le paquet s’installe sous le nom squarecloud-api et s’importe sous le nom squarecloud. La version installée est squarecloud.__version__.

Clé API et scopes

Créez une clé sur squarecloud.app/account/security. Le SDK l’envoie telle quelle dans l’en-tête Authorization (sans préfixe Bearer). Une clé peut être limitée à des scopes (apps:read, apps:deploy, apps:control, ai:chat, …) et à des applications ou bases de données précises :
  • Un appel hors de ces limites lève une SquareCloudAPIError avec 403 MISSING_SCOPE ou RESOURCE_NOT_ALLOWED.
  • Les méthodes de liste (account.me(), apps.status_all(), …) ne renvoient que les ressources que la clé peut voir.
  • Une clé inconnue, révoquée ou expirée donne 401 ACCESS_DENIED.
Gardez la clé hors de votre code source : lisez-la depuis l’environnement (os.environ["SQUARECLOUD_API_KEY"]) ou depuis un gestionnaire de secrets.
Les exemples lisent la clé depuis la variable d’environnement SQUARECLOUD_API_KEY. Définissez-la dans le terminal où vous les exécutez :

Créer le client

Le SDK propose deux clients avec les mêmes groupes et les mêmes méthodes :
  • SquareCloud est synchrone et thread-safe : partagez une seule instance entre les threads. Chaque thread réutilise sa propre connexion keep-alive.
  • AsyncSquareCloud est la même API avec await. Chaque appel exécute le client synchrone dans asyncio.to_thread, de sorte que la boucle d’événements n’est jamais bloquée.
Les deux affichent le nom de votre compte et le nombre d’applications que la clé peut voir :
Quitter le bloc with / async with ferme les connexions du pool. Sans bloc, appelez client.close() lorsque vous avez terminé. close() est une méthode ordinaire (synchrone) sur les deux clients. Une clé vide ou composée uniquement d’espaces lève une ValueError dans le constructeur, avant toute requête.

Le client asynchrone

AsyncSquareCloud ne diffère de SquareCloud qu’en trois points :
  • Chaque méthode renvoie une coroutine : await client.apps.status(app_id).
  • close() est synchrone : appelez-la sans await.
  • apps.realtime(app_id) ne s’utilise pas avec await : elle renvoie un AsyncRealtime que vous consommez avec async for (voir Temps réel).
Comme chaque appel s’exécute dans un thread de travail, vous pouvez lancer des appels en parallèle avec asyncio.gather :
Annuler une tâche en attente n’arrête pas la requête déjà en cours dans son thread de travail : l’appel se termine quand même (ou expire) en arrière-plan.

Options

Les options sont uniquement nommées (keyword-only), et AsyncSquareCloud accepte les mêmes.
Le client ne conserve la clé que dans ses en-têtes de requête privés : il n’y a pas d’attribut client.api_key, et le logger du SDK ne l’écrit jamais.

Modules

Le paquet exporte SquareCloud, AsyncSquareCloud, SquareCloudAPIError, BASE_URL, HTTPTransport, les protocoles Transport et Response, Realtime, AsyncRealtime et __version__. Les types de réponse (App, RuntimeStats, Snapshot, …) se trouvent dans squarecloud.types :

Conventions

L’identifiant d’abord, des données brutes en retour

Chaque méthode prend l’identifiant de la ressource comme premier argument et renvoie des données brutes : chaque réponse est un TypedDict, qui est un dict ordinaire à l’exécution (pas de classes, pas de cache), de sorte que les champs que l’API ajoutera plus tard sont conservés. Les noms de champs sont ceux de l’API (created_at, version_id, lastModified, joinedAt, netIO, …), la référence de l’API s’applique donc telle quelle.
  • Les mutations renvoient None, sauf si l’API renvoie des données (envs.*, deploys.set_webhook, deploys.link_github_app, databases.reset_credentials et les méthodes create).
  • Un résultat de type chaîne n’est jamais None : il vaut '' quand l’API n’en envoie pas.
  • Les listes arrivent complètes en un seul appel : il n’y a pas de pagination.
  • Les modificateurs optionnels sont uniquement nommés (status(app_id, raw=True), commit(app_id, file, path="/src")). La seule exception est le path optionnel de files.list, qui peut aussi être passé par position.
Les méthodes sont des méthodes liées ordinaires, vous pouvez donc en garder une référence :

Applications de workspace

Chaque app_id accepte aussi la forme composite <appId>-<workspaceId> pour agir sur une application partagée avec vous via un workspace. workspaces.get() et workspaces.list() renvoient les identifiants bruts ; c’est à vous de construire l’identifiant composite :

Les identifiants sont encodés

Les identifiants dans le chemin de l’URL sont encodés en pourcentage. Un identifiant vide, . ou .. atteindrait une autre route : il échoue donc localement avec INVALID_ID (statut 0) avant tout envoi. Les routes de workspace envoient plutôt leurs identifiants dans le corps : là, INVALID_ID (400) vient du serveur.

Dates

Les arguments start et end (voir Réseau) acceptent une chaîne ISO 8601 (envoyée telle quelle) ou un datetime (envoyé en UTC). Un datetime naïf est considéré comme une heure locale et converti en UTC : préférez donc des datetime conscients du fuseau (datetime.now(UTC)). Les dates des réponses restent telles que l’API les envoie (chaînes ISO, ou millisecondes Unix là où l’API les utilise).

Timeouts

timeout borne chaque opération de socket : la connexion et chaque lecture ou écriture. Une réponse qui continue d’envoyer des données peut durer plus longtemps que timeout au total. Un timeout de 0 ou moins désactive tous les timeouts, planchers de 120 s compris. Les appels ne peuvent pas être annulés une fois envoyés : le seul flux que vous pouvez arrêter en cours de route est apps.realtime(), avec close() depuis n’importe quel thread. Pour un long envoi, gardez le timeout par défaut afin qu’une connexion morte soit détectée à la connexion, et exécutez-le dans un thread ou avec AsyncSquareCloud si le reste de votre programme doit continuer à tourner.

Compte

client.account.me() renvoie l’utilisateur authentifié ainsi que les applications et bases de données que la clé peut voir.
client.account.snapshots(scope=...) liste tous les snapshots du compte : voir Snapshots.

Statut de la plateforme

client.service.status() renvoie le statut public de la plateforme. La route n’exige pas de clé valide, mais le client en demande tout de même une non vide.
unknown signifie que la vérification elle-même n’a pas pu s’exécuter : ce n’est pas la preuve d’une panne.

Avancé

Transport personnalisé

transport= remplace la couche HTTP. Utilisez-le pour les proxys, le traçage ou les tests. Un transport est n’importe quel appelable avec cette signature :
L’objet renvoyé doit avoir status, read(), readline() et close() : un http.client.HTTPResponse convient. Les nouvelles tentatives, la conversion des erreurs et le déballage de {status, response} restent dans le client : un transport ne fait que transporter des octets. HTTPTransport(timeout=30.0) est le transport par défaut : une connexion keep-alive par thread et par hôte, des réponses compressées en gzip (sauf pour les flux), et timeout comme borne de connexion des appels sans timeout propre. Vous pouvez l’envelopper :
client.close() ferme les connexions du transport par défaut. Un transport personnalisé qui possède une méthode close() est fermé lui aussi.

Journalisation

Le SDK journalise chaque requête au niveau DEBUG sur le logger squarecloud : méthode, chemin et statut, jamais les corps ni les clés. Il n’attache qu’un NullHandler, donc rien n’est affiché tant que vous ne configurez pas la journalisation :

Prochaines étapes

Gérer les applications

Statut, cycle de vie, logs et métriques.

Erreurs

Classe d’erreur, nouvelles tentatives et limites de débit.

Introduction à l'API

URL de base, authentification et une première requête.

Démarrage rapide de la CLI

Déployez et gérez vos applications depuis le terminal.