clario
Turn a messy bank transaction export into a clean, explainable double-entry ledger — from the command line, in one step.
Personal finance tools either make you categorize every transaction by hand, or hide the categorization behind an opaque "smart" algorithm you can't inspect. clario takes a middle path: a transparent rule engine handles the transactions you'd recognize instantly (rent, coffee, your paycheck), and an optional Claude-powered fallback handles the rest — while always telling you why it picked an account, so you can correct it and improve your rules over time.
Features
- Deterministic first. A small, editable YAML rule file does most of the work — no API calls, no surprises, fully offline.
- Explainable AI fallback. Pass
--use-aiand clario asks Claude to categorize anything the rules missed, along with a one-sentence reason — it's a suggestion you can review, not a black box. - Plain-text, portable output. Ledgers are written in a simple beancount/ledger-style double-entry format that's easy to read, diff, and version-control.
- Spending reports.
clario reportgives you per-category totals without needing to write a ledger file at all. - No lock-in. No database, no account, no cloud sync — it reads a CSV and writes a text file.
Installation
pip install clario
To use the --use-ai fallback, install the optional extra:
pip install "clario[ai]"
export ANTHROPIC_API_KEY="your-key-here"
(Or clone the repo and run pip install -e ".[dev]" for local development —
see CONTRIBUTING.md.)
Quickstart
Given a CSV export with date, description, and amount columns:
date,description,amount
2024-01-02,Whole Foods Market,-86.42
2024-01-05,Payroll Deposit,2450.00
2024-01-10,Monthly Rent Payment,-1200.00
Convert it to a ledger:
clario convert transactions.csv --output ledger.beancount
2024-01-02 * "Whole Foods Market"
Assets:Checking -86.42
Expenses:Food:Groceries 86.42
2024-01-05 * "Payroll Deposit"
Assets:Checking 2450.00
Income:Salary -2450.00
2024-01-10 * "Monthly Rent Payment"
Assets:Checking -1200.00
Expenses:Housing:Rent 1200.00
Or just see where your money went:
clario report transactions.csv
Spending by category
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Category ┃ Total ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ Expenses:Food:Groceries │ -86.42 │
│ Expenses:Housing:Rent │ -1200.00 │
│ Income:Salary │ 2450.00 │
└──────────────────────────────┴──────────┘
Anything the default rules can't place falls into
Expenses:Uncategorized. Add a rule for it, or re-run with --use-ai to
have Claude suggest one:
clario convert transactions.csv --use-ai --output ledger.beancount
Custom rules
Rules live in a plain YAML file — copy
examples/custom_rules.yaml as a starting
point:
- match: "trader joe"
account: "Expenses:Food:Groceries"
- match: "shell|chevron|exxon"
account: "Expenses:Transport:Fuel"
regex: true
Rules are checked top to bottom; the first match wins. Use regex: true
when a plain substring match isn't enough.
clario convert transactions.csv --rules my_rules.yaml
How categorization works
flowchart LR
A[CSV transactions] --> B{Rule engine match?}
B -- yes --> D[Assign account from rule]
B -- no --> C{--use-ai set?}
C -- yes --> E[Ask Claude for account + reasoning]
C -- no --> F[Leave Uncategorized]
D --> G[Render ledger]
E --> G
F --> G
The rule engine always runs first because it's free, instant, and fully deterministic. Claude is only consulted for what's left over, and every AI-suggested account is written into the ledger as a comment explaining the reasoning, so nothing is categorized silently.
Command reference
| Command | Description |
|---|---|
clario convert CSV_PATH |
Convert a CSV into a double-entry ledger. |
clario report CSV_PATH |
Print spending totals per category. |
Run clario convert --help or clario report --help for the full list of
options (--output, --rules, --account, --use-ai, --model,
--api-key).
Development
git clone https://github.com/Antares-XB/clario.git
cd clario
pip install -e ".[dev]"
pytest --cov=clario --cov-report=term-missing
ruff check .
See CONTRIBUTING.md for details on the project layout and how to add new default rules.
Project layout
src/clario/
├── transactions.py # CSV parsing into Transaction objects
├── rules.py # Keyword/regex rule engine
├── claude_client.py # Optional Claude-powered categorizer
├── categorizer.py # Combines rules + AI, tracks match stats
├── ledger.py # Double-entry rendering and category summaries
└── cli.py # `clario convert` / `clario report` commands
License
Release files for clario 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| clario-0.1.0.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| clario-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 33.6 kB
Release files / clario-0.1.0.tar.gz
| Download URL | clario-0.1.0.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
72e2f4a75fd981e303a04afe8cdffb5cf8c037d45738566ee260db9345e11d9c
|
|
BLAKE2b-256 checksum How to use checksums |
e957776a06d029cc6728bb3b5fc4e9286f905cfbb287df8a32335efd909587ad
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / clario-0.1.0-py3-none-any.whl
| Download URL | clario-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5b3c170ffe49fd50aed444aa1ecd4415c80d5d2f5381299b6aba2d29e4ae6383
|
|
BLAKE2b-256 checksum How to use checksums |
c7384fefb68e77e4b01970841d0ae2eb5168f7b14ba76abea4d0d1fd73e58e3a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|