Aller au contenu

Utilisation de l'API

Ce guide couvre la fonctionnalité centrale de l’API Apprise : l’envoi de notifications. Vous pouvez envoyer des notifications de deux manières :

  1. Sans état : vous fournissez les URL de configuration dans la charge utile de la requête.
  2. Avec état : vous référencez une clé de configuration préalablement enregistrée.

Par défaut, les points de terminaison renvoient text/plain. Si vous préférez du JSON, envoyez Accept: application/json.

Pour les points de terminaison de notification (/notify et /notify/{KEY}), vous pouvez aussi demander une vue HTML simple des journaux avec Accept: text/html. C’est principalement utile pour des tests manuels dans un navigateur.

Ces réponses attendent la fin de l’envoi des notifications, puis transmettent les journaux une entrée à la fois. Un résultat volumineux stocké sur disque n’est donc pas reconstruit en mémoire et le format de la réponse ne change pas.

Les points de terminaison de notification peuvent indiquer leur progression à mesure que chaque service est notifié. Utilisez ?stream=yes ou envoyez Accept: text/event-stream.

Les éventuels événements log sont suivis d’un événement result. Une erreur inattendue produit plutôt un événement error.

Fenêtre de terminal
curl -N -X POST \
-H "Content-Type: application/json" \
-d '{"body": "Sauvegarde terminée avec succès.", "title": "État du système"}' \
"http://localhost:8000/notify?stream=yes"
event: log
data: {"level": "INFO", "asctime": "2025-01-01 12:00:00,000", "message": "Sent to Telegram", "service": "Telegram"}
event: result
data: {"status": "SUCCESS"}

Le flux commence avec le code HTTP 200, avant la fin de l’envoi. Consultez le statut du dernier événement result (SUCCESS, FAILURE, NOMATCH, PARTIAL ou TIMEOUT) au lieu de compter sur le code HTTP 424.

Chaque connexion conserve jusqu’à 2 Mo de journaux en attente en mémoire. Si le client prend du retard, jusqu’à 256 Mo supplémentaires peuvent être conservés dans un stockage temporaire. Les événements restent ordonnés tant qu’aucune limite n’est atteinte.

Si la limite est atteinte ou si le stockage temporaire échoue, l’envoi des notifications continue. Le flux émet un journal ERROR demandant de contacter l’administrateur du serveur. Le flux reprend les nouvelles entrées une fois les événements stockés envoyés.

Les opérateurs peuvent modifier ces limites avec APPRISE_STREAM_MEMORY_SIZE et APPRISE_STREAM_DISK_SIZE. Les mêmes limites empêchent aussi les journaux du résultat final de croître sans limite en mémoire. Consultez Variables d’environnement pour connaître les modes utilisant la valeur zéro.

Au maximum, APPRISE_STREAM_WORKER_COUNT notifications diffusées s’exécutent simultanément dans chaque processus worker Gunicorn. La valeur par défaut est 4 ; la valeur effective par défaut pour tout le serveur est donc APPRISE_WORKER_COUNT * 4.

APPRISE_STREAM_QUEUE_SIZE permet à 8 flux supplémentaires de rester connectés dans chaque processus worker pendant l’attente d’un emplacement actif ou la fin de leur réponse. Lorsque tous les emplacements actifs et la file d’attente sont occupés, un nouveau flux reçoit le code HTTP 503 avec un en-tête Retry-After. Les notifications qui ne diffusent pas leur progression ne sont pas concernées.

Un envoi continue d’occuper son emplacement si le client se déconnecte pendant son exécution. Un proxy inverse peut aussi appliquer ses propres limites avant qu’une requête atteigne l’API Apprise.

Dans le conteneur fourni, APPRISE_CONNECTION_TIMEOUT définit la durée pendant laquelle le proxy attend une activité du flux. La valeur par défaut est de 10 minutes.

Intégration API sans état

Les notifications sans état sont idéales pour un usage de type « sidecar » lorsque vous ne voulez pas gérer de configuration persistante sur le serveur. Vous devez fournir le paramètre urls à chaque requête.

Lorsque l’authentification est activée, utilisez les identifiants administrateur ou envoyez des urls explicites avec les identifiants d’un utilisateur de configuration et l’en-tête X-Apprise-Config-ID correspondant. L’accès de cet utilisateur doit être user ; locked, public et disabled ne peuvent pas envoyer de notifications sans état. Pour rester compatible avec l’API Apprise v2, l’en-tête envoyé sans urls reste un envoi avec état via la configuration enregistrée.

