beancount-zenmoney
A Beancount importer for Zenmoney CSV exports, built on beangulp.
Installation
pip install beancount-zenmoney
Or with uv:
uv add beancount-zenmoney
Requirements
- Python 3.10+
- Beancount 3.x
- beangulp
Quick Start
Create an import.py file for beangulp (see examples/import.py for a complete example):
from beancount_zenmoney import ZenMoneyImporter
account_map = {
"PKO - PLN": "Assets:Bank:PKO:PLN",
"Revolut - EUR": "Assets:Bank:Revolut:EUR",
}
category_map = {
"Salary": "Income:Salary",
"Food / Groceries": "Expenses:Food:Groceries",
"Gifts": {"income": "Income:Gifts", "expense": "Expenses:Gifts"},
}
importers = [
ZenMoneyImporter(
account_map=account_map,
category_map=category_map,
),
]
Run with beangulp:
beangulp extract -e ledger.beancount import.py zenmoney_export.csv
Configuration Options
ZenMoneyImporter(
# Required: Map Zenmoney account names to Beancount accounts
account_map={
"Bank - PLN": "Assets:Bank:PLN",
},
# Optional: Map Zenmoney categories to Beancount accounts
category_map={
"Food": "Expenses:Food",
},
# Optional: Base account for the importer (default: "Assets:ZenMoney")
base_account="Assets:Import:ZenMoney",
# Optional: Default expense account for unknown categories
default_expense="Expenses:Unknown",
# Optional: Default income account for unknown categories
default_income="Income:Unknown",
# Optional: Default asset account for unknown Zenmoney accounts
default_account="Assets:Unknown",
# Optional: Transaction flag - "*" for cleared (default), "!" for pending
flag="!",
)
Features
Transaction Types
| Zenmoney Transaction | Beancount Result |
|---|---|
| Expense (outcome only) | Debit from asset, credit to expense |
| Income (income only) | Credit to asset, debit from income |
| Transfer (same currency) | Debit from source, credit to destination |
| Currency exchange | Debit in one currency, credit in another with price |
| Refund | Credit to asset, debit from expense |
Currency Exchange with Price
Currency exchanges automatically include price annotations for proper cost tracking:
2025-12-12 * "" "FX EXCHANGE EUR/PLN 4.25"
Assets:Bank:PKO:PLN -4250.00 PLN
Assets:Bank:PKO:EUR 1000.00 EUR @ 4.25 PLN
Metadata Preservation
Each transaction includes metadata from ZenMoney:
2025-12-14 * "SuperMarket" ""
zenmoney_created: "2025-12-14 10:30:00"
zenmoney_changed: "2025-12-14 11:00:00"
zenmoney_category: "Food / Groceries"
Assets:Bank:PKO:PLN -125.50 PLN
Expenses:Food:Groceries 125.50 PLN
File Archiving Support
The importer implements date() and filename() methods for beangulp archiving:
# Archive files with automatic date-based naming
beangulp archive -e ledger.beancount import.py zenmoney_export.csv
# Creates: documents/Assets/Import/ZenMoney/2025-11-29-to-2025-12-15.zenmoney.csv
Logging
Skipped rows are logged as warnings for troubleshooting:
import logging
logging.basicConfig(level=logging.WARNING)
Exporting from Zenmoney
- Open the Zenmoney app or web interface
- Go to Menu → Export
- Select CSV format
- Choose the date range for export
- Download the CSV file
The CSV file should have semicolon-separated columns including:
date,categoryName,payee,commentoutcomeAccountName,outcome,outcomeCurrencyShortTitleincomeAccountName,income,incomeCurrencyShortTitlecreatedDate,changedDate
Example Output
Expense transaction:
2025-12-14 * "SuperMarket" ""
Assets:Bank:PKO:PLN -125.50 PLN
Expenses:Food:Groceries 125.50 PLN
Internal transfer:
2025-12-11 * "" ""
Assets:Bank:PKO:PLN -2000.00 PLN
Assets:Cash:PLN 2000.00 PLN
Income transaction:
2025-12-15 * "ACME CORP" "DECEMBER SALARY"
Assets:Bank:PKO:PLN 15000.00 PLN
Income:Salary -15000.00 PLN
Development
Setup
git clone https://github.com/MrLokans/beancount-zenmoney.git
cd beancount-zenmoney
make install
Releasing
The package is automatically published to PyPI when a version tag is pushed:
make release VERSION=0.2.0
This script will:
- Run all checks (lint, format, typecheck, tests)
- Validate the version format and ensure the tag doesn't exist
- Update version in
pyproject.tomland__init__.py - Commit, tag, and push to remote
Available Commands
make install # Install dependencies
make test # Run tests
make lint # Run linter
make format # Format code (ruff check --fix + ruff format)
make typecheck # Run type checker
make check # Run all checks (lint, format-check, typecheck, test)
make build # Build package
make clean # Clean build artifacts
make release VERSION=X.Y.Z # Create and push a release
Running Tests
make test
Tests use pytest with fixtures for sample CSV data. Test coverage is reported automatically.
License
MIT License - see LICENSE for details.
Metadata
Release files for beancount-zenmoney 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| beancount_zenmoney-0.1.3.tar.gz | 6.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| beancount_zenmoney-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 13.1 kB
Release files / beancount_zenmoney-0.1.3.tar.gz
| Download URL | beancount_zenmoney-0.1.3.tar.gz |
|---|---|
| Size | 6.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
df1bee632894c0a0a749eb40477a4d98a6843b8612748df211f049a332b4df62
|
|
BLAKE2b-256 checksum How to use checksums |
a0bcd871d484a3b1c7e048ef06f746ff0ca7c57f4cf856319207fa29b2f05c09
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.
Transparency logRelease files / beancount_zenmoney-0.1.3-py3-none-any.whl
| Download URL | beancount_zenmoney-0.1.3-py3-none-any.whl |
|---|---|
| Size | 6.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5a34cfb909d0129dd4ae76247c915257a153f6b90245d4288efcce5da3358e9f
|
|
BLAKE2b-256 checksum How to use checksums |
ff813d91c4bcab816b7911143e0c2ed1cc5d67358265c054a8305ee888b3a57b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 19, 2026.
Transparency log