beancount-gocardless
Python client for the GoCardless Bank Account Data API (formerly Nordigen), with Pydantic models recreated from the OpenAPI/Swagger spec, plus a Beancount importer.
Inspired by https://github.com/tarioch/beancounttools.
Documentation: https://beancount-gocardless.readthedocs.io/en/latest/
Key features
- API client with typed Pydantic models for endpoints and data structures.
- Built-in HTTP caching via
requests-cache(optional). - CLI to manage bank authorization (list banks, create links, list accounts, delete links).
- Beancount importer: a
beangulp.Importerimplementation that fetches transactions and emits Beancount entries. - Import-time metadata control (exclude fields, add custom fields), plus subclassing hooks for advanced needs.
Installation
pip install beancount-gocardless
Prerequisites (credentials)
Create a GoCardless Bank Account Data account to get API credentials:
https://bankaccountdata.gocardless.com/overview/
You will need:
GOCARDLESS_SECRET_IDGOCARDLESS_SECRET_KEY
CLI usage (bank authorization)
The importer needs an authorized bank connection first. Use the CLI to create and manage connections.
Set credentials as environment variables:
export GOCARDLESS_SECRET_ID="..."
export GOCARDLESS_SECRET_KEY="..."
Launch the CLI:
beancount-gocardless
Options:
- List accounts: view connected accounts with expiry status (EXPIRED badge shown for expired connections), select an account to view details, check balances, or delete the link
- Add account: add a new bank connection by selecting country, choosing a bank, and creating an authorization link
- List banks: browse available banks by country and create links
Account expiry is shown in the list. Use --mock flag for testing without real credentials.
Beancount usage
1) Create a YAML config
Create gocardless.yaml:
secret_id: $GOCARDLESS_SECRET_ID
secret_key: $GOCARDLESS_SECRET_KEY
# Note: this project substitutes environment variables in YAML values at runtime.
cache_options: # if omitted, caching is disabled
cache_name: "gocardless"
backend: "sqlite"
expire_after: 3600
old_data_on_error: true
accounts:
- id: "<REDACTED_UUID>"
asset_account: "Assets:Banks:Revolut:Checking"
transaction_types: ["booked", "pending"] # optional, defaults to both
preferred_balance_type: "interimAvailable" # optional
2) Create an import script
Create my.import:
#!/usr/bin/env python3
import beangulp
from beancount_gocardless import GoCardLessImporter
from smart_importer import PredictPayees, PredictPostings
importers = [
GoCardLessImporter(),
]
hooks = [
PredictPostings().hook,
PredictPayees().hook,
]
if __name__ == "__main__":
ingest = beangulp.Ingest(importers, hooks=hooks)
ingest()
3) Run the import
python my.import extract ./gocardless.yaml --existing ./ledger.bean
Customizing metadata
Via YAML configuration
You can control metadata per account:
accounts:
- id: "<REDACTED_UUID>"
asset_account: "Assets:Banks:Revolut:Checking"
# Exclude specific default metadata fields.
exclude_default_metadata: ["bookingDate", "creditorName"]
# Add custom metadata fields using dotted paths.
metadata_fields:
payee: "creditorName"
cardScheme: "additionalDataStructured.cardInstrument.cardSchemeName"
balanceType: "balanceAfterTransaction.balance_type"
Supported options:
exclude_default_metadata(default:[]) - Exclude specific default metadata fields.- Default fields include:
nordref,creditorName,debtorName,bookingDate
- Default fields include:
metadata_fields(default:null) - Add or override metadata fields using dotted paths.- Specify the output key as the dict key and the GoCardless path as the value.
- Example:
"cardScheme": "additionalDataStructured.cardInstrument.cardSchemeName"
Example configurations
Use defaults with exclusions:
accounts:
- id: "<REDACTED_UUID>"
asset_account: "Assets:Banks:Revolut:Checking"
exclude_default_metadata: ["bookingDate"] # Keep nordref, creditorName, debtorName
Full customization with custom keys:
accounts:
- id: "<REDACTED_UUID>"
asset_account: "Assets:Banks:Revolut:Checking"
exclude_default_metadata: [] # Keep all defaults
metadata_fields:
# Rename default field by using custom key name
payee: "creditorName"
# Add nested custom fields
cardScheme: "additionalDataStructured.cardInstrument.cardSchemeName"
mcc: "merchant_category_code"
ultimateCreditor: "ultimate_creditor"
Via subclassing
For advanced customization, subclass GoCardLessImporter and override add_metadata:
from beancount_gocardless import GoCardLessImporter
class CustomImporter(GoCardLessImporter):
def add_metadata(self, transaction, custom_metadata, account_config=None):
metakv = super().add_metadata(transaction, custom_metadata, account_config)
if transaction.ultimate_creditor:
metakv["ultimateCreditor"] = transaction.ultimate_creditor
if transaction.merchant_category_code:
metakv["mcc"] = transaction.merchant_category_code
if transaction.bank_transaction_code:
metakv["bankCode"] = transaction.bank_transaction_code
return metakv
importers = [CustomImporter()]
The BankTransaction model (see models.py) contains many optional fields you can expose as metadata, for example:
ultimate_creditor,ultimate_debtorbank_transaction_code,proprietary_bank_transaction_codemerchant_category_code,creditor_id,mandate_identry_reference,account_servicer_reference
Development
API coverage and models
The GoCardless client aims to provide full API coverage with typed models for endpoints and data structures.
Models are manually recreated from the OpenAPI/Swagger spec to keep strong typing and stable semantics.
Local development
git clone https://github.com/jodoox/beancount-gocardless.git
cd beancount-gocardless
python -m venv .venv
source .venv/bin/activate
pip install -U pip
pip install -e ".[dev]"
pytest
Metadata
Release files for beancount-gocardless 0.1.14
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_gocardless-0.1.14.tar.gz | 46.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| beancount_gocardless-0.1.14-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 87.4 kB
Release files / beancount_gocardless-0.1.14.tar.gz
| Download URL | beancount_gocardless-0.1.14.tar.gz |
|---|---|
| Size | 46.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ef393c43ed53f51d5aac1c10fd1fbabddbe1af4ba49cfc12259ad4d5418e681c
|
|
BLAKE2b-256 checksum How to use checksums |
211ed3424488ed2b180f30f421a057325db4b12d2ccc5e847f35ef0e5d182eab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.29 {"installer":{"name":"uv","version":"0.9.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / beancount_gocardless-0.1.14-py3-none-any.whl
| Download URL | beancount_gocardless-0.1.14-py3-none-any.whl |
|---|---|
| Size | 40.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2967568f22cbcfbe07956ede5cf906fc98c5e56b7b868be9421bc7ff21bb96c1
|
|
BLAKE2b-256 checksum How to use checksums |
a72ad5e1bbae71e452d36da0fbf6ab9f20a0ac37cb3119373f15c19d0913dd80
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.29 {"installer":{"name":"uv","version":"0.9.29","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|