Skip to main content

The simple library for import extracted transactions provided by beanhub-extract and generate corresponding Beancount transactions based on predefined rules

Project description

beanhub-import CircleCI

Beanhub-import is a simple, declarative, smart, and easy-to-use library for importing extracted transactions from beanhub-extract. It generates Beancount transactions based on predefined rules.

Read the documentations here.

Note: This project is still in early stage, still subject to rapid major changes

Please also checkout our blog posts about the BeanHub Import and BeanHub Connect features based on this tool:

Features

  • Easy-to-use - you only need to know a little bit about YAML and Jinja2 template syntax.
  • Simple declarative rules - A single import file for all imports
  • Idempotent - As long as the input data and rules are the same, the Beancount files will be the same.
  • Auto-update existing transactions - When you update the rules or data, corresponding Beancount transactions will be updated automatically.
  • Auto-move transactions to a different file - When you change the rules to output the transactions to a different file, it will automatically remove the old ones and add the new ones for you
  • Merge data from multiple files (coming soon) - You can define rules to match transactions from multiple sources for generating your transactions

For example, change the import rules like this to output transactions to files grouped by quarter instead of year:

Git diff screenshot showing default_file changed to output quater file names instead of just year

Then run the import again, and you will get this:

Git diff screenshot showing Beancount transactions removed from the books/2024.bean file and new quater beancount files added

Another example is when you want to add new tags to the generated transactions, so you change the rules with new tags like this:

Git diff screenshot showing new line

When you run import again, you will get this:

Git diff screenshot showing new tags added to all imported Beancount transactions

Please check out our demonstration repository beanhub-import-demo to try it yourself.

It's all declarative and idempotent. With beanhub-import, you say goodbye to manually importing and maintaining transactions! We hope you like this tool. It's still in the early stage of development. We are also working on making generating transactions from multiple sources possible. Please feel free to open issues in the repository if you have any feedback 🙌

Why?

There are countless Beancount importer projects out there, so why do we have to build a new one from the ground up? We are building a new one with a completely new design because we cannot find an importer that meets our requirements for BeanHub. There are a few critical problems we saw in the existing Beancount importers:

  • Need to write Python code to make it work
  • Doesn't handle duplication problem
  • Hard to reuse because extracting logic is coupled with generating logic
  • Hard to customize for our own needs
  • Can only handle a single source file

Example

The rules of beanhub-import is defined in YAML format at .beanhub/imports.yaml. Here's an example

# the `context` defines global variables to be referenced in the Jinja2 template for
# generating transactions
context:
  routine_expenses:
    "Amazon Web Services":
      account: Expenses:Engineering:Servers:AWS
    Netlify:
      account: Expenses:Engineering:ServiceSubscription
    Mailchimp:
      account: Expenses:Marketing:ServiceSubscription
    Circleci:
      account: Expenses:Engineering:ServiceSubscription
    Adobe:
      account: Expenses:Design:ServiceSubscription
    Digital Ocean:
      account: Expenses:Engineering:ServiceSubscription
    Microsoft:
      account: Expenses:Office:Supplies:SoftwareAsService
      narration: "Microsoft 365 Apps for Business Subscription"
    Mercury IO Cashback:
      account: Expenses:CreditCardCashback
      narration: "Mercury IO Cashback"
    WeWork:
      account: Expenses:Office
      narration: "Virtual mailing address service fee from WeWork"

# the `inputs` defines which files to import, what type of beanhub-extract extractor to use,
# and other configurations, such as `prepend_postings` or default values for generating
# a transaction
inputs:
  - match: "import-data/mercury/*.csv"
    config:
      # use `mercury` extractor for extracting transactions from the input file
      extractor: mercury
      # the default output file to use
      default_file: "books/{{ date.year }}.bean"
      # postings to prepend for all transactions generated from this input file
      prepend_postings:
        - account: Assets:Bank:US:Mercury
          amount:
            number: "{{ amount }}"
            currency: "{{ currency | default('USD', true) }}"

