Ga naar hoofdinhoud

Scriptable Workflows met Beancount en Fava

Beancount (een plain-text double-entry accounting tool) en Fava (de web interface) zijn zeer uitbreidbaar en scriptable. Hun ontwerp stelt je in staat om financiële taken te automatiseren, aangepaste rapporten te genereren en alerts in te stellen door Python scripts te schrijven. In de woorden van een gebruiker: “Ik vind het erg fijn om mijn data in zo'n handig formaat te hebben, en ik vind het fijn dat ik dingen naar hartenlust kan automatiseren. Er is geen API zoals een bestand op je schijf; het is gemakkelijk te integreren.” Deze handleiding zal je door het maken van scriptable workflows leiden—van beginner-vriendelijke automatisering tot geavanceerde Fava plugins.

Aan de slag: Beancount uitvoeren als een Python Script

scriptable-workflows

Voordat je in specifieke taken duikt, zorg ervoor dat je Beancount hebt geïnstalleerd (bijv. via pip install beancount). Aangezien Beancount in Python is geschreven, kun je het als een library gebruiken in je eigen scripts. De algemene aanpak is:

  • Laad je Beancount grootboek: Gebruik Beancount's loader om het .beancount bestand te parsen naar Python objecten. Bijvoorbeeld:

    from beancount import loader
    entries, errors, options_map = loader.load_file("myledger.beancount")
    if errors:
    print("Errors:", errors)

    Dit geeft je een lijst met entries (transacties, saldi, enz.) en een options_map met metadata. Al je accounts, transacties en saldi zijn nu toegankelijk in code.

  • Maak gebruik van Beancount Query Language (BQL): In plaats van handmatig te itereren, kun je SQL-achtige queries uitvoeren op de data. Om bijvoorbeeld de totale uitgaven per maand te krijgen, kun je de query API gebruiken:

    from beancount.query import query
    q = query.Query(entries, options_map)
    result = q.query("SELECT month, sum(position) WHERE account ~ 'Expenses' GROUP BY month")
    print(result)

    Dit gebruikt Beancount's Query systeem om data te aggregeren. (Onder de motorkap is dit vergelijkbaar met wat het bean-query commando doet, maar hier gebruik je het in een script.) De Beancount auteur merkt zelfs op dat je het bestand kunt laden en run_query() direct via de Python API kunt aanroepen, waardoor je geen externe commando's in een loop hoeft aan te roepen.

  • Stel een projectstructuur op: Organiseer je scripts naast je grootboek. Een gebruikelijke indeling is om directories te hebben voor importers (om externe data op te halen/parsen), reports of queries (voor analysescripts) en documents (om gedownloade overzichten op te slaan). Een gebruiker bewaart bijvoorbeeld:

    • importers/ – aangepaste Python import scripts (met tests),
    • queries/ – scripts om rapporten te genereren (uitvoerbaar via python3 queries/...),
    • documents/ – gedownloade bank CSV's/PDF's georganiseerd per account.

Met deze setup kun je scripts handmatig uitvoeren (bijv. python3 queries/cash_flow.py) of ze plannen (via cron of een task runner) om je workflow te automatiseren.

Reconciliatie Taken Automatiseren

Reconciliatie betekent ervoor zorgen dat je grootboek overeenkomt met externe records (bankafschriften, creditcard rapporten, enz.). Beancount's plain-text grootboek en Python API maken het mogelijk om een groot deel van dit proces te automatiseren.

Transacties Importeren en Matchen (Beginner)

