Inspection et Débogage
Apprise inclut un petit ensemble d’utilitaires d’inspection qui permettent à votre application de découvrir ce qui est pris en charge à l’exécution et de capturer une sortie de diagnostic sans reprendre la configuration globale de journalisation. Les points d’entrée les plus importants sont Apprise.details() et Apprise.json(), conçus pour des outils dynamiques comme les générateurs d’URL, les assistants de configuration, les interfaces d’administration et les pipelines de validation.
Inspecter les capacités
Section intitulée « Inspecter les capacités »Les deux méthodes renvoient les mêmes données : la version d’Apprise, la configuration AppriseAsset active (icônes, thèmes, masques) et tous les schémas (plugins) connus d’Apprise, y compris les modèles de construction d’URL et les métadonnées de jetons permettant de construire dynamiquement une URL Apprise correcte. La différence se situe au niveau du type de retour : details() renvoie un dictionnaire Python brut, tandis que json() renvoie une chaîne JSON sérialisée (ou écrit dans un fichier).
Apprise.details() renvoie un dictionnaire décrivant tous les services de notification pris en charge. Utilisez-le lorsque vous devez manipuler les données de manière programmatique en Python.
Signature de details()
Section intitulée « Signature de details() »apobj.details( lang=None, # Tag de langue BCP 47, ex. "fr" ou "de" show_requirements=False, # Inclure les dépendances propres à chaque plugin show_disabled=False, # Inclure les plugins actuellement indisponibles)Utilisation de base de details()
Section intitulée « Utilisation de base de details() »import apprise
# Instancier Appriseapobj = apprise.Apprise()
# Produire la liste des détailsinfo: dict = apobj.details()details() avec plugins désactivés
Section intitulée « details() avec plugins désactivés »Certains schémas peuvent être présents mais inutilisables parce que des dépendances optionnelles manquent. Si vous construisez une interface, vous voudrez généralement les afficher comme « disponibles, mais actuellement désactivés », avec la raison correspondante. Cette raison peut venir de paquets non installés, de l’environnement ou d’une désactivation manuelle par un administrateur. Par défaut show_disabled=False, donc pour voir cette liste il faut l’activer explicitement.
import apprise
apobj = apprise.Apprise()
# Inclure les services existants mais actuellement inutilisablesinfo: dict = apobj.details(show_disabled=True)Apprise.json() est un raccourci autour de details() qui gère la sérialisation JSON pour vous, y compris l’encodage correct des types que le module json standard ne prend pas en charge (comme les objets datetime, bytes, set, frozenset et tuple).
Signature de json()
Section intitulée « Signature de json() »apobj.json( lang=None, # Tag de langue BCP 47, ex. "fr" ou "de" show_requirements=False, # Inclure les dépendances propres à chaque plugin show_disabled=False, # Inclure les plugins actuellement indisponibles indent=None, # Transmis à json.dumps(); None = sortie compacte path=None, # Si défini, écrit dans ce fichier au lieu de renvoyer une chaîne)Utilisation de base de json()
Section intitulée « Utilisation de base de json() »Sans argument path, json() renvoie le JSON sérialisé sous forme de str :
import apprise
# Instancier Appriseapobj = apprise.Apprise()
# Chaîne JSON compacte — utile pour une API, du cache, etc.payload: str = apobj.json()
# JSON indenté — utile pour le débogage ou pour générer des squelettes de configpayload: str = apobj.json(indent=2)json() avec plugins désactivés
Section intitulée « json() avec plugins désactivés »Comme pour details(), passez show_disabled=True pour inclure les services existants mais actuellement indisponibles :
import apprise
apobj = apprise.Apprise()
# Inclure les services existants mais actuellement inutilisablespayload: str = apobj.json(show_disabled=True)Écrire le JSON dans un fichier
Section intitulée « Écrire le JSON dans un fichier »Passez path pour écrire directement le résultat sur disque. En cas de succès, la méthode renvoie True; sinon (problème de permission, disque plein, etc.), elle journalise l’erreur et renvoie False.
import apprise
apobj = apprise.Apprise()
ok: bool = apobj.json(path="/var/cache/apprise/details.json")if not ok: print("Échec de l'écriture des détails — consultez les logs pour connaître la raison")Inclure dépendances et plugins désactivés
Section intitulée « Inclure dépendances et plugins désactivés »import apprise
apobj = apprise.Apprise()
# Dump complet d'audit — chaque plugin, même ceux sans dépendances installéespayload: str = apobj.json( show_requirements=True, show_disabled=True, indent=2,)Comprendre la structure renvoyée
Section intitulée « Comprendre la structure renvoyée »Clés de premier niveau
Section intitulée « Clés de premier niveau »Vous pouvez vous attendre à trouver ces clés de premier niveau :
version: la version de la bibliothèque Apprise ;asset: les paramètresAppriseAssetactifs ;schemas: la liste de tous les schémas pris en charge, une entrée par plugin.
Le contenu de asset est produit par AppriseAsset.details() et contient actuellement :
app_idapp_descdefault_extensionthemeimage_path_maskimage_url_maskimage_url_logo
Ces valeurs sont importantes pour les clients qui souhaitent afficher des icônes, montrer un en-tête personnalisé ou lier le bon logo et les bons assets de thème. Plus d’informations sont disponibles ici.
Entrées schemas
Section intitulée « Entrées schemas »Chaque entrée de schéma décrit un plugin, comme discord, mailto, slack, etc. Une entrée contient généralement :
- un nom lisible (
service_name) ; - des informations de protocole (variantes sécurisées et non sécurisées) ;
- des modèles de construction d’URL ;
- des métadonnées de jetons pour les composants d’URL et les paramètres de requête ;
- les dépendances nécessaires (paquets obligatoires ou recommandés).
La partie « construction d’URL » est générée par l’assistant d’inspection apprise.plugins.details(plugin), qui renvoie une structure avec les clés suivantes :
templatestokensargskwargs
Modèles d’URL
Section intitulée « Modèles d’URL »templates est une liste de modèles d’URL pris en charge par le plugin, exprimés avec des espaces réservés {token}. Ces modèles servent à l’affichage et aux outils, par exemple pour :
- montrer des exemples dans votre interface ;
- piloter un assistant qui ne demande que les jetons utiles au modèle choisi ;
- valider qu’une URL construite correspond à au moins un modèle.
Les modèles proviennent directement de l’attribut templates de chaque plugin.
Métadonnées de jetons
Section intitulée « Métadonnées de jetons »La partie la plus utile des détails de schéma réside dans les métadonnées des jetons. Apprise génère une structure cohérente et prévisible, même lorsque des plugins omettent des champs optionnels. Cette normalisation est gérée en interne pour que les outils clients puissent compter sur des clés stables.
Les jetons sont répartis en trois groupes :
tokens: chemin, hôte, authentification et autres éléments « cœur » servant à initialiser le plugin ;args: arguments de chaîne de requête (options normales du plugin) ;kwargs: arguments dynamiques clé/valeur, où l’utilisateur fournit à la fois le nom de l’argument et sa valeur.
Le jeton implicite schema
Section intitulée « Le jeton implicite schema »Apprise injecte automatiquement un jeton schema, toujours requis. Ses valeurs proviennent des paramètres secure_protocol et protocol du plugin. C’est ainsi qu’un outil peut afficher par exemple les variantes http et https lorsqu’elles existent.
Champs standards des jetons (normalisés)
Section intitulée « Champs standards des jetons (normalisés) »Après normalisation, vous pouvez généralement compter sur la présence des champs suivants :
| Clé | Description |
|---|---|
name | Libellé lisible (prend le nom du jeton par défaut s’il manque). |
map_to | Argument du plugin ciblé par ce jeton (prend le nom du jeton par défaut). |
type | Type de jeton (par défaut string). Prend aussi list:* et choice:*. |
required | Vaut False par défaut si non précisé. |
private | Vaut False par défaut si non précisé. |
default | Peut être présent, y compris rempli automatiquement s’il n’existe qu’un choix. |
values | Pour les jetons choice:* et certains autres champs contraints. |
delim | Pour les jetons list:* (la valeur par défaut varie selon le contexte). |
regex | Regex de validation facultative, normalisée en paire (pattern, flags). |
group | Pour les alias de liste qui mappent plusieurs champs sous-jacents. |
Comportement des délimiteurs
Section intitulée « Comportement des délimiteurs »Apprise assigne des délimiteurs par défaut différents selon l’emplacement du jeton :
tokens(listes orientées chemin) utilisent/par défaut ;argsetkwargs(listes orientées requête) utilisent,et espace.
Cela compte lorsque votre interface doit expliquer comment saisir plusieurs destinataires, canaux ou cibles.
Alias et groupement
Section intitulée « Alias et groupement »Si plusieurs noms de jetons pointent vers le même argument via map_to, Apprise peut exposer un champ group pour les types liste, afin qu’un outil puisse montrer qu’un jeton liste agit comme alias pour plusieurs entrées liées.
Dépendances et indices d’installation (requirements)
Section intitulée « Dépendances et indices d’installation (requirements) »Apprise peut aussi renvoyer les détails de dépendance par plugin via apprise.plugins.requirements(plugin).
La structure inclut :
details: court message lisible, rempli automatiquement si le plugin n’en fournit pas ;packages_required: liste des paquets obligatoires (chaînes de dépendancepip) ;packages_recommended: liste des paquets recommandés.
C’est la partie à afficher lorsqu’un plugin apparaît dans details(show_disabled=True) mais ne peut pas être activé tant que ses dépendances ne sont pas installées.
Utiliser details() pour construire un assistant d’URL
Section intitulée « Utiliser details() pour construire un assistant d’URL »Une approche pratique qui fonctionne bien :
- Laisser l’utilisateur choisir un service dans
schemasviaservice_name. - Afficher les
templatesdisponibles pour ce service. - Une fois un modèle choisi, identifier chaque
{token}du modèle et demander les champs correspondants danstokens. - Proposer la configuration facultative via
args(etkwargsseulement si présent). - Respecter
private=Trueen masquant les champs et sans jamais réafficher leur valeur en clair. - Respecter
typepour rendre les bons widgets :bool: case à cocherchoice:*: liste déroulante basée survaluesint/float: champ numérique avec min/max si présentslist:*: saisie multiple avec aide sur le délimiteur tirée dedelim
Débogage avec LogCapture
Section intitulée « Débogage avec LogCapture »Pour le débogage programmatique, Apprise fournit LogCapture, un gestionnaire de contexte qui intercepte la sortie de journal pendant la durée d’un bloc. C’est souvent préférable à une modification globale des handlers de journalisation Python.
Capturer les logs en mémoire
Section intitulée « Capturer les logs en mémoire »import apprise
apobj = apprise.Apprise()apobj.add("mailto://user:pass@example.com")
# Capturer tous les logs (INFO et plus) en mémoirewith apprise.LogCapture(level=apprise.logging.INFO) as output: apobj.notify(title="Bonjour", body="Monde")
# 'output' est un objet StringIO print("Logs capturés :") print(output.getvalue())Capturer les logs dans un fichier
Section intitulée « Capturer les logs dans un fichier »Vous pouvez aussi diriger les logs vers un fichier temporaire ou persistant.
import apprise
apobj = apprise.Apprise()
with apprise.LogCapture(path="/var/log/apprise.log", delete=False) as fp: apobj.notify(title="Système", body="Crash détecté")Formatage HTML personnalisé des logs
Section intitulée « Formatage HTML personnalisé des logs »Vous pouvez injecter un format personnalisé dans le flux de log afin d’afficher directement les logs dans une page web.
import apprise
fmt = ( "<li>" "<span class=\"time\">%(asctime)s</span> " "<span class=\"lvl\">%(levelname)s</span> " "<span class=\"msg\">%(message)s</span>" "</li>")
apobj = apprise.Apprise()with apprise.LogCapture(fmt=fmt) as logs: apobj.notify(title="Test", body="Message") # Récupérer la chaîne HTML html: str = f"<ul>{logs.getvalue()}</ul>"Notes pour les auteurs de bibliothèques
Section intitulée « Notes pour les auteurs de bibliothèques »Si vous intégrez Apprise dans une autre bibliothèque ou un autre service :
- préférez
json()lorsque vous avez besoin d’une charge utile JSON (réponses API, dumps fichier) ; - préférez
details()lorsque vous avez besoin du dictionnaire brut pour un traitement ultérieur, par exemple construire une interface ou inspecter des métadonnées de plugins ; - préférez
LogCapturedans les tests et le diagnostic afin de montrer des erreurs utiles aux utilisateurs sans leur imposer de reconfigurer la journalisation globale.
Questions ou commentaires ?
Documentation
Vous avez repéré une faute de frappe ou une erreur ? Signalez-la ou proposez une correction .
Problèmes Techniques
Vous rencontrez un problème avec le code ? Ouvrez un ticket sur GitHub :