Records API

The records API is the lower level API. It parses each line of “OCR” text input into a record object. A record object also knows about its OCR representation.

For most use cases, the objects API is preferable to the records API.

File parsing

To parse an OCR file, you must first read the contents of the OCR file. It should be decoded using the ISO-8559-1 encoding:

with open('my-ocr-file.txt', 'r', encoding='iso-8859-1') as fh:
    data = fh.read()

For the purpose of the following example we use the following input data:

>>> data = '''
... NY000010555555551000081000080800000000000000000000000000000000000000000000000000
... NY210020000000000400008688888888888000000000000000000000000000000000000000000000
... NY2121300000001170604           00000000000000100          008000011688373000000
... NY2121310000001NAVN                                                        00000
... NY212149000000140011 Gjelder Faktura: 168837  Dato: 19/03/0400000000000000000000
... NY212149000000140012                  ForfallsDato: 17/06/0400000000000000000000
... NY2121300000002170604           00000000000000100          008000021688389000000
... NY2121310000002NAVN                                                        00000
... NY212149000000240011 Gjelder Faktura: 168838  Dato: 19/03/0400000000000000000000
... NY212149000000240012                  ForfallsDato: 17/06/0400000000000000000000
... NY2121300000003170604           00000000000000100          008000031688395000000
... NY2121310000003NAVN                                                        00000
... NY2121300000004170604           00000000000000100          008000041688401000000
... NY2121310000004NAVN                                                        00000
... NY2121300000005170604           00000000000000100          008000051688416000000
... NY2121310000005NAVN                                                        00000
... NY212149000000540011 Gjelder Faktura: 168841  Dato: 19/03/0400000000000000000000
... NY212149000000540012                  ForfallsDato: 17/06/0400000000000000000000
... NY2102300000006170604           00000000000000100          008000061688422000000
... NY2102310000006NAVN                                                        00000
... NY210088000000060000002000000000000000600170604170604000000000000000000000000000
... NY000089000000060000002200000000000000600170604000000000000000000000000000000000
... '''.strip()  # noqa

netsgiro.records.parse() parses the input and returns a record object for each line of input:

>>> import netsgiro.records
>>> records = netsgiro.records.parse(data)
>>> len(records)
22
>>> pprint(records)
[TransmissionStart(service_code=<ServiceCode.NONE: 0>, transmission_number='1000081', data_transmitter='55555555', data_recipient='00008080'),
 AssignmentStart(service_code=<ServiceCode.AVTALEGIRO: 21>, assignment_type=<AssignmentType.TRANSACTIONS: 0>, assignment_number='4000086', assignment_account='88888888888', agreement_id='000000000'),
 TransactionAmountItem1(service_code=<ServiceCode.AVTALEGIRO: 21>, transaction_type=<TransactionType.PURCHASE_WITH_TEXT: 21>, transaction_number=1, nets_date=datetime.date(2004, 6, 17), amount=100, kid='008000011688373', centre_id=None, day_code=None, partial_settlement_number=None, partial_settlement_serial_number=None, sign=None),
 TransactionAmountItem2(service_code=<ServiceCode.AVTALEGIRO: 21>, transaction_type=<TransactionType.PURCHASE_WITH_TEXT: 21>, transaction_number=1, reference=None, form_number=None, bank_date=None, debit_account=None, _filler=None, payer_name='NAVN'),
 TransactionSpecification(service_code=<ServiceCode.AVTALEGIRO: 21>, transaction_type=<TransactionType.PURCHASE_WITH_TEXT: 21>, transaction_number=1, line_number=1, column_number=1, text=' Gjelder Faktura: 168837  Dato: 19/03/04'),
 TransactionSpecification(service_code=<ServiceCode.AVTALEGIRO: 21>, transaction_type=<TransactionType.PURCHASE_WITH_TEXT: 21>, transaction_number=1, line_number=1, column_number=2, text='                  ForfallsDato: 17/06/04'),
 ...
 AssignmentEnd(service_code=<ServiceCode.AVTALEGIRO: 21>, assignment_type=<AssignmentType.TRANSACTIONS: 0>, num_transactions=6, num_records=20, total_amount=600, nets_date_1=datetime.date(2004, 6, 17), nets_date_2=datetime.date(2004, 6, 17), nets_date_3=None),
 TransmissionEnd(service_code=<ServiceCode.NONE: 0>, num_transactions=6, num_records=22, total_amount=600, nets_date=datetime.date(2004, 6, 17))]