Voor beginners is de aanbevolen aanpak om Beancount's importer plugins te gebruiken. Je schrijft een kleine Python class die het Beancount importer protocol volgt om een gegeven formaat (CSV, OFX, PDF, enz.) te parsen en transacties te produceren. Gebruik vervolgens het bean-extract commando of een script om deze importers toe te passen:

  • Schrijf een importer (een Python class met methoden zoals identify(), extract()) voor het CSV formaat van je bank. Beancount's documentatie biedt een handleiding en voorbeelden.
  • Gebruik bean-extract in een script of Makefile (zoals het justfile voorbeeld) om nieuwe overzichten te parsen. Een workflow voert bijvoorbeeld bean-extract uit op alle bestanden in ~/Downloads en voert transacties uit naar een tijdelijk bestand.
  • Controleer en kopieer handmatig transacties van het tijdelijke bestand naar je hoofd grootboek, en voer vervolgens bean-check uit om ervoor te zorgen dat de saldi reconciliëren.

Hoewel dit proces nog steeds een beoordelingsstap omvat, wordt veel van het zware werk van het parsen en formatteren van entries geautomatiseerd. Importer scripts kunnen ook automatisch categorieën toewijzen en zelfs balans assertions (verklaringen van verwachte saldi) instellen om discrepanties op te vangen. Na het importeren kun je bijvoorbeeld een regel hebben als 2025-04-30 balance Assets:Bank:Checking 1234.56 USD die het eindsaldo bevestigt. Wanneer je bean-check uitvoert, zal Beancount verifiëren dat al deze balans assertions correct zijn, en eventuele fouten signaleren als transacties ontbreken of gedupliceerd zijn. Dit is een best practice: genereer automatisch balans assertions voor elke overzichtsperiode om de computer onverzoende verschillen te laten opsporen.

Aangepaste Reconciliatie Scripts (Intermediate)

Voor meer controle kun je een aangepast Python script schrijven om de transactielijst van een bank (CSV of via API) te vergelijken met je grootboek entries:

  1. Lees de externe data: Parse het CSV bestand van de bank met behulp van Python's csv module (of Pandas). Normaliseer de data naar een lijst met transacties, bijv. elk met een datum, bedrag en beschrijving.
  2. Laad grootboek transacties: Gebruik loader.load_file zoals eerder getoond om alle grootboek entries te krijgen. Filter deze lijst op het account van belang (bijv. je betaalrekening) en eventueel de datumbereik van het overzicht.
  3. Vergelijk en vind mismatches:
  • Controleer voor elke externe transactie of een identieke entry bestaat in het grootboek (match op datum en bedrag, misschien beschrijving). Indien niet gevonden, markeer het als "nieuw" en voer het eventueel uit als een Beancount-geformatteerde transactie ter beoordeling.
  • Identificeer omgekeerd alle grootboek entries in dat account die niet in de externe bron voorkomen – dit kunnen data entry fouten zijn of transacties die nog niet door de bank zijn verwerkt.
  1. Voer resultaten uit: Print een rapport of maak een nieuw .beancount fragment met de ontbrekende transacties.

Als voorbeeld doet een community script genaamd reconcile.py precies dit: gegeven een Beancount bestand en een input CSV, print het een lijst met nieuwe transacties die moeten worden geïmporteerd, evenals alle bestaande grootboek postings die niet in de input staan (mogelijk een teken van verkeerde classificatie). Met zo'n script kan maandelijkse reconciliatie zo eenvoudig zijn als het uitvoeren ervan en vervolgens de voorgestelde transacties aan je grootboek toevoegen. Een Beancount gebruiker merkt op dat ze "elke maand een reconciliatie proces uitvoeren op alle accounts" en een groeiende verzameling Python code gebruiken om veel van het handmatige werk bij het importeren en reconciliëren van data te elimineren.

Tip: Maak tijdens de reconciliatie gebruik van Beancount's tools voor nauwkeurigheid:

  • Gebruik balans assertions zoals vermeld, om geautomatiseerde controles op account saldi te hebben.
  • Gebruik de pad directive indien gewenst, die automatisch balancerende entries kan invoegen voor kleine afrondingsverschillen (gebruik met voorzichtigheid).
  • Schrijf unit tests voor je importer of reconciliatie logica (Beancount biedt test helpers). Een workflow omvatte bijvoorbeeld het nemen van een voorbeeld CSV, het schrijven van failing tests met verwachte transacties, en vervolgens het implementeren van de importer totdat alle tests slaagden. Dit zorgt ervoor dat je import script correct werkt voor verschillende gevallen.