La méthode la plus courante consiste à envoyer une charge utile JSON à /notify.

Point de terminaison : POST /notify

Fenêtre de terminal
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"urls": "mailto://user:pass@gmail.com",
"body": "Sauvegarde terminée avec succès.",
"title": "État du système"
}' \
http://localhost:8000/notify

Pour envoyer des pièces jointes, utilisez multipart/form-data. L’API accepte les envois de fichiers classiques ainsi que les URL distantes. Utilisez attach comme nom de champ recommandé. Les alias attachment et attachments sont également acceptés.

Pour les charges utiles JSON qui fournissent des pièces jointes distantes ou encodées, utilisez les mêmes noms de champ.

Fenêtre de terminal
# Envoyer un fichier local
curl -X POST \
-F "urls=discord://webhook_id/token" \
-F "body=Voir le journal joint." \
-F "attach=@/var/log/syslog" \
http://localhost:8000/notify
# Référencer une URL distante (Apprise la téléchargera puis la transmettra)
curl -X POST \
-F "urls=discord://webhook_id/token" \
-F "body=Instantané de la caméra de sécurité" \
-F "attach=http://camera-ip/snapshot.jpg" \
http://localhost:8000/notify
Intégration API avec état

Les notifications avec état vous permettent de simplifier votre code client. Vous stockez une fois sur le serveur les URL complexes, associées à une clé, puis votre client référence simplement cette clé.

Point de terminaison : POST /notify/{KEY}

Si vous avez enregistré une configuration sous la clé my-alerts :

Fenêtre de terminal
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"body": "Échec de la connexion à la base de données",
"type": "warning"
}' \
http://localhost:8000/notify/my-alerts

Lorsque l’authentification est activée, conservez la même URL avec la clé et ajoutez Basic Auth :

Fenêtre de terminal
curl -u "user:password" -X POST \
-H "Content-Type: application/json" \
-d '{"body": "Échec de la connexion à la base de données", "type": "warning"}' \
http://localhost:8000/notify/my-alerts

Une connexion administrateur avec mot de passe uniquement utilise -u ":password".

Un administrateur peut aussi définir un ID de configuration comme public. Les appelants publics omettent Basic Auth, mais doivent fournir un tag précis autre que all. L’accès public fonctionne uniquement pour les notifications avec état ; les autres points de terminaison restent protégés.

Le mode disabled bloque l’accès de l’utilisateur sans supprimer sa configuration ni ses identifiants. Un administrateur peut toujours la gérer et l’utiliser.

Les configurations avec état prennent en charge les tags, ce qui vous permet de notifier des sous-groupes spécifiques de vos URL enregistrées.

La valeur passée dans le champ tag suit les règles suivantes :

Valeur tagServices sélectionnés
"TagA"Possède TagA
"TagA TagB"Possède TagA ET TagB
"TagA+TagB"Possède TagA ET TagB
"TagA&TagB"Possède TagA ET TagB
"TagA,TagB"Possède TagA OU TagB
"TagA|TagB"Possède TagA OU TagB
"TagA TagC,TagB"Possède (TagA ET TagC) OU TagB
Fenêtre de terminal
# Notifier les services tagués "devops" OU "admin"
curl -X POST -d '{"tag": "devops,admin", "body": "..."}' ...
# Notifier les services tagués "devops" ET "critical"
curl -X POST -d '{"tag": "devops critical", "body": "..."}' ...
# Notifier les services correspondant à ('comment' ET 'create') OU 'admin'
curl -X POST -d '{"tag": "comment create,admin", "body": "..."}' ...

Si une configuration enregistrée utilise des marqueurs ${NOM}, les URL qui en dépendent ne sont pas utilisées tant qu’une valeur n’est pas disponible. Vous pouvez fournir ces valeurs avec la notification elle-même.

Le YAML enregistré doit déclarer chaque marqueur :

template:
api_key:
urls:
- sendgrid://${API_KEY}:noreply@example.com/admin@example.com:
- tag: alerts

En JSON, utilisez un objet template :

Fenêtre de terminal
curl -X POST \
-H "Content-Type: application/json" \
-d '{
"tag": "alerts",
"body": "Échec de la connexion à la base de données",
"template": {"api_key": "votre-cle-secrete"}
}' \
http://localhost:8000/notify/my-alerts

Avec un formulaire, nommez chaque champ template[nom] :

