Some time ago I wrote a library to read MT940 files with Python. While there are multiple libraries available for this target, none of the others really work properly and/or support all variants of the format.
The MT940 library I wrote is slightly different, it’s designed to be able to parse any MT940 file, regardless whether it’s correct or complete. The initial version of the library was very strict and only supported files that perfectly followed the standards, a few months after the release it became obvious that most banks either used different standards when implementing the standard or interpreted the standard different. Regardless, the library gave little to no results or even crashed on some MT940 files.
Upon reflection I rewrote nearly all of the code to have a script that is flexible enough to support any format (even supporting custom processors for specific format) and wrote test code that tested every MT940 file I could find on the web. The result… a library that parsers pretty much everything out there while still maintaining a reasonable amount of results.
Usage? As simple as you might imagine. After installing (pip install mt-940
, note the dash) usage can be as simple as this:
[python]import mt940
import pprint
transactions = mt940.parse(‘tests/jejik/abnamro.sta’)
print ‘Transactions:’
print transactions
pprint.pprint(transactions.data)
print
for transaction in transactions:
print ‘Transaction: ‘, transaction
pprint.pprint(transaction.data)[/python]
For more examples, have a look at the tests. For example, the preprocessor test:
[python]import pytest
import mt940
@pytest.fixture
def sta_data():
with open(‘tests/jejik/abnamro.sta’) as fh:
return fh.read()
def test_pre_processor(sta_data):
transactions = mt940.models.Transactions(processors=dict(
pre_closing_balance=[
mt940.processors.add_currency_pre_processor(‘USD’),
],
pre_opening_balance=[
mt940.processors.add_currency_pre_processor(‘EUR’),
],
))
transactions.parse(sta_data)
assert transactions.data[‘closing_balance’].amount.currency == ‘USD’
assert transactions.data[‘opening_balance’].amount.currency == ‘EUR’
def test_post_processor(sta_data):
transactions = mt940.models.Transactions(processors=dict(
post_closing_balance=[
mt940.processors.date_cleanup_post_processor,
],
))
transactions.parse(sta_data)
assert ‘closing_balance_day’ not in transactions.data
[/python]
Hello Rick,
I am trying to understand your MT940 Library. I ran your testprogram. I have trouble to extract data. The most important one: opening balance. Without that I can not check my data input. It does not show up in your test program. I am not afraid to hack a bit, but I do not get into your program. What are you doing ? How does it work ? Please, enlighten me.
Kind regards,
Roel Dijkema
The shown example code should have your balance in it within
transactions.data
, if it doesn’t than perhaps your MT940 file is doing something the library doesn’t understand yet.Some extra docs can be found here: http://mt940.readthedocs.org/en/latest/
And the github repo where you can create issues if you’ve found bugs: https://github.com/WoLpH/mt940/
Hi Roel, This pull request should help you get the final opening balance on each transaction which what I think you’re looking for.
https://github.com/WoLpH/mt940/pull/19
– Ben
Hi Rick,
Thanks to this post. Could you elaborate the code bit more to get the output as a valid json format?
There’s no built-in way but it’s easy enough to write a json encoder:
[python]
import json
import mt940
transactions = mt940.parse(‘tests/jejik/abnamro.sta’)
def default(value):
if isinstance(value, mt940.models.Transactions):
data = value.data.copy()
data[‘transactions’] = value.transactions
return data
elif hasattr(value, ‘data’):
return value.data
print(json.dumps(transactions, default=default, indent=4))
[/python]
With this code,
import mt940
import pprint
# https://github.com/WoLpH/mt940/issues/85
transactions = mt940.parse(‘1591139129348.STA’, processors=dict(
post_transaction_details=[
mt940.processors.transaction_details_post_processor
],
))
for transaction in transactions:
# pprint.pprint(transaction.data)
# pprint.pprint(transactions.post_transaction_details)
pprint.pprint(transactions.processors.post_transaction_details)
I get this error message.
Traceback (most recent call last):
File “./mt940-test.transaction_details.py”, line 17, in
pprint.pprint(transactions.processors.post_transaction_details)
AttributeError: ‘dict’ object has no attribute ‘post_transaction_details’
How do I get at the stuff generated by
mt940.processors.transaction_details_post_processor
?
Hi. I’m trying to convert my MT940 from citiban( it is .txt file) to excel or csv file. But I’m a beginner for python and I’m struggling with reading the code you wrote, may I ask if I could message you more about the code? thanks in advance.
Hi Rick, i am trying to parse a BankingCircle files with your library but for many cases it fails to get the right data[‘bank_reference’]. it seems it breaks it in half. Is there a way that I can get for each transaction the whole 61 tag?