Aangepaste Rapporten en Samenvattingen Genereren

Hoewel Fava veel standaard rapporten biedt (Winst- en verliesrekening, Balans, enz.), kun je aangepaste rapporten maken met behulp van scripts. Deze kunnen variëren van eenvoudige console uitvoer tot rijke geformatteerde bestanden of grafieken.

Data Opvragen voor Rapporten (Beginner)

Op een basisniveau kun je de Beancount Query Language (BQL) gebruiken om samenvattende data te krijgen en deze te printen of op te slaan. Bijvoorbeeld:

  • Cash Flow Samenvatting: Gebruik een query om de netto cash flow te berekenen. "Cash flow" kan worden gedefinieerd als de verandering in saldo van bepaalde accounts over een periode. Met behulp van BQL kun je het volgende doen:

    SELECT year, month, sum(amount)
    WHERE account LIKE 'Income:%' OR account LIKE 'Expenses:%'
    GROUP BY year, month

    Dit zou alle inkomsten en uitgaven postings per maand netten. Je kunt dit uitvoeren via de bean-query CLI of via de Python API (query.Query zoals eerder getoond) en vervolgens het resultaat formatteren.

  • Categorie Uitgaven Rapport: Query totale uitgaven per categorie:

    SELECT account, round(sum(position), 2)
    WHERE account ~ 'Expenses'
    GROUP BY account
    ORDER BY sum(position) ASC

    Dit levert een tabel op van uitgaven per categorie. Je kunt meerdere queries uitvoeren in een script en de resultaten uitvoeren als tekst, CSV of zelfs JSON voor verdere verwerking.

Een gebruiker vond het “triviaal” om financiële data te analyseren met Fava of met scripts, en citeerde dat ze één Python script gebruiken om data uit Beancount te halen via de Query Language en het vervolgens in een Pandas DataFrame te plaatsen om een aangepast rapport voor te bereiden. Je kunt bijvoorbeeld maandelijkse totalen ophalen met een query en vervolgens Pandas/Matplotlib gebruiken om een cash flow grafiek in de loop van de tijd te plotten. De combinatie van BQL en data science libraries stelt je in staat om rapporten te bouwen die verder gaan dan wat Fava standaard biedt.

Geavanceerde Rapportage (Grafieken, Performance, enz.)

Voor meer geavanceerde behoeften kunnen je scripts metrics berekenen zoals investeringsperformance of visuele uitvoer creëren:

  • Investeringsperformance (IRR/XIRR): Aangezien je grootboek alle cash flows bevat (aankopen, verkopen, dividenden), kun je de portfolio rendementen berekenen. Je kunt bijvoorbeeld een script schrijven dat transacties van je beleggingsrekeningen filtert en vervolgens de Internal Rate of Return berekent. Er zijn libraries (of formules) om IRR te berekenen gegeven cash flow data. Sommige community-ontwikkelde Fava extensies (zoals PortfolioSummary of fava_investor) doen precies dit, het berekenen van IRR en andere metrics voor investeringsportefeuilles. Als een script kun je een IRR functie (van NumPy of je eigen) gebruiken op de reeks bijdragen/opnames plus de eindwaarde.

  • Multi-periode of Aangepaste Metrics: Wil je een rapport van je spaargraad (verhouding van sparen tot inkomen) elke maand? Een Python script kan het grootboek laden, alle Inkomsten accounts en alle Uitgaven accounts optellen, en vervolgens sparen = inkomen - uitgaven en het percentage berekenen. Dit kan een mooie tabel opleveren of zelfs een HTML/Markdown rapport genereren voor je records.

  • Visualisatie: Je kunt grafieken genereren buiten Fava. Gebruik bijvoorbeeld matplotlib of altair in een script om een netto waarde in de loop van de tijd grafiek te maken, met behulp van grootboek data. Omdat het grootboek alle historische saldi heeft (of je kunt ze accumuleren door entries te itereren), kun je tijdreeks plots produceren. Sla deze grafieken op als afbeeldingen of interactieve HTML. (Als je de voorkeur geeft aan visuals in de app, zie de Fava extensie sectie hieronder voor het toevoegen van grafieken binnen Fava.)

