Deterministic multi-ERP financial consolidation, POS-to-journal, and GL audit engine for SMEs
Project description
accounting-bridge
Deterministic multi-ERP financial consolidation, POS-to-journal conversion, and GL audit — as a typed Python library.
Every finance team with two or more entities runs the same manual loop each month: export trial balances from each ERP, rearrange columns, VLOOKUP account codes, reconcile currencies, and hunt for the difference when it doesn't balance. accounting-bridge does that loop in seconds — and it is deterministic: no LLM sits in the data path, so every number is reproducible and auditable, with row-level lineage back to the source file.
It reads exports from any accounting system (CSV, Excel, PDF, OFX/QFX, QuickBooks IIF, scanned images) and produces:
- Consolidated trial balances across entities and currencies, with IAS 21 FX translation and a cumulative translation adjustment.
- POS-to-journal conversion with balanced double entries and Canadian GST/QST tax splitting.
- GL audit packages with anomaly flags, balance checks, and Benford's-law analysis.
Install
pip install accounting-bridge # core library, zero UI/server deps
pip install "accounting-bridge[pdf]" # + PDF table extraction
pip install "accounting-bridge[ocr]" # + scanned-image OCR
pip install "accounting-bridge[all]" # everything
Requires Python 3.11+.
Library quickstart
The library's front door is a small set of typed functions that take a validated config and return a named result.
import pandas as pd
from accounting_bridge import consolidate, ConsolidationConfig
hq = pd.DataFrame({"account_code": ["4100"], "amount_local": [-10_000.0], "currency": ["USD"]})
eu = pd.DataFrame({"account_code": ["4100"], "amount_local": [-8_000.0], "currency": ["EUR"]})
cols = {"account_code": "account_code", "amount_local": "amount_local", "currency": "currency"}
config = ConsolidationConfig(
columns_per_entity={"HQ": cols, "EU": cols},
base_currency="USD",
rates={"EUR": {"closing": 1.08, "average": 1.07, "historical": 1.05}},
)
result = consolidate([("HQ", hq), ("EU", eu)], config)
print(result.summary) # consolidated by account, in USD
print(result.fx_warnings) # any FX/rate issues surfaced
Other entry points follow the same shape:
from accounting_bridge import convert_pos, audit_ledger, summarize_trial_balance
from accounting_bridge import PosConfig, AuditConfig
pos_result = convert_pos(pos_df, PosConfig(columns=..., accounts=...))
audit_result = audit_ledger(gl_df, AuditConfig(columns=..., large_amount=100_000))
tb_result = summarize_trial_balance(tb_df, {"account_code": "Acct", "amount": "Balance"})
Reading messy real-world files:
from accounting_bridge.ingest import read_smart
df, diagnostics = read_smart("messy_export.xlsx") # encoding, delimiter, header auto-detected
Command line
# Consolidate several trial balances into one audit-ready workbook
accounting-bridge consolidate --files entity_a.csv entity_b.xlsx \
--base-currency USD --rates EUR:closing=1.08,average=1.07 --output consolidated.xlsx
# Inspect how a file is parsed (encoding, delimiter, columns)
accounting-bridge read --file messy_export.csv
Supported formats
| Format | Extensions | Extra |
|---|---|---|
| Delimited text | .csv .tsv .txt |
core |
| Excel | .xlsx .xls .xlsm |
core |
| PDF tables | .pdf |
[pdf] |
| Open Financial Exchange | .ofx .qfx |
[ofx] |
| QuickBooks Desktop | .iif |
core |
| Scanned images | .png .jpg |
[ocr] |
Architecture
Library-first. The engine is the product; the app and server are thin layers over it.
accounting_bridge/ core library — pure, typed, no UI/server deps
models/ pydantic v2 config + result models (validated at the boundary)
ingest/ multi-format readers (encoding/delimiter/header auto-detection)
engine/ consolidation, POS, audit, trial balance, intercompany, FX
processing.py the typed public API (consolidate / convert_pos / audit_ledger / ...)
cli.py one-shot command-line consolidation
A FastAPI server and a dedicated web frontend are layered on the same library
(see the redesign in progress in CHANGELOG.md).
Self-hosting
docker compose up # single-user instance, SQLite, no secrets required
Authentication and billing ship disabled by default; set the documented environment variables to enable a multi-tenant hosted deployment.
Development
uv venv --python 3.12 && source .venv/bin/activate
uv pip install -e ".[all,dev]"
make test # python -m pytest
make lint # ruff check + ruff format --check
make typecheck # mypy --strict
See CONTRIBUTING.md for conventions and SECURITY.md to report vulnerabilities.
License
MIT © Wietze Suijker
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file accounting_bridge-0.6.0.tar.gz.
File metadata
- Download URL: accounting_bridge-0.6.0.tar.gz
- Upload date:
- Size: 315.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45a7c827d72c4c39bfa9fc0a51f9e0ac68052708034779826e61083e60c54fe3
|
|
| MD5 |
a0905c9fe01e6063df82e38a70737422
|
|
| BLAKE2b-256 |
47ad04f5b2088ea3dc46c1d6c2b637b7a82bffe4f09558deb617341d6d987248
|
Provenance
The following attestation bundles were made for accounting_bridge-0.6.0.tar.gz:
Publisher:
release.yml on wietzesuijker/accounting-bridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
accounting_bridge-0.6.0.tar.gz -
Subject digest:
45a7c827d72c4c39bfa9fc0a51f9e0ac68052708034779826e61083e60c54fe3 - Sigstore transparency entry: 1693753141
- Sigstore integration time:
-
Permalink:
wietzesuijker/accounting-bridge@9da3845e51175bd17a38e5df7af44b91713101e8 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/wietzesuijker
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da3845e51175bd17a38e5df7af44b91713101e8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file accounting_bridge-0.6.0-py3-none-any.whl.
File metadata
- Download URL: accounting_bridge-0.6.0-py3-none-any.whl
- Upload date:
- Size: 261.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31e507a70197b061176e642b5b74498b19168c170a6579b6556a523156e3fc1d
|
|
| MD5 |
654f4773721306ae2233c50a9c654069
|
|
| BLAKE2b-256 |
cbfbc536451406c30059b907b58447c4cb431b28b28b0a03693f75ba9115a293
|
Provenance
The following attestation bundles were made for accounting_bridge-0.6.0-py3-none-any.whl:
Publisher:
release.yml on wietzesuijker/accounting-bridge
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
accounting_bridge-0.6.0-py3-none-any.whl -
Subject digest:
31e507a70197b061176e642b5b74498b19168c170a6579b6556a523156e3fc1d - Sigstore transparency entry: 1693753363
- Sigstore integration time:
-
Permalink:
wietzesuijker/accounting-bridge@9da3845e51175bd17a38e5df7af44b91713101e8 -
Branch / Tag:
refs/tags/v0.6.0 - Owner: https://github.com/wietzesuijker
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9da3845e51175bd17a38e5df7af44b91713101e8 -
Trigger Event:
push
-
Statement type: