Personal finance CLI that parses statements and produces CSV output.
- Create a virtual env and install deps with uv:
uv venv
source .venv/bin/activate
uv pip install -e .- Run the CLI:
finance --helpfinance parse <pdf|csv> [options]Parses statements into CSV format:
- Itaú:
index,transaction_date,payment_date,description,amount(plus optional columns). - Nubank:
id,transaction_date,payment_date,description,amount(plus optional columns).
Itaú ids are generated during import from payment_date and index.
Templates:
itau_cc(PDF)nu_cred(CSV)nu_acc(CSV)
Auto-detection is based on file type, CSV headers, and filename hints. Override with -t/--template.
Examples:
finance parse Fatura.pdf
finance parse "faturas/*.pdf" -s "transaction_date DESC"
finance parse "faturas/*.pdf" -m -o merged.csv
finance parse Itau.pdf --total 9356.73
finance parse nubank.csv -t nu_credfinance import <csv> [--source itau_cc|nu_cred|nu_acc]Imports a standard-format CSV into the database (SQLite).
If --source is omitted,
the CLI tries to infer it from a source column or the filename.
Bulk apply cached categorizations (no AI in bulk mode):
finance category --db finances.dbManually categorize with Pareto ordering (most frequent descriptions first):
finance category manualIf installment labels (e.g. 02/10) are preventing grouping, re-canonicalize:
finance category recanonExport/import the category cache:
finance category cache export --file categorizations.csv
finance category cache import --file categorizations.csvForce AI suggestions for every item:
finance category manual --forceFind a statement by id or description glob, suggest categories, and cache the result:
finance category find "IFOOD*"
finance category find 123If there are no cached suggestions yet, category find falls back to AI and requires
OPENAI_API_KEY. You can store this in a .env file (see .env.example).
Store the categorization prompt in the database so it syncs across machines:
finance category prompt set --file prompts/categorization_prompt.txtRead the stored prompt:
finance category prompt getPull from Notion into the local cache:
finance sync pull
finance sync pull --since 2024-01-01T00:00:00ZPush category/reconciled updates to Notion (only changed records by default):
finance sync push
finance sync push --forceThese commands are placeholders for now:
finance group
finance exportDebug output modes:
all(default): raw text + normalized text + scanned totalraw: raw text onlynormalized: normalized text onlytotal: scanned total only
The normalized text strips accents, lowercases, and removes whitespace so PDF spacing artifacts are easier to diagnose.
CSV output uses en-US formatting for data interchange:
- Dates are
MM/DD/YY - Amounts use
.as decimal separator
modern(default): Aug 2025+ statements.legacy: Jul 2025 and earlier; split uses midpoint on page 1 and shifts 1.5cm right on page 2+.
Sort columns supported:
indextransaction_datepayment_datedescriptionamount
Example:
finance parse Fatura.pdf -s "amount DESC"pytest