Output Opties: Bepaal hoe je het rapport wilt leveren:

  • Voor eenmalige analyses kan printen naar het scherm of opslaan in een CSV/Excel bestand voldoende zijn.
  • Voor dashboards kun je overwegen om een HTML bestand te genereren met de data (mogelijk met behulp van een templating library zoals Jinja2 of zelfs gewoon Markdown schrijven) dat je in een browser kunt openen.
  • Je kunt ook integreren met Jupyter Notebooks voor een interactieve rapportage omgeving, hoewel dat meer voor exploratie is dan voor automatisering.

Alerts Triggeren vanuit je Grootboek

Een ander krachtig gebruik van scriptable workflows is het instellen van alerts op basis van condities in je financiële data. Omdat je grootboek regelmatig wordt bijgewerkt (en toekomstige items zoals aankomende rekeningen of budgetten kan bevatten), kun je het scannen met een script en een melding krijgen van belangrijke gebeurtenissen.

Lage Account Saldo Waarschuwingen

Om rood staan te voorkomen of om een minimum saldo te behouden, wil je misschien een alert als een account (bijv. betaalrekening of spaarrekening) onder een bepaalde drempel valt. Hier is hoe je dit kunt implementeren:

  1. Bepaal huidige saldi: Na het laden van entries via de loader, bereken het laatste saldo van de accounts van belang. Je kunt dit doen door postings te aggregeren of een query te gebruiken. Gebruik bijvoorbeeld een BQL query voor het saldo van een specifiek account:

    SELECT sum(position) WHERE account = 'Assets:Bank:Checking'

    Dit geeft het huidige saldo van dat account terug (som van al zijn postings). Als alternatief kun je Beancount's interne functies gebruiken om een balans op te stellen. Bijvoorbeeld:

    from beancount.core import realization
    tree = realization.realize(entries, options_map)
    acct = realization.get_or_create(tree, "Assets:Bank:Checking")
    balance = acct.balance # an Inventory of commodities

    Haal vervolgens de numerieke waarde eruit (bijv. balance.get_currency_units('USD') kan de Decimal geven). Het gebruik van de query is echter eenvoudiger in de meeste gevallen.

  2. Controleer drempel: Vergelijk het saldo met je vooraf gedefinieerde limiet. Zo ja, trigger een alert.

  3. Trigger notificatie: Dit kan zo simpel zijn als het printen van een waarschuwing naar de console, maar voor echte alerts kun je een e-mail of push notificatie sturen. Je kunt integreren met e-mail (via smtplib) of een service zoals IFTTT of Slack's webhook API om de alert te pushen. Bijvoorbeeld:

    if balance < 1000:
    send_email("Low balance alert", f"Account XYZ balance is {balance}")

    (Implementeer send_email met je e-mail server details.)

Door dit script dagelijks uit te voeren (via een cron job of Windows Task Scheduler), krijg je proactieve waarschuwingen. Omdat het het grootboek gebruikt, kan het alle transacties overwegen, inclusief de transacties die je zojuist hebt toegevoegd.

Aankomende Betalingstermijnen

