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 robustflatten()dictionary dumps available as well). - Robust and Fast Parsing: Built on top of
lxmlwith 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
You can install openpurse locally:
git clone https://github.com/yourusername/openpurse.git
cd openpurse
pip install .
To install development dependencies (for running tests):
pip install -e .[dev]
Usage
You can extract standard standard fields strictly into a structured dataclass or loosely into a dictionary:
from openpurse.parser import OpenPurseParser
# 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 = 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
-}'''
# Output: {"message_id": "MT103MSG", "amount": "50000.00", "currency": "EUR"... }
# 3. Translate between MT and MX formats
from openpurse.translator import Translator
msg_struct = parser.parse()
# Convert to MT103 byte string
mt_bytes = Translator.to_mt(msg_struct, "103")
# Convert to ISO 20022 XML (e.g. pacs.008, camt.004)
mx_bytes = Translator.to_mx(msg_struct, "camt.004")
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 notationcurrency: 3-Letter currency codesender_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
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 openpurse-0.1.0.tar.gz.
File metadata
- Download URL: openpurse-0.1.0.tar.gz
- Upload date:
- Size: 3.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14a802116ad53055652c4db9e50b59c4d77a53273c384ace11b4afe337376a8b
|
|
| MD5 |
e7230c6d5f300006e786d237855c0bfe
|
|
| BLAKE2b-256 |
400077aff3f41236fafc49fb07216409ef8b8d2779aa5c71d619392964a44b6f
|
File details
Details for the file openpurse-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openpurse-0.1.0-py3-none-any.whl
- Upload date:
- Size: 8.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8d9e663e573fd4181550feaf94805f3d7857ef0da607a20b226b65710a2767b2
|
|
| MD5 |
d64c6e3f67fb314c6277b9f3be34671b
|
|
| BLAKE2b-256 |
144bea4d74ebc75f4f26ff93b5911ef71f97a22d37c4906edc020575cee2dc41
|