netsgiro.records.parse(data: str) → typing.List[netsgiro.records.Record][source]

Parse an OCR file into a list of record objects.

Record types

Given a record object, all record fields are available as sensible Python types:

>>> assignment_end = records[-2]
>>> assignment_end.service_code
<ServiceCode.AVTALEGIRO: 21>
>>> assignment_end.RECORD_TYPE
<RecordType.ASSIGNMENT_END: 88>
>>> assignment_end.assignment_type
<AssignmentType.TRANSACTIONS: 0>
>>> assignment_end.nets_date_earliest
datetime.date(2004, 6, 17)
>>> assignment_end.nets_date_latest
datetime.date(2004, 6, 17)
>>> assignment_end.num_records
20
>>> assignment_end.num_transactions
6
>>> assignment_end.total_amount
600

You can also convert the record back to an OCR string:

>>> assignment_end.to_ocr()
'NY210088000000060000002000000000000000600170604170604000000000000000000000000000'

For details on the semantics of each field, please refer to Nets’ documentation. The reference directory of the netsgiro Git repo contains the file format specifications, which is a good place to start.

class netsgiro.records.TransmissionStart(service_code, transmission_number, data_transmitter, data_recipient)[source]

TransmissionStart is the first record in every OCR file.

A file can only contain a single transmission.