Als je Beancount gebruikt om rekeningen of deadlines bij te houden, kun je toekomstige betalingen markeren en scripts je eraan laten herinneren. Twee manieren om aankomende verplichtingen in Beancount weer te geven:

  • Events: Beancount ondersteunt een event directive voor willekeurige gedateerde notities. Bijvoorbeeld:

    2025-05-10 event "BillDue" "Mortgage payment due"

    Dit heeft geen invloed op de saldi, maar registreert een datum met een label. Een script kan entries scannen op Event entries waar Event.type == "BillDue" (of een aangepast type dat je kiest) en controleren of de datum binnen, zeg, de komende 7 dagen vanaf vandaag ligt. Zo ja, trigger een alert (e-mail, notificatie of zelfs een popup).

  • Toekomstige Transacties: Sommige mensen voeren toekomstige transacties in (gedateerd in de toekomst) voor dingen zoals geplande betalingen. Deze worden niet weergegeven in saldi totdat de datum is verstreken (tenzij je rapporten uitvoert vanaf toekomstige datums). Een script kan zoeken naar transacties die in de nabije toekomst zijn gedateerd en ze weergeven.

Met behulp hiervan kun je een "tickler" script maken dat, wanneer het wordt uitgevoerd, een lijst met taken of rekeningen oplevert die binnenkort verschuldigd zijn. Integreer met een API zoals Google Calendar of een taakbeheerder als je automatisch herinneringen daar wilt maken.

Anomalie Detectie

Naast bekende drempels of datums, kun je aangepaste alerts scripten voor ongebruikelijke patronen. Als bijvoorbeeld een normaal gesproken maandelijkse uitgave niet heeft plaatsgevonden (misschien ben je vergeten een rekening te betalen), of als de uitgaven van een categorie deze maand abnormaal hoog zijn, kan je script dit signaleren. Dit omvat doorgaans het opvragen van recente data en het vergelijken met de geschiedenis (wat een geavanceerd onderwerp kan zijn – mogelijk met behulp van statistieken of ML).

In de praktijk vertrouwen veel gebruikers op reconciliatie om anomalieën op te vangen (onverwachte transacties). Als je bank notificaties ontvangt (zoals e-mails voor elke transactie), kun je deze parsen met een script en ze automatisch toevoegen aan Beancount, of ze in ieder geval verifiëren dat ze zijn vastgelegd. Een enthousiasteling configureerde zelfs hun bank om e-mail alerts voor transacties te sturen, met het plan om ze te parsen en automatisch aan het grootboek toe te voegen. Dit soort event-gedreven alerts kan ervoor zorgen dat geen enkele transactie ongeregistreerd blijft.

Fava Uitbreiden met Aangepaste Plugins en Views

Fava is al scriptable via zijn extensie systeem. Als je wilt dat je automatisering of rapporten rechtstreeks in de web interface worden geïntegreerd, kun je een Fava extensie (ook wel een plugin genoemd) in Python schrijven.

Hoe Fava Extensies Werken: Een extensie is een Python module die een class definieert die overerft van fava.ext.FavaExtensionBase. Je registreert het in je Beancount bestand via een aangepaste optie. Als je bijvoorbeeld een bestand myextension.py hebt met een class MyAlerts(FavaExtensionBase), kun je het inschakelen door het volgende aan je grootboek toe te voegen:

1970-01-01 custom "fava-extension" "myextension"

Wanneer Fava laadt, zal het die module importeren en je MyAlerts class initialiseren.

Extensies kunnen verschillende dingen doen:

  • Hooks: Ze kunnen inhaken op gebeurtenissen in de lifecycle van Fava. after_load_file() wordt bijvoorbeeld aangeroepen nadat het grootboek is geladen. Je kunt dit gebruiken om controles uit te voeren of data vooraf te berekenen. Als je de low-balance controle binnen Fava wilt implementeren, kan after_load_file over account saldi itereren en misschien waarschuwingen opslaan (hoewel het tonen ervan aan de UI misschien wat meer werk vereist, zoals het genereren van een FavaAPIError of het gebruik van Javascript om een notificatie weer te geven).
  • Aangepaste Rapporten/Pagina's: Als je extensie class een report_title attribuut instelt, zal Fava een nieuwe pagina in de sidebar toevoegen. Je levert vervolgens een template (HTML/Jinja2) voor de inhoud van die pagina. Dit is hoe je volledig nieuwe views maakt, zoals een dashboard of samenvatting die Fava standaard niet heeft. De extensie kan alle data verzamelen die het nodig heeft (je hebt toegang tot self.ledger die alle entries, saldi, enz. heeft) en vervolgens de template renderen.

