Skip to main content

beancount-zenmoney

PyPI version Python versions License CI codecov

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

  1. Open the Zenmoney app or web interface
  2. Go to Menu → Export
  3. Select CSV format
  4. Choose the date range for export
  5. Download the CSV file

The CSV file should have semicolon-separated columns including:

  • date, categoryName, payee, comment
  • outcomeAccountName, outcome, outcomeCurrencyShortTitle
  • incomeAccountName, income, incomeCurrencyShortTitle
  • createdDate, 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.toml and __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)

Source distribution for beancount-zenmoney 0.1.3
File Size Uploaded
beancount_zenmoney-0.1.3.tar.gz 6.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for beancount-zenmoney 0.1.3
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page