# the `imports` defines the rules to match transactions extracted from the input files and
# how to generate the transaction
imports:
  - name: Routine expenses
    match:
      extractor:
        equals: "mercury"
      desc:
        one_of:
          - Amazon Web Services
          - Netlify
          - Mailchimp
          - Circleci
          - WeWork
          - Adobe
          - Digital Ocean
          - Microsoft
          - Mercury IO Cashback
    actions:
      # generate a transaction into the beancount file
      - file: "books/{{ date.year }}.bean"
        txn:
          narration: "{{ routine_expenses[desc].narration | default(desc, true) | default(bank_desc, true) }}"
          postings:
            - account: "{{ routine_expenses[desc].account }}"
              amount:
                number: "{{ -amount }}"
                currency: "{{ currency | default('USD', true) }}"

  # To avoid many match/actions statements for mostly identical transaction template,
  # you can also define different match conditions and the corresponding variables for the transaction template
  - name: Routine Wells Fargo expenses
    # the condition shared between all the matches
    common_cond:
      extractor:
        equals: "plaid"
      file:
        suffix: "(.+)/Wells Fargo/(.+).csv"
    match:
      - cond:
          desc: "Comcast"
        vars:
          account: Expenses:Internet:Comcast
          narration: "Comcast internet fee"
      - cond:
          desc: "PG&E"
        vars:
          account: Expenses:Gas:PGE
          narration: "PG&E Gas"
    actions:
      # generate a transaction into the beancount file
      - file: "books/{{ date.year }}.bean"
        txn:
          payee: "{{ payee | default(omit, true) }}"
          narration: "{{ narration | default(desc, true) | default(bank_desc, true) }}"
          postings:
            - account: "{{ account }}"
              amount:
                number: "{{ -amount }}"
                currency: "{{ currency | default('USD', true) }}"

  - name: Receive payments from contracting client
    match:
      extractor:
        equals: "mercury"
      desc:
        equals: Evil Corp
    actions:
      - txn:
          narration: "Receive payment from Evil Corp"
          postings:
            - account: "Assets:AccountsReceivable:EvilCorpContracting"
              amount:
                number: "{{ -amount / 300 }}"
                currency: "EVIL.WORK_HOUR"
              price:
                number: "300.0"
                currency: "USD"

  - name: Ignore unused entries
    match:
      extractor:
        equals: "mercury"
      desc:
        one_of:
        - Mercury Credit
        - Mercury Checking xx1234
    actions:
      # ignore action is a special type of import rule action to tell the importer to ignore the
      # transaction so that it won't show up in the "unprocessed" section in the import result
      - type: ignore

Usage

This project is a library and not meant for end-users. If you simply want to import transactions from CSV into their beancount files, please checkout the import command of beanhub-cli.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

beanhub_import-1.0.3.tar.gz (16.1 kB view details)

Uploaded Source

Built Distribution

beanhub_import-1.0.3-py3-none-any.whl (15.2 kB view details)

Uploaded Python 3

File details

Details for the file beanhub_import-1.0.3.tar.gz.

File metadata

  • Download URL: beanhub_import-1.0.3.tar.gz
  • Upload date:
  • Size: 16.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.2 CPython/3.10.11 Linux/5.15.0-1057-aws

File hashes

Hashes for beanhub_import-1.0.3.tar.gz
Algorithm Hash digest
SHA256 a3769c045265c26d580c5b5f69aa9a6ac42e42115047bc1ee819995ed9c5566b
MD5 61d889621c1ea3886543e8162ad7790b
BLAKE2b-256 02dd82f21e6d5a07a272072ed6bd628d86a02ea6a8c393d74cae4ae6d22947e0

See more details on using hashes here.

File details

Details for the file beanhub_import-1.0.3-py3-none-any.whl.

File metadata

  • Download URL: beanhub_import-1.0.3-py3-none-any.whl
  • Upload date:
  • Size: 15.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.4.2 CPython/3.10.11 Linux/5.15.0-1057-aws

File hashes

Hashes for beanhub_import-1.0.3-py3-none-any.whl
Algorithm Hash digest
SHA256 1592cb357b646be0283ee35cab0686c6d979bdd8671ccf3eeb8d8cfb1c4d534a
MD5 127f13db8280d9f093b46f481b5de920
BLAKE2b-256 299a6f8741dfbc5b82da7d2b53cebfebcb792cd56fe4206b683e46e39d4f5fc9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page