De ingebouwde portfolio_list extensie in Fava voegt bijvoorbeeld een pagina toe die je portfolio posities weergeeft. Community extensies gaan verder:

  • Dashboards: De fava-dashboards plugin staat het definiëren van aangepaste grafieken en panels toe (met behulp van libraries zoals Apache ECharts). Het leest een YAML config van queries om uit te voeren, voert ze uit via Beancount en genereert een dynamische dashboard pagina in Fava. In wezen verbindt het Beancount data en een JavaScript grafiek library om interactieve visualisaties te produceren.
  • Portfolio analyse: De PortfolioSummary extensie (door gebruikers bijgedragen) berekent investeringssamenvattingen (het groeperen van accounts, het berekenen van IRR, enz.) en toont ze in Fava's UI.
  • Transactie beoordeling: Een andere extensie, fava-review, helpt bij het beoordelen van transacties in de loop van de tijd (bijv. om ervoor te zorgen dat je geen kwitanties hebt gemist).

Om zelf een eenvoudige extensie te maken, begin met het overerven van FavaExtensionBase. Een minimale extensie die een pagina toevoegt, kan er bijvoorbeeld zo uitzien:

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")

Als je dit in hello.py hebt geplaatst en custom "fava-extension" "hello" aan je grootboek hebt toegevoegd, zou Fava een nieuwe "Hello World" pagina weergeven (je zou ook een template bestand HelloReport.html in een templates subfolder nodig hebben om de pagina inhoud te definiëren, tenzij de extensie alleen hooks gebruikt). De template kan data gebruiken die je aan de extensie class koppelt. Fava gebruikt Jinja2 templates, dus je kunt je data in een HTML tabel of grafiek in die template renderen.

Note: Fava's extensie systeem is krachtig, maar wordt als "onstabiel" beschouwd (kan veranderen). Het vereist enige bekendheid met web development (HTML/JS) als je aangepaste pagina's maakt. Als je doel is om simpelweg scripts of analyses uit te voeren, kan het gemakkelijker zijn om ze als externe scripts te bewaren. Gebruik Fava extensies als je een op maat gemaakte in-app ervaring voor je workflow wilt.

Integratie van Derde Partij API's en Data

