Skip to main content

A lightweight Python package to flatten complex ISO 20022 XML messages into usable data.

Project description

OpenPurse

OpenPurse is a lightweight, open-source Python package that parses and flattens deeply nested ISO 20022 XML financial messages into highly usable, flat Python dictionaries (which can be easily dumped to JSON).

Features

  • Universal Support: Dynamically determines the message format. It fully supports both XML-based ISO 20022 schemas and legacy block-based SWIFT MT formats (like MT103 and MT202).
  • Structured Schema: Extracts all major variables into a standard Python PaymentMessage @dataclass (with robust flatten() dictionary dumps available as well).
  • Robust and Fast Parsing: Built on top of lxml with robust error handling, regular expressions for non-XML data, and graceful degradation for missing optional fields.
  • Zero Bloat: Only requires lxml. No heavy dependencies like pandas or pydantic are needed.

Installation

OpenPurse is published on PyPI. You can install it directly via pip:

pip install openpurse

Publishing to PyPI (Maintainers Only)

To publish a new version of OpenPurse to PyPI:

  1. Configure Credentials: Copy .env.example to .env and add your PyPI API token:
    cp .env.example .env
    # Then edit .env and add your token to TWINE_PASSWORD
    
  2. Update Version: Increment the version in pyproject.toml.
  3. Run Release Script:
    ./scripts/publish.sh
    
    This script will automatically clean old builds, rebuild the package, and upload the new version to PyPI using your stored token.

To install development dependencies (for running tests):

pip install -e .[dev]

Usage

You can import the main classes directly from the openpurse package to parse raw XML or MT bytes:

import openpurse

# Your raw ISO 20022 XML data (or MT bytes)
xml_data = b'''<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.08">
    <FIToFICstmrCdtTrf>
        <GrpHdr>
            <MsgId>MSG12345</MsgId>
            ...
        </GrpHdr>
        <CdtTrfTxInf>
            <IntrBkSttlmAmt Ccy="USD">1000.50</IntrBkSttlmAmt>
        </CdtTrfTxInf>
    </FIToFICstmrCdtTrf>
</Document>'''

# Initialize the parser
parser = openpurse.OpenPurseParser(xml_data)

# 1. Parse into a structured PaymentMessage dataclass (Recommended)
msg_struct = parser.parse()
print(f"ID is {msg_struct.message_id} sending {msg_struct.amount} {msg_struct.currency}")

# 2. Flatten directly into a dictionary
flat_dict = parser.flatten()
print(flat_dict)
# Output:
# {
#     "message_id": "MSG12345",
#     "end_to_end_id": None,
#     "amount": "1000.50",
#     "currency": "USD",
#     "sender_bic": None,
#     "receiver_bic": None,
#     "debtor_name": None,
#     "creditor_name": None
# }

# Or parse legacy SWIFT MT formats without changing any logic!
mt_data = b'''{1:F01BANKUS33AXXX0000000000}{2:I103BANKGB22XXXXN}{4:
:20:MT103MSG
:32A:231024EUR50000,00
-}'''

parser = openpurse.OpenPurseParser(mt_data)
# Output: {"message_id": "MT103MSG", "amount": "50000.00", "currency": "EUR"... }

# 3. Translate between MT and MX formats
msg_struct = parser.parse()

# Convert to SWIFT MT103 format
mt_bytes = openpurse.Translator.to_mt(msg_struct, "103")

# Convert to ISO 20022 XML (e.g. pacs.008, camt.004)
mx_bytes = openpurse.Translator.to_mx(msg_struct, "camt.004")

# 4. Deep parsing for specific schemas (e.g. camt.054, pacs.008)
camt_data = b'''... your standard CAMT 054 XML ...'''
parser = openpurse.OpenPurseParser(camt_data)
detailed_msg = parser.parse_detailed()
# Returns a typed `Camt054Message` object wrapping entries, notifications, etc.
# detailed_msg.entries[0]["reference"] == "REF001"

Supported Fields

Whether you call .parse() (which yields a PaymentMessage dataclass instance) or .flatten() (which yields a dict), the parser standardizes the following fields across all schemas:

  • message_id: GrpHdr/MsgId (XML) or Block 4 :20: (MT)
  • end_to_end_id: EndToEndId (XML)
  • amount: Extracted value preserving decimal notation
  • currency: 3-Letter currency code
  • sender_bic: InstgAgt/BICFI (XML) or Header Block 1 (MT)
  • receiver_bic: InstdAgt/BICFI (XML) or Header Block 2 (MT)
  • debtor_name: Dbtr/Nm (XML) or :50K: tags (MT)
  • creditor_name: Cdtr/Nm (XML) or :59: tags (MT)

Missing or optional fields gracefully return None.

Tests

Testing is done using pytest. Currently, coverage includes mock definitions for basic pacs and camt schemas, validating graceful degradation when schemas don't provide creditor/debtor names.

pytest tests/

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

openpurse-0.1.2.tar.gz (3.6 MB view details)

Uploaded Source

Built Distribution

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

openpurse-0.1.2-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

Details for the file openpurse-0.1.2.tar.gz.

File metadata

  • Download URL: openpurse-0.1.2.tar.gz
  • Upload date:
  • Size: 3.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for openpurse-0.1.2.tar.gz
Algorithm Hash digest
SHA256 43a4fcaf6d7aed6f07f899b5581c91fbacd2a745e33e940fe50183fcdc66374a
MD5 4d194e414c6d72cccb3e6e181e87990a
BLAKE2b-256 da9d7d92dc0911bbcb94df272ae5ad447dcb5502cbf638e095ab6db5dd166a49

See more details on using hashes here.

File details

Details for the file openpurse-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: openpurse-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 17.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for openpurse-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0225dca31c7211dac1dfec60008872649fcb60a842eb15b6019fb5d9bc28801a
MD5 159fd4c1399db89dd040a4fb94a593ea
BLAKE2b-256 8cb876bd1629fba9656582d116815b9e699d4501f2eb03f0417305715b8b64c0

See more details on using hashes here.

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