Each transmission can contain any number of assignments.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 10
data_recipient = Attribute(name='data_recipient', default=NOTHING, validator=<function str_of_length.<locals>.validator>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
data_transmitter = Attribute(name='data_transmitter', default=NOTHING, validator=<function str_of_length.<locals>.validator>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
transmission_number = Attribute(name='transmission_number', default=NOTHING, validator=<function str_of_length.<locals>.validator>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
class netsgiro.records.TransmissionEnd(service_code, num_transactions, num_records, total_amount, nets_date)[source]

TransmissionEnd is the first record in every OCR file.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 89
nets_date = Attribute(name='nets_date', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_date>, metadata=mappingproxy({}))
num_records = Attribute(name='num_records', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
num_transactions = Attribute(name='num_transactions', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
total_amount = Attribute(name='total_amount', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
class netsgiro.records.AssignmentStart(service_code, assignment_type, assignment_number, assignment_account, agreement_id=None)[source]

AssignmentStart is the first record of an assignment.

Each assignment can contain any number of transactions.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 20
agreement_id = Attribute(name='agreement_id', default=None, validator=<optional validator for <function str_of_length.<locals>.validator> or None>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
assignment_account = Attribute(name='assignment_account', default=NOTHING, validator=<function str_of_length.<locals>.validator>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
assignment_number = Attribute(name='assignment_number', default=NOTHING, validator=<function str_of_length.<locals>.validator>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
assignment_type = Attribute(name='assignment_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_assignment_type>, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
class netsgiro.records.AssignmentEnd(service_code, assignment_type, num_transactions, num_records, total_amount=None, nets_date_1=None, nets_date_2=None, nets_date_3=None)[source]

AssignmentEnd is the last record of an assignment.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 88
assignment_type = Attribute(name='assignment_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_assignment_type>, metadata=mappingproxy({}))
nets_date

Nets’ processing date.

Only used for OCR Giro.

nets_date_1 = Attribute(name='nets_date_1', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_date>, metadata=mappingproxy({}))
nets_date_2 = Attribute(name='nets_date_2', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_date>, metadata=mappingproxy({}))
nets_date_3 = Attribute(name='nets_date_3', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_date>, metadata=mappingproxy({}))
nets_date_earliest

Earliest date from the contained transactions.

nets_date_latest

Latest date from the contained transactions.

num_records = Attribute(name='num_records', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
num_transactions = Attribute(name='num_transactions', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
total_amount = Attribute(name='total_amount', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_int>, metadata=mappingproxy({}))
class netsgiro.records.TransactionAmountItem1(service_code, transaction_type, transaction_number, nets_date, amount, kid, centre_id=None, day_code=None, partial_settlement_number=None, partial_settlement_serial_number=None, sign=None)[source]

TransactionAmountItem1 is the first record of a transaction.

The record is used both for AvtaleGiro and for OCR Giro.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 30
amount = Attribute(name='amount', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
centre_id = Attribute(name='centre_id', default=None, validator=<optional validator for <function str_of_length.<locals>.validator> or None>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
day_code = Attribute(name='day_code', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_int>, metadata=mappingproxy({}))
kid = Attribute(name='kid', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_str>, metadata=mappingproxy({}))
nets_date = Attribute(name='nets_date', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_date>, metadata=mappingproxy({}))
partial_settlement_number = Attribute(name='partial_settlement_number', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_int>, metadata=mappingproxy({}))
partial_settlement_serial_number = Attribute(name='partial_settlement_serial_number', default=None, validator=<optional validator for <function str_of_length.<locals>.validator> or None>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
sign = Attribute(name='sign', default=None, validator=<optional validator for <function str_of_length.<locals>.validator> or None>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
transaction_number = Attribute(name='transaction_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
transaction_type = Attribute(name='transaction_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_transaction_type>, metadata=mappingproxy({}))
class netsgiro.records.TransactionAmountItem2(service_code, transaction_type, transaction_number, reference, form_number=None, bank_date=None, debit_account=None, filler=None, payer_name=None)[source]

TransactionAmountItem2 is the second record of a transaction.

The record is used both for AvtaleGiro and for OCR Giro.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 31
bank_date = Attribute(name='bank_date', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_date>, metadata=mappingproxy({}))
debit_account = Attribute(name='debit_account', default=None, validator=<optional validator for <function str_of_length.<locals>.validator> or None>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
form_number = Attribute(name='form_number', default=None, validator=<optional validator for <function str_of_length.<locals>.validator> or None>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
payer_name = Attribute(name='payer_name', default=None, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_str>, metadata=mappingproxy({}))
reference = Attribute(name='reference', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_str>, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
transaction_number = Attribute(name='transaction_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
transaction_type = Attribute(name='transaction_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_transaction_type>, metadata=mappingproxy({}))
class netsgiro.records.TransactionAmountItem3(service_code, transaction_type, transaction_number, text)[source]

TransactionAmountItem3 is the third record of a transaction.

The record is only used for some OCR Giro transaction types.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 32
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
text = Attribute(name='text', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_str>, metadata=mappingproxy({}))
transaction_number = Attribute(name='transaction_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
transaction_type = Attribute(name='transaction_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_transaction_type>, metadata=mappingproxy({}))
class netsgiro.records.TransactionSpecification(service_code, transaction_type, transaction_number, line_number, column_number, text)[source]

TransactionSpecification is used for AvtaleGiro transactions.

The record is only used when bank notification is used to notify the payer.

Each record contains half of an 80 char long line of text and can be repeated up to 84 times for a single transaction for a total of 42 lines of specification text.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

classmethod from_text(*, service_code, transaction_type, transaction_number, text) → typing.Iterable[typing.TransactionSpecification][source]

Create a sequence of specification records from a text string.

to_ocr() → str[source]

Get record as OCR string.

classmethod to_text(records: typing.Sequence[typing.TransactionSpecification]) → str[source]

Get a text string from a sequence of specification records.

RECORD_TYPE = 49
column_number = Attribute(name='column_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
line_number = Attribute(name='line_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
text = Attribute(name='text', default=NOTHING, validator=<instance_of validator for type <class 'str'>>, repr=True, cmp=True, hash=None, init=True, convert=None, metadata=mappingproxy({}))
transaction_number = Attribute(name='transaction_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
transaction_type = Attribute(name='transaction_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_transaction_type>, metadata=mappingproxy({}))
class netsgiro.records.AvtaleGiroAgreement(service_code, transaction_type, transaction_number, registration_type, kid, notify)[source]

AvtaleGiroAgreement is used by Nets to notify about agreement changes.

This includes new or deleted agreements, as well as updates to the payer’s notification preferences.

from_string(line: str) → netsgiro.records.Record

Parse OCR string into a record object.

to_ocr() → str[source]

Get record as OCR string.

RECORD_TYPE = 70
kid = Attribute(name='kid', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function optional_str>, metadata=mappingproxy({}))
notify = Attribute(name='notify', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_bool>, metadata=mappingproxy({}))
registration_type = Attribute(name='registration_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_avtalegiro_registration_type>, metadata=mappingproxy({}))
service_code = Attribute(name='service_code', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_service_code>, metadata=mappingproxy({}))
transaction_number = Attribute(name='transaction_number', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<class 'int'>, metadata=mappingproxy({}))
transaction_type = Attribute(name='transaction_type', default=NOTHING, validator=None, repr=True, cmp=True, hash=None, init=True, convert=<function to_transaction_type>, metadata=mappingproxy({}))