Een van de voordelen van scriptable workflows is de mogelijkheid om externe data op te halen. Hier zijn veelvoorkomende integraties:

  • Wisselkoersen & Commodities: Beancount haalt prijzen niet automatisch op (om rapporten deterministisch te houden), maar het biedt een Price directive om tarieven aan te leveren. Je kunt het ophalen van deze prijzen automatiseren. Een script kan bijvoorbeeld een API (Yahoo Finance, Alpha Vantage, enz.) bevragen voor de laatste wisselkoers of aandelenkoers en een prijs entry aan je grootboek toevoegen:

    2025-04-30 price BTC 30000 USD
    2025-04-30 price EUR 1.10 USD

    Er zijn tools zoals bean-price (nu een externe tool onder Beancount's umbrella) die dagelijkse koersen ophalen en ze in Beancount formaat uitvoeren. Je kunt bean-price plannen om elke avond te draaien om een prices.beancount include bestand bij te werken. Of gebruik Python: bijv. met de requests library om een API aan te roepen. Beancount's documentatie suggereert dat je voor publiekelijk verhandelde activa "code kunt aanroepen die prijzen downloadt en de directives voor je uitschrijft." Met andere woorden, laat een script de lookup doen en de price regels invoegen, in plaats van dat je het handmatig doet.

  • Aandelen Portfolio Data: Vergelijkbaar met wisselkoersen, kun je integreren met API's om gedetailleerde aandelen data of dividenden op te halen. De Yahoo Finance API (of community libraries zoals yfinance) kan bijvoorbeeld historische data voor een ticker ophalen. Een script kan je grootboek bijwerken met maandelijkse prijsgeschiedenis voor elk aandeel dat je bezit, waardoor nauwkeurige historische rapporten van de marktwaarde mogelijk zijn. Sommige aangepaste extensies (zoals fava_investor) halen zelfs prijs data on the fly op voor weergave, maar het eenvoudigste is om regelmatig prijzen in het grootboek te importeren.

  • Banking API's (Open Banking/Plaid): In plaats van CSV's te downloaden, kun je API's gebruiken om transacties automatisch op te halen. Services zoals Plaid aggregeren bankaccounts en staan programmatische toegang tot transacties toe. In een geavanceerde setup kun je een Python script hebben dat Plaid's API gebruikt om dagelijks nieuwe transacties op te halen en ze op te slaan in een bestand (of rechtstreeks naar het grootboek te importeren). Een power-user bouwde een systeem waar Plaid in hun import pipeline feeds, waardoor hun boeken bijna automatisch zijn. Ze merken op dat "niets je ervan weerhoudt om je aan te melden bij de Plaid API en hetzelfde lokaal te doen" – d.w.z. je kunt een lokaal script schrijven om bank data te krijgen en vervolgens je Beancount importer logica gebruiken om het naar grootboek entries te parsen. Sommige regio's hebben open banking API's die door banken worden geleverd; deze kunnen op dezelfde manier worden gebruikt.

  • Andere API's: Je kunt budgettering tools integreren (het exporteren van geplande budgetten om te vergelijken met actuals in Beancount), of een OCR API gebruiken om kwitanties te lezen en ze automatisch aan transacties te matchen. Omdat je scripts volledige toegang hebben tot Python's ecosysteem, kun je alles integreren, van e-mail services (voor het verzenden van alerts) tot Google Sheets (bijv. een sheet bijwerken met maandelijkse financiële metrics) tot messaging apps (stuur jezelf een samenvattend rapport via een Telegram bot).

Wanneer je third-party API's gebruikt, vergeet dan niet om je credentials te beveiligen (gebruik omgevingsvariabelen of config bestanden voor API keys) en om fouten (netwerkproblemen, API downtime) op een elegante manier in je scripts af te handelen. Het is vaak verstandig om data te cachen (sla bijvoorbeeld opgehaalde wisselkoersen op, zodat je niet herhaaldelijk dezelfde historische koers aanvraagt).

Best Practices voor Modulaire, Onderhoudbare Scripts

Naarmate je scriptable workflows uitbouwt, houd je code georganiseerd en robuust:

  • Modulariteit: Verdeel verschillende concerns over verschillende scripts of modules. Je kunt bijvoorbeeld aparte scripts hebben voor "data import/reconciliatie" vs. "rapport generatie" vs. "alerts". Je kunt zelfs een klein Python package maken voor je grootboek met modules zoals ledger_import.py, ledger_reports.py, enz. Dit maakt elk onderdeel gemakkelijker te begrijpen en te testen.

  • Configuratie: Vermijd het hard-coden van waarden. Gebruik een config bestand of top-of-script variabelen voor dingen zoals account namen, drempels, API keys, datumbereiken, enz. Dit maakt het gemakkelijk aan te passen zonder de code diepgaand te bewerken. Definieer bijvoorbeeld LOW_BALANCE_THRESHOLDS = {"Assets:Bank:Checking": 500, "Assets:Savings": 1000} bovenaan, en je alert script kan door dit dict loopen.

  • Testen: Behandel je financiële automatisering als mission-critical code – omdat het zo is! Schrijf tests voor complexe logica. Beancount biedt enkele test helpers (intern gebruikt voor importer testing) die je kunt gebruiken om grootboek inputs te simuleren. Zelfs zonder fancy frameworks kun je een dummy CSV en verwachte output transacties hebben en beweren dat je import script de juiste entries produceert. Als je pytest gebruikt, kun je deze tests gemakkelijk integreren (zoals Alex Watt deed via een just test commando dat pytest omhult).

  • Versiebeheer: Bewaar je grootboek en scripts onder versiebeheer (git). Dit geeft je niet alleen backups en geschiedenis, maar moedigt je aan om wijzigingen op een gecontroleerde manier aan te brengen. Je kunt releases van je "financieringsscripts" taggen of verschillen beoordelen bij het debuggen van een probleem. Sommige gebruikers volgen zelfs hun financiële records in Git om veranderingen in de loop van de tijd te zien. Wees voorzichtig om gevoelige data te negeren (zoals ruwe statement bestanden of API keys) in je repo.

  • Documentatie: Documenteer je aangepaste workflows voor toekomstige je. Een README in je repository die uitlegt hoe je de omgeving instelt, hoe je elk script uitvoert en wat elk script doet, zal van onschatbare waarde zijn na maanden. Commentaar ook je code, vooral niet-voor de hand liggende accounting logica of API interactie.

  • Fava Plugins Onderhoud: Als je een Fava extensie schrijft, houd het dan eenvoudig. Fava kan veranderen, dus kleinere extensies met gerichte functionaliteit zijn gemakkelijker bij te werken. Vermijd het dupliceren van te veel logica – gebruik Beancount's query engine of bestaande helper functies waar mogelijk, in plaats van hardcoding berekeningen die gevoelig kunnen zijn voor grootboek wijzigingen.

  • Beveiliging: Aangezien je scripts gevoelige data kunnen verwerken en verbinding kunnen maken met externe services, behandel ze dan met zorg. Stel geen API keys bloot en overweeg om je automatisering op een beveiligde machine uit te voeren. Als je een gehoste oplossing of cloud gebruikt (zoals het plannen van GitHub Actions of een server om Fava uit te voeren), zorg er dan voor dat je grootboek data in rust is versleuteld en dat je je comfortabel voelt met de privacy implicaties.

Door deze practices te volgen, zorg je ervoor dat je workflow betrouwbaar blijft, zelfs als je financiën (en de tools zelf) evolueren. Je wilt scripts die je jaar na jaar kunt hergebruiken, met minimale aanpassingen.

Conclusie

Beancount en Fava bieden een krachtig, flexibel platform voor tech-savvy gebruikers om hun persoonlijke financiële tracking volledig aan te passen. Door Python scripts te schrijven, kun je vervelende taken automatiseren, zoals het reconciliëren van overzichten, rijke rapporten produceren die zijn afgestemd op je behoeften, en op de hoogte blijven van je financiën met tijdige alerts. We hebben een reeks voorbeelden behandeld van basic tot geavanceerd – beginnend met eenvoudige queries en CSV imports, en gaandeweg naar volwaardige Fava plugins en externe API integraties. Naarmate je deze implementeert, begin eenvoudig en bouw geleidelijk op. Zelfs een paar kleine automatiseringsscripts kunnen uren werk besparen en de nauwkeurigheid aanzienlijk verbeteren. En onthoud, omdat alles plain text en Python is, heb je de volledige controle – je financiële systeem groeit met je mee, en past zich aan je specifieke behoeften aan. Veel plezier met scripten!

Bronnen: De bovenstaande technieken zijn ontleend aan de Beancount documentatie en community ervaringen. Zie voor verder lezen Beancount's officiële documenten, community handleidingen en blogs, en de Awesome Beancount repository voor links naar nuttige plugins en tools.