Skip to main content

BAI2 (Bank Administration Institute v2) cash-management loader that parses BAI2 files into bankstatementparser Transaction objects.

Project description

bankstatementparser-loader-bai2 logo

bankstatementparser-loader-bai2

A BAI2 (Bank Administration Institute, version 2) cash-management loader that parses BAI2 files into bankstatementparser Transaction objects.

PyPI version Python versions PyPI downloads Tests License


Contents


What is bankstatementparser-loader-bai2?

BAI2 (Bank Administration Institute, version 2) is the de-facto US cash-management file format that banks ship for intraday and prior-day balance and transaction reporting. The published bankstatementparser library parses PDF and other statement formats but does not support BAI2.

bankstatementparser-loader-bai2 is a small, dependency-light companion that fills that gap: give it a BAI2 payload and it returns a flat list of bankstatementparser.transaction_models.Transaction objects (source="bai2") that the rest of your deterministic pipeline can consume unchanged.

Concern How this loader handles it
Record model A documented, pragmatic subset of BAI2 (01/02/03/16/88 plus ignored trailers)
Amounts BAI2 minor-unit integers (cents) converted to Decimal (never float)
Debit / credit Derived from the 16 type-code range, with the raw code preserved
Multiple accounts All 16 records across every group / account are flattened into one list
Robustness Tolerates CRLF, blank lines, and an optional trailing / per record
Errors A clear ValueError if the file does not start with an 01 File Header

Install

Channel Command Notes
PyPI pip install bankstatementparser-loader-bai2 Pulls in bankstatementparser >= 0.0.9
Source git clone https://github.com/sebastienrousseau/bankstatementparser-loader-bai2 && cd bankstatementparser-loader-bai2 && poetry install For development

Requires Python 3.10 or later. Works on macOS, Linux, and Windows.

Using an isolated virtual environment (recommended)
python -m venv venv
source venv/bin/activate        # macOS/Linux
venv\Scripts\activate           # Windows
python -m pip install -U bankstatementparser-loader-bai2

Quick start

from bankstatementparser_loader_bai2 import load_bai2_file

transactions = load_bai2_file("statement.bai")
for txn in transactions:
    print(txn.account_id, txn.currency, txn.amount, txn.description)

Or parse an in-memory payload:

from bankstatementparser_loader_bai2 import load_bai2

payload = (
    "01,SENDER,RECEIVER,260601,1200,FILE001,,,/\n"
    "02,RCVR,ORIG,1,260601,1200,USD,/\n"
    "03,0123456789,USD,010,150000,1,,/\n"
    "16,165,150000,Z,BANKREF1,CUSTREF1,Incoming wire payment/\n"
    "88,from ACME Corp invoice 42/\n"
    "16,475,2500,Z,BANKREF2,,ATM withdrawal/\n"
    "49,152500,2/\n"
    "98,152500,1,4/\n"
    "99,152500,1,6/\n"
)

for txn in load_bai2(payload):
    print(txn.amount, txn.category, txn.description)
# 1500 bai2:165 Incoming wire payment from ACME Corp invoice 42
# -25 bai2:475 ATM withdrawal

Runnable versions live in examples/.


Public API

from bankstatementparser_loader_bai2 import (
    load_bai2,
    load_bai2_file,
    summarize_bai2,
    Bai2Summary,
)
Function Signature Returns
load_bai2 load_bai2(text: str) list[Transaction]
load_bai2_file load_bai2_file(path) list[Transaction]
summarize_bai2 summarize_bai2(text: str) Bai2Summary

Bai2Summary is a dataclass with the fields file_id, group_count, account_count, transaction_count, and currency.

Each produced Transaction is populated as follows:

Transaction field Source
account_id 03 Account Identifier — accountNumber
currency 03 currencyCode, falling back to the 02 group currency
amount 16 amount (cents / 100), signed per the convention below
booking_date 02 Group Header as-of date, when present
description 16 text plus any 88 continuations
transaction_id 16 bankRefNum, falling back to customerRefNum
reference / category The raw 16 type code (category as bai2:<code>)
source Always "bai2"

Supported BAI2 subset

BAI2 records are comma-delimited fields ending with a / delimiter, each beginning with a numeric type code. This loader implements a documented, pragmatic subset:

Record Meaning Handling
01 File Header Required first record. fileId captured for the summary.
02 Group Header Group currency and as-of date captured.
03 Account Identifier accountNumber + optional currencyCode captured; account currency overrides group currency.
16 Transaction Detail One transaction.
88 Continuation Appended to the preceding 03/16 record's text.
49 / 98 / 99 Account / Group / File trailers Ignored — control totals are not validated.