Fenêtre de terminal
curl -X POST \
-F "tag=alerts" \
-F "body=Échec de la connexion à la base de données" \
-F "template[api_key]=votre-cle-secrete" \
http://localhost:8000/notify/my-alerts

Une valeur envoyée ainsi passe en premier. Si elle est vide ou ne contient que des espaces, Apprise utilise la valeur par défaut de la configuration, puis l’environnement du serveur. Les noms ne sont pas sensibles à la casse. Les noms valides supplémentaires sont acceptés et ignorés ; seul leur nom apparaît dans le journal de débogage local du serveur.

Une valeur manquante ignore seulement les URL concernées. Le résultat est PARTIAL si une autre URL correspondante est envoyée, ou FAILURE si elles sont toutes ignorées. Les noms manquants apparaissent uniquement dans le journal local du serveur. Utilisez l’onglet Review ou GET /json/urls/{KEY} pour voir ce qu’attend la configuration.

Ces valeurs concernent uniquement les configurations enregistrées ; les requêtes sans état les ignorent.

L’onglet Notifications ajoute une ligne clé/valeur masquée pour chaque variable utilisée par les destinations sélectionnées. Les valeurs par défaut déclarées dans template: sont remplies lorsqu’elles sont disponibles, mais celles de l’environnement du serveur ne sont jamais affichées. Un champ vide utilise la valeur par défaut de la configuration, puis l’environnement. Vous pouvez supprimer librement des lignes, et Clear Form reconstruit les suggestions. Add Value devient disponible lorsque chaque ligne actuelle possède un nom ; les lignes mises en évidence seront envoyées. Les tests rapides utilisent une fenêtre masquée distincte. Les tests sans état ne changent pas.

Tout appelant autorisé à envoyer via une configuration enregistrée peut fournir ses valeurs déclarées. Consultez Variables de substitution pour la configuration et le choix des emplacements.

GET /json/urls/{KEY} liste chaque URL enregistrée avec les noms de substitution qu’elle utilise :

{
"url": "mailto://user:pass@gmail.com?smtp=${SMTPSERVER}&to=${RECIPIENT}",
"template": { "smtpserver": null, "recipient": "default@example.com" }
}

template associe chaque nom utilisé par l’URL à la valeur par défaut déclarée pour lui dans la section template: de la configuration :

  • null signifie qu’aucune valeur par défaut ne peut être transmise. Soit aucune n’a été écrite, soit privacy=1 ou APPRISE_CONFIG_LOCK l’a masquée.
  • null ne veut pas dire que la valeur est indisponible. Le serveur peut encore la fournir depuis son propre environnement au moment de l’envoi. Les valeurs de l’environnement, et même leur existence, ne sont jamais indiquées.
  • L’objet est toujours présent. Il est vide lorsqu’il n’y a rien à signaler.

Les marqueurs présents dans url sont laissés exactement tels qu’ils ont été écrits :

  • Ils ne sont jamais encodés en pourcentage ni masqués. Un client peut donc les rechercher et y substituer ses propres valeurs.
  • Les noms des marqueurs sont en majuscules alors que les clés de template sont en minuscules. Comparez-les sans tenir compte de la casse.

Chaque url reprend aussi les paramètres écrits sous elle dans la configuration : en substituant les marqueurs, vous obtenez donc une URL qui envoie comme le fait l’entrée enregistrée. Seule exception : un paramètre pour lequel le service n’a aucun argument d’URL est omis, car une URL ne peut pas l’exprimer.

Avec privacy=1, le texte autour de chaque marqueur est masqué et toutes les valeurs par défaut sont retirées. Cette liste convient à l’affichage, mais ne permet pas d’envoyer.

Parfois, vous ne pouvez pas changer le format de la charge utile envoyée par un outil tiers (par ex. Grafana, Prometheus). L’API Apprise permet de faire correspondre les champs entrants avec les champs compatibles Apprise via des paramètres de requête préfixés par deux-points (:).

SyntaxeEffet
?:incoming_field=apprise_fieldRenomme incoming_field vers le champ Apprise
?:incoming_field=Supprime incoming_field de la charge utile
?:apprise_field=literal valueForce apprise_field à une chaîne fixe

Exemple : votre outil envoie {"message": "Server Down", "severity": "high"}, mais Apprise attend body et type :

Fenêtre de terminal
curl -X POST \
-d '{"message": "Server Down", "severity": "high"}' \
"http://localhost:8000/notify/my-alerts?:message=body&:severity=type"

