Brancher un autre logiciel sur Kewos
Le reste de ce parcours s’adresse à qui écrit un module. Cette page s’adresse à qui reste dehors : un logiciel tiers, un script de synchronisation, un connecteur maison.
Un jeton, pas un compte
Un autre logiciel n’a pas de compte utilisateur. Il a un jeton de service : pas de
user_id, des droits qui viennent uniquement de ses groupes.
from kewos.auth.tokens import create_service_token
issued = create_service_token(engine, name="logiciel-de-la-mairie", groups=("library_reader",))jeton émis : kws_IfsG4HDR... (36 caractères, la seule copie en clair)en base : 618039e46002f1cd...le jeton en clair y est ? Falseuser_id : None | type : service | groupes : ['library_reader']La base ne contient qu’une empreinte : elle ne permet pas de rejouer le jeton. Et les groupes suffisent à tout :
GET /api/v1/library_title avec le jeton -> 200POST /api/v1/library_title avec le même -> 403 (groupe lecteur seulement)GET /api/v1/library_title sans jeton -> 401Un intégrateur ne demande donc pas « un compte admin » : il demande un jeton et la liste des groupes dont il a besoin.
Chaque modèle est déjà une API
Il n’y a rien à exposer : tout modèle du registre a son point d’entrée, et les modules du Builder aussi.
GET /api/v1/library_title?genre=science&sort=name&limit=2
{"count": 1, "next_cursor": null, "results": [{"name": "A Brief History of Time", "genre": "science", ...}]}- Tout paramètre qui n’est pas réservé est un filtre de colonne.
limit,offset,sort,cursorettagsont réservés ;genre=sciencefiltre. - La pagination se fait par
limit/offsetou par curseur (next_cursor), plus sûr quand des lignes s’insèrent pendant que vous paginez. - Un champ inconnu est refusé en nommant le champ, pas ignoré en silence :
{"field": "order", "reason": "unknown or read-only field"}.
Et l’export sort le même contenu en fichier :
GET /api/v1/library_title/export?format=csvid,name,author,isbn,published_year,genre,summary,cover,kws_custom_rayon_prefereLes formats sont csv, jsonl, json, xlsx, xml. Notez la dernière colonne : un champ
ajouté à chaud par le client sort aussi, sans que personne ait touché à l’export.
Écrire deux fois sans créer deux fois
Un connecteur qui perd sa connexion ne sait pas si son POST est passé. D’où l’en-tête
Idempotency-Key :
POST /api/v1/library_title Idempotency-Key: cmd-4711 -> 201 {"id": 12}POST /api/v1/library_title Idempotency-Key: cmd-4711 -> 201 {"id": 12}
fiches créées : 1Le deuxième appel ne rejoue pas l’écriture : il renvoie la première réponse. Réessayer devient sans danger, ce qui est la seule façon d’écrire un connecteur fiable.
Ne pas écraser le travail de quelqu’un d’autre
Chaque fiche porte un numéro de version. En le renvoyant dans If-Match, votre écriture est
refusée si la fiche a changé entre-temps :
GET /api/v1/library_title/1 -> version 3PATCH /api/v1/library_title/1 If-Match: 3 -> 200 (la version passe à 4)PATCH /api/v1/library_title/1 If-Match: 3 -> 409 "version mismatch -- refetch and retry"Sans If-Match, la dernière écriture gagne, en silence. C’est un choix à faire consciemment.
La limite de débit
appel 1 -> 200appel 4 -> 429 retry-after: 36Le refus est un 429 avec Retry-After en secondes : le client sait quand réessayer au lieu
de deviner. Le compteur est par jeton, donc un connecteur bavard ne pénalise pas les autres.
JSON-RPC, pour les actions qui ne sont pas du CRUD
« Confirmer une commande » n’est pas un PATCH. Un module expose alors une méthode :
from kewos.api.jsonrpc import register_jsonrpc_method
register_jsonrpc_method("library.loan.renew", renew_loan)POST /api/v1/jsonrpc {"jsonrpc":"2.0","method":"kewos.ping","id":1} -> {"jsonrpc":"2.0","result":{"pong":true,"tenant":"main"},"id":1}
méthode inconnue -> {"error":{"code":-32601,"message":"method not found: 'nobody.home'"}} mauvaise version -> {"error":{"code":-32600,"message":"invalid JSON-RPC 2.0 envelope"}} sans jeton -> 401kewos.ping renvoie le client résolu : un seul appel vérifie que la pile répond et que
vous parlez au bon locataire.
Recevoir un appel entrant
L’inverse existe aussi : un prestataire de paiement ou un service tiers vous appelle. Le noyau fournit la vérification de signature et le registre d’idempotence : un même événement rejoué (même fournisseur, même identifiant d’événement) est enregistré une fois et sans effet la seconde fois. La route répond 200 même sur rejeu, parce qu’un prestataire réessaie sur tout code non-2xx et qu’une tempête de 5xx est pire que l’événement perdu.