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
Real-world text The 16 free-text field (and 88 continuations) is kept verbatim — commas and slashes inside it are preserved, not split on
Robustness Tolerates CRLF, blank lines, trailing spaces, an optional trailing / per record, and V/S funds-type subfields
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. The free-text field runs to end-of-record (commas included) and is kept verbatim; V/S funds-type subfields are accounted for when locating the references and text.
88 Continuation Appended verbatim (commas included) to the preceding 16 record's text. A 88 continuing an 03 summary, or one with no preceding 16, is dropped rather than mis-attached. The rare 88: colon form is tolerated.
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)
make mutation mutmut run + mutmut results (mutation testing)

Current state (v0.0.12): all tests passing, 100% line + branch coverage against a 100% enforced floor, mypy --strict clean, interrogate 100%, and a mutation-tested loader (317/336 mutants killed; the 19 survivors are documented equivalent mutants — see tests/MUTATION.md).


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.12.tar.gz (21.7 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.12.tar.gz.

File metadata

File hashes

Hashes for bankstatementparser_loader_bai2-0.0.12.tar.gz
Algorithm Hash digest
SHA256 72d71ea3b0455ab8e76270daac181abf166c0aa1db570ea2d8551d67fa949611
MD5 5375edf0e6ca27d61c45e1c67118d754
BLAKE2b-256 f9b388840e48ee660de75e3e37b24cbab6508eb39c1833c41f135eac0e4786ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_loader_bai2-0.0.12.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.12-py3-none-any.whl.

File metadata

File hashes

Hashes for bankstatementparser_loader_bai2-0.0.12-py3-none-any.whl
Algorithm Hash digest
SHA256 d429434af2f7a5f5acc2c90066d4cdd109c0ba5ea44dcd417df4487f1bbee690
MD5 3083b29ca790d63891d95bf67cb9bf37
BLAKE2b-256 a2dcf33e07d67c3349317c4793baf3efe322c246b916687e3d74a4d0636159a7

See more details on using hashes here.

Provenance

The following attestation bundles were made for bankstatementparser_loader_bai2-0.0.12-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