Beancount (un outil de comptabilité en partie double en texte brut) et Fava (son interface web) sont hautement extensibles et scriptables. Leur conception vous permet d'automatiser des tâches financières, de générer des rapports personnalisés et de configurer des alertes en écrivant des scripts Python. Pour reprendre les mots d'un utilisateur, « J'aime vraiment avoir mes données dans un format aussi pratique, et j'aime pouvoir tout automatiser à volonté. Il n'y a pas d'API comme un fichier sur votre disque ; c'est facile à intégrer. » Ce guide vous accompagne dans la création de workflows scriptables — de l'automatisation accessible aux débutants jusqu'aux plugins Fava avancés.
Explorez un grand livre d'exemple en direct :
Commencez avec la commande bea
Avant d'écrire le moindre code Python, vérifiez si bea ne fait pas déjà le travail. Il valide le grand livre, exécute des requêtes BQL, produit les quatre rapports financiers et importe les exports bancaires, et l'option globale --json transforme chacun d'entre eux en une enveloppe analysable que votre shell peut transmettre à jq. Ses codes de sortie constituent le contrat sur lequel une tâche planifiée se base, de sorte que cron ou CI n'a besoin d'aucun script de chargement. Consultez automatiser la comptabilité avec bea pour la résolution des cibles, l'enveloppe et le branchement sur les codes de sortie, puis revenez ici lorsque vous avez besoin d'un calcul personnalisé que l'interface CLI n'expose pas.
Pour commencer : exécuter Beancount comme script Python
Pour les scripts Python personnalisés ci-dessous, installez les bibliothèques de scripting (pip install beancount beanquery beangulp). Les workflows de la commande bea utilisent le moteur géré à la place ; suivez le démarrage rapide de la CLI pour l'installer. Comme Beancount est écrit en Python, vous pouvez l'utiliser comme une bibliothèque dans vos propres scripts. Les scripts ci-dessous ont été exécutés avec Beancount 3.2.3, beanquery 0.2.0 et beangulp 0.2.0. L'approche générale est la suivante :
-
Chargez votre grand livre Beancount : utilisez le chargeur de Beancount pour analyser le fichier
.beancounten objets Python. Par exemple :from beancount import loader entries, errors, options = loader.load_file("myledger.beancount") if errors: for error in errors: print(error) raise SystemExit(1)Le chargeur renvoie les écritures et les erreurs ensemble. Un fichier déséquilibré ou invalide renvoie quand même des écritures, donc vérifiez
errorset arrêtez-vous avant de faire confiance aux données. Tous vos comptes, transactions et soldes sont désormais accessibles dans le code. -
Tirez parti du Beancount Query Language (BQL) : au lieu d'itérer manuellement, vous pouvez exécuter des requêtes de type SQL sur les données. Les requêtes résident dans le paquet séparé
beanquery. Il n'y a pas de modulebeancount.querydans Beancount 3.2.3. Par exemple, pour obtenir le total des dépenses par mois, connectez les écritures chargées et exécutez la requête directement :import beanquery conn = beanquery.connect("beancount:", entries=entries, errors=errors, options=options) cur = conn.execute( "SELECT year, month, sum(position) WHERE account ~ 'Expenses' GROUP BY year, month" ) for row in cur.fetchall(): print(row)Cela utilise beanquery pour agréger les données. C'est le même moteur que celui derrière
bea query, mais ici vous l'appelez dans un script. Cela évite d'invoquer une commande externe en boucle. -
Configurez une structure de projet : organisez vos scripts à côté de votre grand livre. Une disposition courante consiste à avoir des répertoires pour les importateurs (pour récupérer/analyser des données externes), les rapports ou requêtes (pour les scripts d'analyse) et les documents (pour stocker les relevés téléchargés). Par exemple, un utilisateur conserve :
importers/– scripts d'import Python personnalisés (avec tests),queries/– scripts pour générer des rapports (exécutables viapython3 queries/...),documents/– CSV/PDF bancaires téléchargés, organisés par compte.
Avec cette configuration, vous pouvez exécuter les scripts manuellement (par exemple python3 queries/cash_flow.py) ou les planifier (via cron ou un gestionnaire de tâches) pour automatiser votre workflow.
Automatisation des tâches de rapprochement
Le rapprochement consiste à s'assurer que votre grand livre correspond aux enregistrements externes (relevés bancaires, rapports de carte de crédit, etc.). Le grand livre en texte brut et l'API Python de Beancount permettent d'automatiser une grande partie de ce processus.
Importation et correspondance des transactions (Débutant)
Pour les débutants, l'approche recommandée consiste à utiliser les importateurs du paquet séparé beangulp. Beancount 3 a supprimé le module d'ingestion v2 et sa commande extract. Vous écrivez une petite classe Python qui hérite de beangulp.Importer pour analyser un format donné (CSV, OFX, PDF, etc.) et produire des transactions. Enregistrez-la dans un court script d'ingestion, puis exécutez-la via bea ingest dans le moteur géré :
- Écrivez un importateur (une classe Python avec les méthodes
identify(),account()etextract()) pour le format CSV de votre banque. - Ajoutez un script d'ingestion qui enregistre vos importateurs.
bea ingestexécute les commandesidentify,extractetarchivedu script. Par exemple, un workflow exécuteextractsur tous les fichiers de~/Downloadset écrit les transactions dans un fichier temporaire. - Révisez manuellement et copiez les transactions du fichier temporaire dans votre grand livre principal, puis exécutez
bea checkpour vous assurer que les soldes concordent.
Un exemple minimal : un statement.csv avec les colonnes date,description,amount, analysé par cet importateur (checking_importer.py) :
import csv
import datetime
from beancount.core import data
from beancount.core.amount import Amount
from beancount.core.number import D
import beangulp
class CheckingImporter(beangulp.Importer):
def identify(self, filepath: str) -> bool:
return filepath.endswith("statement.csv")
def account(self, filepath: str) -> str:
return "Assets:Bank:Checking"
def extract(self, filepath: str, existing):
entries = []
with open(filepath, newline="") as f:
for row in csv.DictReader(f):
date = datetime.date.fromisoformat(row["date"])
amount = Amount(D(row["amount"]), "USD")
meta = data.new_metadata(filepath, 0)
entries.append(
data.Transaction(
meta, date, "*", None, row["description"],
data.EMPTY_SET, data.EMPTY_SET, [
data.Posting("Expenses:Food:Groceries", amount,
None, None, None, None),
data.Posting("Assets:Bank:Checking",
Amount(-amount.number, "USD"),
None, None, None, None),
]))
return entriesLe script d'ingestion (ingest.py) le câble :
from checking_importer import CheckingImporter
from beangulp import Ingest
ingest = Ingest([CheckingImporter()])
if __name__ == "__main__":
ingest()Exécutez-le sur un fichier téléchargé. Aucune authentification n'est nécessaire pour un CSV local. Installez d'abord la bibliothèque système libmagic. La commande d'activation ponctuelle télécharge Beangulp dans le moteur géré :
bea engine enable beangulp
bea ingest identify --config ingest.py statement.csv
bea ingest extract --config ingest.py statement.csv -o new.beancountidentify signale checking_importer.CheckingImporter pour le fichier. extract écrit les transactions au format Beancount :
2024-01-08 * "Grocery Store"
Expenses:Food:Groceries 120.00 USD
Assets:Bank:Checking -120.00 USDRévisez new.beancount, copiez les écritures dans votre grand livre principal et exécutez bea check.
Vous n'avez pas besoin d'écrire un importateur pour convertir un seul relevé. Collez le fichier dans le convertisseur CSV vers Beancount, ou utilisez OFX et QIF vers Beancount pour les téléchargements .ofx, .qfx et .qif. Les deux fonctionnent entièrement dans votre navigateur, donc le relevé ne quitte jamais votre machine.
Bien que ce processus implique encore une étape de révision, une grande partie du travail ingrat d'analyse et de mise en forme des écritures est automatisée. Les scripts d'importateur peuvent également attribuer automatiquement des catégories et même définir des assertions de solde (déclarations de soldes attendus) pour détecter les écarts. Par exemple, après l'import, vous pourriez avoir une ligne comme 2025-04-30 balance Assets:Bank:Checking 1234.56 USD qui affirme le solde de clôture. Lorsque vous exécutez bea check, Beancount vérifiera que toutes ces assertions de solde sont correctes et signalera toute erreur si des transactions sont manquantes ou dupliquées. C'est une bonne pratique : générez automatiquement des assertions de solde pour chaque période de relevé afin de laisser l'ordinateur repérer les écarts non rapprochés pour vous.
Scripts de rapprochement personnalisés (Intermédiaire)
Pour plus de contrôle, vous pouvez écrire un script Python personnalisé pour comparer la liste des transactions d'une banque (CSV ou via API) avec les écritures de votre grand livre :
- Lisez les données externes : analysez le fichier CSV de la banque à l'aide du module
csvde Python (ou Pandas). Normalisez les données en une liste de transactions, chacune avec une date, un montant et une description. - Chargez les transactions du grand livre : utilisez
loader.load_filecomme montré plus haut pour obtenir toutes les écritures du grand livre. Filtrez cette liste sur le compte d'intérêt (par exemple votre compte courant) et éventuellement sur la plage de dates du relevé. - Comparez et trouvez les écarts :
- Pour chaque transaction externe, vérifiez si une écriture identique existe dans le grand livre (correspondance par date et montant, éventuellement description). Si elle n'est pas trouvée, marquez-la comme « nouvelle » et éventuellement produisez-la sous forme de transaction au format Beancount à réviser.
- Inversement, identifiez toute écriture du grand livre sur ce compte qui n'apparaît pas dans la source externe – il peut s'agir d'erreurs de saisie ou de transactions qui n'ont pas encore été débitées par la banque.
- Produisez les résultats : imprimez un rapport ou créez un nouvel extrait
.beancountavec les transactions manquantes.
À titre d'exemple, un script communautaire appelé reconcile.py fait exactement cela : étant donné un fichier Beancount et un CSV d'entrée, il imprime une liste des nouvelles transactions qui devraient être importées, ainsi que toute écriture existante du grand livre qui n'est pas dans l'entrée (signe potentiel d'une mauvaise classification). Avec un tel script, le rapprochement mensuel peut se résumer à l'exécuter puis à ajouter les transactions suggérées à votre grand livre. Un utilisateur de Beancount note qu'il « effectue un processus de rapprochement sur tous les comptes chaque mois » et utilise une collection croissante de code Python pour éliminer une grande partie du travail manuel d'import et de rapprochement des données.
Astuce : pendant le rapprochement, tirez parti des outils de Beancount pour la précision :
- Utilisez les assertions de solde comme mentionné, pour disposer de vérifications automatisées des soldes de compte.
- Utilisez la directive
padsi vous le souhaitez, qui peut insérer automatiquement des écritures d'équilibrage pour de petits écarts d'arrondi (à utiliser avec prudence). - Écrivez des tests unitaires pour votre importateur ou votre logique de rapprochement (Beancount fournit des aides de test). Par exemple, un workflow consistait à prendre un CSV d'exemple, écrire des tests échouants avec les transactions attendues, puis implémenter l'importateur jusqu'à ce que tous les tests passent. Cela garantit que votre script d'import fonctionne correctement pour divers cas.
Génération de rapports et résumés personnalisés
Bien que Fava fournisse de nombreux rapports standards (compte de résultat, bilan, etc.), vous pouvez créer des rapports personnalisés à l'aide de scripts. Ceux-ci peuvent aller de simples sorties console à des fichiers ou graphiques richement formatés.
Interrogation des données pour les rapports (Débutant)
À un niveau basique, vous pouvez utiliser le Beancount Query Language (BQL) pour obtenir des données de synthèse et les imprimer ou les enregistrer. Par exemple :
-
Synthèse des flux de trésorerie : utilisez une requête pour calculer le flux de trésorerie net. Le « flux de trésorerie » peut être défini comme la variation du solde de certains comptes sur une période. Avec BQL, vous pourriez faire :
SELECT year, month, sum(position) WHERE account ~ 'Income' OR account ~ 'Expenses' GROUP BY year, monthCela nette toutes les écritures de revenus et de dépenses par mois. Filtrez avec
~et une expression régulière :LIKEest une erreur de syntaxe dans beanquery 0.2.0. Les écritures portentposition, pasamount. Chaque ligne contient un Inventory, donc chaque devise est listée séparément plutôt que convertie. Les revenus arrivent en négatif et les dépenses en positif. Vous pourriez exécuter cela viabea queryou via l'API Python beanquery montrée plus haut, puis formater le résultat. -
Rapport de dépenses par catégorie : interrogez le total des dépenses par catégorie :
SELECT account, sum(position) WHERE account ~ 'Expenses' GROUP BY account ORDER BY sum(position) ASCCela produit un tableau des dépenses par catégorie. Chaque total est un Inventory dans sa devise d'origine. N'enveloppez pas l'agrégat dans
round(): il n'existe pas de fonctionround(inventory, int), doncround(sum(position), 2)ne compile pas. Vous pouvez exécuter plusieurs requêtes dans un script et produire les résultats en texte, CSV ou même JSON pour un traitement ultérieur.
Un utilisateur a trouvé qu'il était « trivial » d'analyser des données financières avec Fava ou avec des scripts, citant qu'il utilise un seul script Python pour extraire les données de Beancount via le Query Language, puis les placer dans un DataFrame Pandas pour préparer un rapport personnalisé. Par exemple, vous pourriez récupérer les totaux mensuels avec une requête, puis utiliser Pandas/Matplotlib pour tracer un graphique de flux de trésorerie dans le temps. La combinaison de BQL et des bibliothèques de science des données vous permet de construire des rapports au-delà de ce que Fava propose par défaut.
Rapports avancés (graphiques, performance, etc.)
Pour des besoins plus avancés, vos scripts peuvent calculer des métriques comme la performance des investissements ou créer des sorties visuelles :
-
Performance des investissements (IRR/XIRR) : comme votre grand livre contient tous les flux de trésorerie (achats, ventes, dividendes), vous pouvez calculer les taux de rendement du portefeuille. Par exemple, vous pourriez écrire un script qui filtre les transactions de vos comptes d'investissement, puis calcule le taux de rendement interne. Il existe des bibliothèques (ou des formules) pour calculer l'IRR à partir des données de flux de trésorerie. Certaines extensions Fava développées par la communauté (comme PortfolioSummary ou fava_investor) font exactement cela, calculant l'IRR et d'autres métriques pour les portefeuilles d'investissement. En tant que script, vous pourriez utiliser une fonction IRR (de NumPy ou la vôtre) sur la série des contributions/retraits plus la valeur finale.
-
Métriques multi-périodes ou personnalisées : vous voulez un rapport de votre taux d'épargne (ratio de l'épargne sur le revenu) chaque mois ? Un script Python peut charger le grand livre, additionner tous les comptes de revenus et tous les comptes de dépenses, puis calculer épargne = revenus - dépenses et le pourcentage. Cela pourrait produire un joli tableau ou même générer un rapport HTML/Markdown pour vos archives.
-
Visualisation : vous pouvez générer des graphiques en dehors de Fava. Par exemple, utilisez
matplotliboualtairdans un script pour créer un graphique de valeur nette dans le temps, à partir des données du grand livre. Comme le grand livre contient tous les soldes historiques (ou vous pouvez les accumuler en itérant sur les écritures), vous pouvez produire des graphiques de séries temporelles. Enregistrez ces graphiques sous forme d'images ou de HTML interactif. (Si vous préférez les visuels intégrés à l'application, consultez la section sur les extensions Fava ci-dessous pour ajouter des graphiques au sein de Fava.)
Options de sortie : décidez comment livrer le rapport :
- Pour une analyse ponctuelle, l'affichage à l'écran ou l'enregistrement dans un fichier CSV/Excel peut suffire.
- Pour des tableaux de bord, envisagez de générer un fichier HTML avec les données (éventuellement à l'aide d'une bibliothèque de templates comme Jinja2, ou simplement en écrivant du Markdown) que vous pouvez ouvrir dans un navigateur.
- Vous pouvez également vous intégrer à des Jupyter Notebooks pour un environnement de reporting interactif, bien que cela relève davantage de l'exploration que de l'automatisation.
Déclenchement d'alertes depuis votre grand livre
Une autre utilisation puissante des workflows scriptables consiste à configurer des alertes basées sur des conditions dans vos données financières. Comme votre grand livre est mis à jour régulièrement (et peut inclure des éléments datés dans le futur comme des factures à venir ou des budgets), vous pouvez le parcourir avec un script et être notifié d'événements importants.
Avertissements de solde de compte faible
Pour éviter les découverts ou maintenir un solde minimum, vous pourriez vouloir une alerte si un compte (par exemple courant ou épargne) tombe sous un seuil. Voici comment vous pouvez implémenter cela :
-
Déterminez les soldes actuels : après avoir chargé
entriesvia le chargeur, calculez le dernier solde des comptes d'intérêt. Vous pouvez le faire en agrégeant les écritures ou en utilisant une requête. Par exemple, utilisez une requête BQL pour le solde d'un compte spécifique :SELECT sum(position) WHERE account = 'Assets:Bank:Checking'Cela renvoie le solde actuel de ce compte (somme de toutes ses écritures). Alternativement, utilisez les fonctions internes de Beancount pour construire un bilan. Par exemple :
from beancount.core import realization tree = realization.realize(entries) acct = realization.get_or_create(tree, "Assets:Bank:Checking") balance = acct.balance # an Inventory of commoditiesPassez uniquement les entrées : le deuxième paramètre est
min_accounts, pas le dictionnaire d'options. Ensuite, extrayez la valeur numérique (par exemplebalance.get_currency_units('USD')renvoie le montant Decimal en USD). Comme un agrégat de requête, le solde conserve chaque devise séparément. Cependant, utiliser la requête est plus simple dans la plupart des cas. -
Vérifiez le seuil : comparez le solde à votre limite prédéfinie. S'il est en dessous, déclenchez une alerte.
-
Déclenchez la notification : cela peut être aussi simple qu'imprimer un avertissement dans la console, mais pour de vraies alertes, vous pourriez envoyer un e-mail ou une notification push. Vous pouvez vous intégrer à l'e-mail (via
smtplib) ou à un service comme IFTTT ou l'API webhook de Slack pour pousser l'alerte. Par exemple :if balance < 1000: send_email("Low balance alert", f"Account XYZ balance is {balance}")(Implémentez
send_emailavec les détails de votre serveur de messagerie.)
En exécutant ce script quotidiennement (via une tâche cron ou le Planificateur de tâches Windows), vous obtiendrez des avertissements proactifs. Comme il utilise le grand livre, il peut prendre en compte toutes les transactions, y compris celles que vous venez d'ajouter.
Échéances de paiement à venir
Si vous utilisez Beancount pour suivre des factures ou des échéances, vous pouvez marquer les paiements futurs et demander aux scripts de vous les rappeler. Deux façons de représenter les obligations à venir dans Beancount :
-
Événements : Beancount prend en charge une directive
eventpour des notes datées arbitraires. Par exemple :2025-05-10 event "BillDue" "Mortgage payment due"Cela n'affecte pas les soldes mais enregistre une date avec un libellé. Un script peut parcourir
entriesà la recherche d'écrituresEventoùEvent.type == "BillDue"(ou tout type personnalisé que vous choisissez) et vérifier si la date se situe dans, disons, les 7 prochains jours à partir d'aujourd'hui. Si oui, déclenchez une alerte (e-mail, notification ou même une popup). -
Transactions futures : certaines personnes saisissent des transactions datées dans le futur (post-datées) pour des choses comme des paiements planifiés. Celles-ci n'apparaîtront pas dans les soldes avant que la date ne passe (sauf si vous exécutez des rapports à des dates futures). Un script peut rechercher les transactions datées dans un futur proche et les lister.
En utilisant ces éléments, vous pourriez créer un script « pense-bête » qui, lorsqu'il est exécuté, produit une liste de tâches ou de factures à échéance proche. Intégrez-le à une API comme Google Calendar ou un gestionnaire de tâches si vous souhaitez y créer automatiquement des rappels.
Détection d'anomalies
Au-delà des seuils ou des dates connus, vous pouvez scripter des alertes personnalisées pour des schémas inhabituels. Par exemple, si une dépense normalement mensuelle n'a pas eu lieu (peut-être avez-vous oublié de payer une facture), ou si les dépenses d'une catégorie sont anormalement élevées ce mois-ci, votre script pourrait le signaler. Cela implique généralement d'interroger les données récentes et de les comparer à l'historique (ce qui peut être un sujet avancé – éventuellement en recourant aux statistiques ou au ML).
En pratique, de nombreux utilisateurs s'appuient sur le rapprochement pour détecter les anomalies (transactions inattendues). Si vous recevez des notifications bancaires (comme des e-mails pour chaque transaction), vous pourriez les analyser avec un script et les ajouter automatiquement à Beancount, ou au moins vérifier qu'elles sont enregistrées. Un passionné a même configuré sa banque pour envoyer des e-mails d'alerte de transaction, avec le projet de les analyser et de les ajouter automatiquement au grand livre. Ce type d'alerte pilotée par les événements peut garantir qu'aucune transaction ne passe inaperçue.
Extension de Fava avec des plugins et vues personnalisés
Fava est déjà scriptable grâce à son système d'extensions. Si vous souhaitez que votre automatisation ou vos rapports s'intègrent directement à l'interface web, vous pouvez écrire une extension Fava (aussi appelée plugin) en Python.
Comment fonctionnent les extensions Fava : une extension est un module Python qui définit une classe héritant de fava.ext.FavaExtensionBase. Vous l'enregistrez dans votre fichier Beancount via une option personnalisée. Par exemple, si vous avez un fichier myextension.py avec une classe MyAlerts(FavaExtensionBase), vous pouvez l'activer en ajoutant à votre grand livre :
1970-01-01 custom "fava-extension" "myextension"Lorsque Fava se charge, il importera ce module et initialisera votre classe MyAlerts.
Les extensions peuvent faire plusieurs choses :
- Hooks : elles peuvent se greffer sur les événements du cycle de vie de Fava. Par exemple,
after_load_file()est appelé après le chargement du grand livre. Vous pourriez l'utiliser pour exécuter des vérifications ou précalculer des données. Si vous vouliez implémenter la vérification de solde faible à l'intérieur de Fava,after_load_filepourrait itérer sur les soldes de compte et éventuellement stocker des avertissements (bien que leur affichage dans l'interface puisse demander un peu plus de travail, comme lever une FavaAPIError ou utiliser Javascript pour afficher une notification). - Rapports/pages personnalisés : si votre classe d'extension définit un attribut
report_title, Fava ajoutera une nouvelle page dans la barre latérale pour celui-ci. Vous fournissez ensuite un template (HTML/Jinja2) pour le contenu de cette page. C'est ainsi que vous créez des vues entièrement nouvelles, comme un tableau de bord ou une synthèse que Fava n'a pas par défaut. L'extension peut rassembler les données dont elle a besoin (vous pouvez accéder àself.ledgerqui contient toutes les écritures, soldes, etc.) puis rendre le template.
Par exemple, l'extension intégrée portfolio_list dans Fava ajoute une page listant les positions de votre portefeuille. Les extensions communautaires vont plus loin :
- Tableaux de bord : le plugin fava-dashboards permet de définir des graphiques et des panneaux personnalisés (à l'aide de bibliothèques comme Apache ECharts). Il lit une configuration YAML de requêtes à exécuter, les exécute via Beancount et génère une page de tableau de bord dynamique dans Fava. En essence, il relie les données Beancount et une bibliothèque de graphiques JavaScript pour produire des visualisations interactives.
- Analyse de portefeuille : l'extension PortfolioSummary (contribution d'utilisateur) calcule des synthèses d'investissement (regroupement de comptes, calcul de l'IRR, etc.) et les affiche dans l'interface de Fava.
- Revue de transactions : une autre extension, fava-review, aide à revoir les transactions dans le temps (par exemple pour s'assurer que vous n'avez manqué aucun reçu).
Pour créer vous-même une extension simple, commencez par hériter de FavaExtensionBase. Par exemple, une extension minimale qui ajoute une page pourrait ressembler à :
from fava.ext import FavaExtensionBase
class HelloReport(FavaExtensionBase):
report_title = "Hello World"
def __init__(self, ledger, config):
super().__init__(ledger, config)
# any initialization, perhaps parse config if provided
def after_load_file(self):
# (optional) run after ledger is loaded
print("Ledger loaded with", len(self.ledger.entries), "entries")Si vous placiez ceci dans hello.py et ajoutiez custom "fava-extension" "hello" à votre grand livre, Fava afficherait une nouvelle page « Hello World » (vous auriez aussi besoin d'un fichier template HelloReport.html dans un sous-dossier templates pour définir le contenu de la page, sauf si l'extension n'utilise que des hooks). Le template peut utiliser les données que vous attachez à la classe d'extension. Fava utilise des templates Jinja2, donc vous pourriez rendre vos données dans un tableau HTML ou un graphique dans ce template.
Remarque : le système d'extensions de Fava est puissant mais considéré comme « instable » (sujet à changement). Il exige une certaine familiarité avec le développement web (HTML/JS) si vous créez des pages personnalisées. Si votre objectif est simplement d'exécuter des scripts ou des analyses, il pourrait être plus simple de les conserver comme scripts externes. Utilisez les extensions Fava lorsque vous voulez une expérience intégrée sur mesure pour votre workflow.
Intégration d'API et de données tierces
L'un des avantages des workflows scriptables est la possibilité d'intégrer des données externes. Voici les intégrations courantes :
Pour les prix de valorisation hébergés, Live Prices propose des includes gérés sans script planifié de récupération des prix. Choisissez les paires d'actifs prises en charge et une devise de cotation dans le sélecteur. Les workflows locaux basés sur des fichiers ci-dessous restent utiles pour Beancount en amont, Fava et des rapports reproductibles. Une actualisation gérée ne crée pas de commit Git dans votre grand livre.
-
Taux de change et matières premières : Beancount en amont ne récupère pas les prix lui-même, mais il fournit une directive
pricepour que vous fournissiez les taux. Vous pouvez automatiser la récupération de ces prix. Par exemple, un script peut interroger une API (Yahoo Finance, Alpha Vantage, etc.) pour le dernier taux de change ou cours d'action et ajouter une écriture de prix à votre grand livre :2025-04-30 price BTC 30000 USD 2025-04-30 price EUR 1.10 USDIl existe des outils comme
bea price, soutenus par Beanprice dans le moteur géré, qui récupèrent les cotations quotidiennes et les produisent au format Beancount. Vous pourriez l'activer une fois avecbea engine enable beanprice, puis planifierbea price main.beancountpour s'exécuter chaque nuit afin de mettre à jour un fichier includeprices.beancount. Ou utilisez Python : par exemple, avec la bibliothèquerequestspour appeler une API. La documentation de Beancount suggère que pour les actifs cotés en bourse, vous pouvez « invoquer du code qui téléchargera les prix et écrira les directives pour vous ». En d'autres termes, laissez un script faire la recherche et insérer les lignesprice, plutôt que de le faire manuellement. -
Données de portefeuille d'actions : comme pour les taux de change, vous pouvez vous intégrer à des API pour récupérer des données détaillées sur les actions ou les dividendes. Par exemple, l'API Yahoo Finance (ou des bibliothèques communautaires comme
yfinance) peut récupérer des données historiques pour un ticker. Un script pourrait mettre à jour votre grand livre avec l'historique mensuel des prix pour chaque action que vous détenez, permettant des rapports historiques précis de la valeur de marché. Certaines extensions personnalisées (comme fava_investor) récupèrent même les données de prix à la volée pour l'affichage, mais le plus simple est d'importer régulièrement les prix dans le grand livre. -
API bancaires (Open Banking/Plaid) : au lieu de télécharger des CSV, vous pouvez utiliser des API pour récupérer les transactions automatiquement. Des services comme Plaid agrègent les comptes bancaires et permettent un accès programmatique aux transactions. Dans une configuration avancée, vous pourriez avoir un script Python qui utilise l'API de Plaid pour récupérer les nouvelles transactions quotidiennement et les enregistrer dans un fichier (ou les importer directement dans le grand livre). Un utilisateur avancé a construit un système où Plaid alimente son pipeline d'import, rendant sa comptabilité presque automatique. Il note que « rien ne vous empêche de vous inscrire à l'API Plaid et de faire la même chose localement » – c'est-à-dire que vous pouvez écrire un script local pour obtenir les données bancaires, puis utiliser votre logique d'importateur Beancount pour les analyser en écritures de grand livre. Certaines régions disposent d'API d'open banking fournies par les banques ; celles-ci pourraient être utilisées de la même manière.
-
Autres API : vous pourriez intégrer des outils de budgétisation (exportant les budgets prévus pour les comparer aux chiffres réels dans Beancount), ou utiliser une API OCR pour lire les reçus et les faire correspondre automatiquement aux transactions. Comme vos scripts ont un accès complet à l'écosystème Python, vous pouvez intégrer tout, des services de messagerie (pour envoyer des alertes) à Google Sheets (par exemple mettre à jour une feuille avec des métriques financières mensuelles) en passant par les applications de messagerie (vous envoyer un rapport de synthèse via un bot Telegram).
Lorsque vous utilisez des API tierces, rappelez-vous de sécuriser vos identifiants (utilisez des variables d'environnement ou des fichiers de configuration pour les clés API) et de gérer les erreurs (problèmes réseau, indisponibilité d'API) avec élégance dans vos scripts. Il est souvent sage de mettre en cache les données (par exemple, stocker les taux de change récupérés pour ne pas redemander le même taux historique à plusieurs reprises).
Bonnes pratiques pour des scripts modulaires et maintenables
Au fur et à mesure que vous développez des workflows scriptables, gardez votre code organisé et robuste :
-
Modularité : répartissez les différentes préoccupations dans différents scripts ou modules. Par exemple, ayez des scripts séparés pour « l'import/rapprochement des données », la « génération de rapports » et les « alertes ». Vous pouvez même créer un petit paquet Python pour votre grand livre avec des modules comme
ledger_import.py,ledger_reports.py, etc. Cela rend chaque partie plus facile à comprendre et à tester. -
Configuration : évitez de coder en dur les valeurs. Utilisez un fichier de configuration ou des variables en haut du script pour des choses comme les noms de compte, les seuils, les clés API, les plages de dates, etc. Cela permet de les ajuster facilement sans modifier le code en profondeur. Par exemple, définissez
LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000}en haut, et votre script d'alerte peut parcourir ce dictionnaire. -
Tests : traitez votre automatisation financière comme du code critique – parce qu'elle l'est ! Écrivez des tests pour la logique complexe. Beancount fournit quelques aides de test (utilisées en interne pour tester les importateurs) que vous pouvez exploiter pour simuler des entrées de grand livre. Même sans framework sophistiqué, vous pouvez avoir un CSV factice et des transactions attendues, et affirmer que votre script d'import produit les bonnes écritures. Si vous utilisez
pytest, vous pouvez intégrer facilement ces tests (comme Alex Watt l'a fait via une commandejust testenveloppant pytest). -
Contrôle de version : gardez votre grand livre et vos scripts sous contrôle de version (git). Cela vous donne non seulement des sauvegardes et un historique, mais vous encourage à faire des changements de manière contrôlée. Vous pouvez étiqueter les versions de vos « scripts financiers » ou examiner les différences lors du débogage d'un problème. Certains utilisateurs suivent même leurs enregistrements financiers dans Git pour voir les changements au fil du temps. Faites juste attention à ignorer les données sensibles (comme les fichiers de relevé bruts ou les clés API) dans votre dépôt.
-
Documentation : documentez vos workflows personnalisés pour votre futur vous. Un README dans votre dépôt expliquant comment configurer l'environnement, comment exécuter chaque script et ce que chacun fait sera inestimable après plusieurs mois. Commentez aussi votre code, en particulier toute logique comptable ou interaction API non évidente.
-
Maintenance des plugins Fava : si vous écrivez une extension Fava, gardez-la simple. Fava pourrait changer, donc des extensions plus petites avec une fonctionnalité ciblée sont plus faciles à mettre à jour. Évitez de dupliquer trop de logique – utilisez le moteur de requête de Beancount ou les fonctions d'aide existantes autant que possible, plutôt que de coder en dur des calculs qui pourraient être sensibles aux changements du grand livre.
-
Sécurité : comme vos scripts peuvent manipuler des données sensibles et se connecter à des services externes, traitez-les avec soin. N'exposez pas les clés API et envisagez d'exécuter votre automatisation sur une machine sécurisée. Si vous utilisez une solution hébergée ou le cloud (comme planifier des GitHub Actions ou un serveur pour exécuter Fava), assurez-vous que les données de votre grand livre sont chiffrées au repos et que vous êtes à l'aise avec les implications de confidentialité.
En suivant ces pratiques, vous vous assurez que votre workflow reste fiable même lorsque vos finances (et les outils eux-mêmes) évoluent. Vous voulez des scripts que vous pouvez réutiliser année après année, avec un minimum d'ajustements.
Conclusion
Beancount et Fava offrent une plateforme puissante et flexible permettant aux utilisateurs avertis en technologie de personnaliser complètement le suivi de leurs finances personnelles. En écrivant des scripts Python, vous pouvez automatiser des tâches fastidieuses comme le rapprochement des relevés, produire des rapports riches adaptés à vos besoins et garder une longueur d'avance sur vos finances grâce à des alertes opportunes. Nous avons couvert un éventail d'exemples du basique à l'avancé – en commençant par de simples requêtes et imports CSV, et en passant à des plugins Fava complets et des intégrations d'API externes. Au fur et à mesure de leur mise en œuvre, commencez simplement et construisez progressivement. Même quelques petits scripts d'automatisation peuvent économiser des heures de travail et améliorer considérablement la précision. Et rappelez-vous, comme tout est en texte brut et en Python, vous avez le contrôle total – votre système financier grandit avec vous, pliant à vos besoins spécifiques. Bon scripting !
Sources : Les techniques ci-dessus sont tirées de la documentation de Beancount et d'expériences de la communauté. Pour aller plus loin, consultez la documentation officielle de Beancount, les guides et blogs communautaires, et le dépôt Awesome Beancount pour des liens vers des plugins et outils utiles.