Lorsque la charge utile entrante utilise des objets imbriqués ou des tableaux, référencez-les côté source de la règle avec une notation pointée pour les objets imbriqués et une notation entre crochets pour les éléments de tableau. Les deux peuvent être combinés librement.

Utilisez un chemin séparé par des points pour parcourir des dictionnaires imbriqués :

Fenêtre de terminal
# Charge utile provenant d'un outil de supervision :
# { "event": { "title": "CPU spike", "state": "critical" },
# "component": { "name": "web-server-01" } }
curl -X POST \
-H "Content-Type: application/json" \
-d '{"event":{"title":"CPU spike","state":"critical"},"component":{"name":"web-server-01"}}' \
"http://localhost:8000/notify/my-alerts?:event.title=title&:event.state=type&:component.name=body"

Ajoutez [N] juste après le nom de clé pour déréférencer l’index N dans ce tableau. Les indices multiples et le mélange avec la notation pointée sont pris en charge :

Fenêtre de terminal
# Charge utile provenant d'un webhook de forum ou de gestion de projet (ex. Scoold / Para) :
# { "items": [ { "title": "New post", "objectURI": "https://example.com/q/1234" } ] }
curl -g -X POST \
-H "Content-Type: application/json" \
-d '{"items":[{"title":"New post","objectURI":"https://example.com/q/1234"}]}' \
"http://localhost:8000/notify/my-alerts?:items[0].title=title&:items[0].objectURI=body"

Les indices chaînés permettent de traverser des tableaux imbriqués :

# Clé source Ce à quoi elle correspond
items[0] premier élément du tableau items
items[0].objectURI propriété .objectURI du premier élément
matrix[0][1] ligne 0, colonne 1 d'un tableau 2D
a[0][1][2].value[3] tableaux imbriqués -> dict -> tableau

Règles et limites :

  • Seul le côté source peut utiliser la notation de chemin ; la cible doit être un champ Apprise simple (title, body, type, format, tag, etc.).
  • N dans [N] doit être un entier positif ou nul. key[abc] (non entier), tout comme key[0 / key0] (crochet non fermé), sont rejetés avec un WARNING.
  • Si une étape du chemin ne peut pas être résolue (clé absente, index hors limites, ou nœud qui n’est pas une liste rencontré lors d’une étape d’index), le serveur renvoie 400 et journalise un WARNING. Aucune notification n’est envoyée. Cela vous permet de repérer les règles mal configurées sans perdre des messages en silence.
  • La profondeur correspond au nombre total d’opérations de parcours individuelles : chaque recherche de clé de dictionnaire et chaque déréférencement d’index de tableau compte pour une étape. Par exemple, items[0].objectURI représente 3 étapes (items -> [0] -> objectURI), et a[0][1][2].b[3] en représente 6.
  • La profondeur de parcours maximale est de 5 par défaut. Ajustez-la avec la variable d’environnement APPRISE_WEBHOOK_MAPPING_MAX_DEPTH.

L’interface Web choisit une langue pour chaque page qu’elle affiche, dans cet ordre :

  1. La langue que vous sélectionnez dans le menu en haut de la page. Elle est conservée dans un cookie pendant un an et l’emporte toujours.
  2. Sinon, l’en-tête Accept-Language envoyé par votre navigateur, selon l’ordre de préférence qu’il contient. Une langue que votre navigateur signale comme non souhaitée (q=0) est ignorée.
  3. Chaque tag complet de cet en-tête est essayé avant tout tag raccourci. Demander pt-BR, de essaie pt-BR, puis de, et seulement ensuite pt.
  4. L’anglais, lorsqu’aucune de vos langues n’est disponible.

Cet en-tête n’est pas réservé aux navigateurs. N’importe quel client peut l’envoyer, et les étapes 2 à 4 ci-dessus s’appliquent de la même manière :

GET /details HTTP/1.1
Accept-Language: en-US,en;q=0.9,de;q=0.5

Chaque réponse indique la langue utilisée grâce à un en-tête Content-Language. Les textes lus par une personne la suivent : les noms de services et les descriptions de champs renvoyés par /details arrivent donc dans cette langue.

Apprise API est traduite en allemand, anglais, arabe, chinois, coréen, espagnol, français, hindi, indonésien, italien, japonais, malais, néerlandais, polonais, portugais, russe, tagalog, thaï, turc et vietnamien.

Questions ou commentaires ?

Documentation

Vous avez repéré une faute de frappe ou une erreur ?

Problèmes Techniques

Vous rencontrez un problème avec le code ? Ouvrez un ticket sur GitHub :

Conçu avec amour depuis le Canada