Any other (or unknown) leading type code is ignored so that vendor extensions do not abort the parse. Ignoring control-total trailers is a deliberate, documented choice: the goal is faithful transaction extraction, not file-level reconciliation.


Amount and sign convention

BAI2 amounts are unsigned integers in the account currency's minor units (cents), with no decimal point. They are converted to decimal.Decimal by dividing by 100. An empty amount field is treated as 0.

Debit / credit direction is derived from the documented numeric ranges of the 16 record's type code (this is the loader's chosen, documented convention):

Type-code range Meaning Behaviour
100399 Credit amount kept positive
400699 Debit amount made negative
700799 Loan detail treated as a debit-side disbursement: amount made negative
900999 Custom / summary / status no Transaction emitted — these non-detail status/summary codes are skipped (and any continuation attached to one is dropped with it)
anything else Unknown (incl. non-numeric) amount kept positive

The raw BAI2 type code is always preserved on every emitted Transaction in both category (as bai2:<code>) and reference, so no information is lost.

A small, optional lookup of well-known type codes (for example 142 "ACH credit", 301 "Commercial deposit", 475 "Check paid", 501 "Wire transfer debit") enriches the description of a 16 record that carries no free-text of its own; a record that already has text keeps its own text unchanged.


When not to use this loader

  • You have ISO 20022 camt.053 or SWIFT MT940, not BAI2. Those are different formats with their own dedicated loaders.
  • You need control-total reconciliation. This loader extracts transactions and deliberately ignores the 49/98/99 trailers; if you must validate file sums, do so before or after loading.
  • You need the full BAI2 specification. This is a documented subset focused on transaction extraction, not an exhaustive BAI2 parser.

Development

This project uses Poetry and mise.

git clone https://github.com/sebastienrousseau/bankstatementparser-loader-bai2.git
cd bankstatementparser-loader-bai2
poetry env use python3.12
poetry install

A Makefile orchestrates the quality gates (kept in lockstep with CI):

Target What it runs
make check All gates (REQUIRED before commit)
make test pytest --cov=bankstatementparser_loader_bai2 --cov-branch --cov-fail-under=100
make lint ruff check + black --check
make type-check mypy --strict
make doc-coverage interrogate --fail-under=100 (docstring coverage)

Current state (v0.0.11): all tests passing, 100% line + branch coverage against a 100% enforced floor, mypy --strict clean, interrogate 100%.


Security

  • Read-only. The loader only reads text / files you pass it; it writes nothing.
  • No XML, no network, no code execution. Parsing is a pure string-to-dataclass transformation.
  • Decimal arithmetic is used throughout, avoiding float rounding surprises in financial amounts.
  • Dependencies are pinned via poetry.lock and audited in CI.

To report a vulnerability, please use GitHub private vulnerability reporting rather than a public issue.


Contributing

Contributions are welcome — see the contributing instructions. Thanks to all the contributors who have helped build bankstatementparser-loader-bai2.


License

Licensed under the Apache License, Version 2.0. Any contribution submitted for inclusion shall be licensed as above, without additional terms.


bankstatementparser.com · PyPI · GitHub

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

bankstatementparser_loader_bai2-0.0.11.tar.gz (18.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

File details

Details for the file bankstatementparser_loader_bai2-0.0.11.tar.gz.

File metadata

File hashes

Hashes for bankstatementparser_loader_bai2-0.0.11.tar.gz
Algorithm Hash digest
SHA256 cdfbd465a0918a03a9fde5cd9052a42e2c8e685b708e916d1898b34ba1881c10
MD5 6fc46855cc71fd3b9a5d34cc670b60c6
BLAKE2b-256 dd9cf4f9203066a5d50ad286e9ed2a92c0a3abc9acfe63c66abf153f19cc3a1a

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_loader_bai2-0.0.11.tar.gz:

Publisher: release.yml on sebastienrousseau/bankstatementparser-loader-bai2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bankstatementparser_loader_bai2-0.0.11-py3-none-any.whl.

File metadata

File hashes

Hashes for bankstatementparser_loader_bai2-0.0.11-py3-none-any.whl
Algorithm Hash digest
SHA256 cbac19882c2d642a4e2b534a2f6548e6b21d05d5f03c5cff9c267a52eecfa67e
MD5 397a7e2cfbb62804e4a7e198adc547e8
BLAKE2b-256 0be7f7e9530433404f73cc01f3b6ed72778c655fe077310a617d59a802321d43

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_loader_bai2-0.0.11-py3-none-any.whl:

Publisher: release.yml on sebastienrousseau/bankstatementparser-loader-bai2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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