Scriptable Workflows with Beancount and Fava
Beancount (a plain-text double-entry accounting tool) and Fava (its web interface) are highly extensible and scriptable. Their design allows you to automate financial tasks, generate custom reports, and set up alerts by writing Python scripts. In the words of one user, “I really like having my data in such a convenient format, and I like that I can automate things to my heart’s content. There is no API like a file on your disk; it’s easy to integrate with.” This guide will walk through creating scriptable workflows—from beginner-friendly automation to advanced Fava plugins.
Getting Started: Running Beancount as a Python Script
Before diving into specific tasks, ensure you have Beancount installed (e.g. via pip install beancount
). Since Beancount is written in Python, you can use it as a library in your own scripts. The general approach is:
-
Load your Beancount ledger: Use Beancount’s loader to parse the
.beancount
file into Python objects. For example:from beancount import loader
entries, errors, options_map = loader.load_file("myledger.beancount")
if errors:
print("Errors:", errors)This gives you a list of
entries
(transactions, balances, etc.) and anoptions_map
with metadata. All your accounts, transactions, and balances are now accessible in code. -
Leverage Beancount Query Language (BQL): Instead of manually iterating, you can run SQL-like queries on the data. For instance, to get total expenses by month, you could use the query API:
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)This uses Beancount’s Query system to aggregate data. (Under the hood, this is similar to what the
bean-query
command does, but here you’re using it in a script.) In fact, the Beancount author notes that you can load the file and callrun_query()
directly via the Python API, avoiding the need to call external commands in a loop. -
Set up a project structure: Organize your scripts alongside your ledger. A common layout is to have directories for importers (to fetch/parse external data), reports or queries (for analysis scripts), and documents (to store downloaded statements). For example, one user keeps:
importers/
– custom Python import scripts (with tests),queries/
– scripts to generate reports (runnable viapython3 queries/...
),documents/
– downloaded bank CSVs/PDFs organized by account.
With this setup, you can run scripts manually (e.g. python3 queries/cash_flow.py
) or schedule them (via cron or a task runner) to automate your workflow.
Automating Reconciliation Tasks
Reconciliation means making sure your ledger matches external records (bank statements, credit card reports, etc.). Beancount’s plain-text ledger and Python API make it possible to automate much of this process.