Source code for iso8583.tools

import sys as _sys
from typing import IO, AnyStr, Any


[docs]def add_field(doc_dec: dict, field: str, val: str) -> None: r"""Add or override field and its value in ISO8583 dictionary. Parameters ---------- doc_dec : dict Dict containing decoded ISO8583 data field : str Field key to be added val : str Field value to be added Examples -------- >>> import iso8583 >>> from iso8583.specs import default_ascii as spec >>> s = b"02004010100000000000161234567890123456123456840" >>> doc_dec, doc_enc = iso8583.decode(s, spec) >>> iso8583.pp(doc_dec, spec) 'bm' Enabled Fields : [2, 12, 20] 't' Message Type : [0200] 'p' Bitmap, Primary : [4010100000000000] '2' Primary Account Number (PAN) : 16 [1234567890123456] '12' Time, Local Transaction : [123456] '20' PAN Country Code : [840] >>> iso8583.add_field(doc_dec, "t", "0210") >>> iso8583.add_field(doc_dec, "39", "00") >>> s, doc_enc = iso8583.encode(doc_dec, spec) >>> iso8583.pp(doc_dec, spec) 'bm' Enabled Fields : [2, 12, 20, 39] 't' Message Type : [0210] 'p' Bitmap, Primary : [4010100002000000] '2' Primary Account Number (PAN) : 16 [1234567890123456] '12' Time, Local Transaction : [123456] '20' PAN Country Code : [840] '39' Response Code : [00] """ if "bm" not in doc_dec: doc_dec["bm"] = set() if field.isnumeric(): doc_dec["bm"].add(int(field)) doc_dec[field] = val
[docs]def del_field(doc_dec: dict, field: str) -> Any: r"""Delete field from ISO8583 dictionary. Parameters ---------- doc_dec : dict Dict containing decoded ISO8583 data field : int or str Field key to be deleted Returns ------- Key Value or None Deleted field value. None if the field did not exist. Examples -------- >>> import iso8583 >>> from iso8583.specs import default_ascii as spec >>> s = b"02004010100000000000161234567890123456123456840" >>> doc_dec, doc_enc = iso8583.decode(s, spec) >>> iso8583.pp(doc_dec, spec) 'bm' Enabled Fields : [2, 12, 20] 't' Message Type : [0200] 'p' Bitmap, Primary : [4010100000000000] '2' Primary Account Number (PAN) : 16 [1234567890123456] '12' Time, Local Transaction : [123456] '20' PAN Country Code : [840] >>> iso8583.del_field(doc_dec, "20") '840' >>> s, doc_enc = iso8583.encode(doc_dec, spec) >>> iso8583.pp(doc_dec, spec) 'bm' Enabled Fields : [2, 12] 't' Message Type : [0200] 'p' Bitmap, Primary : [4010000000000000] '2' Primary Account Number (PAN) : 16 [1234567890123456] '12' Time, Local Transaction : [123456] """ if "bm" not in doc_dec: doc_dec["bm"] = set() if field.isnumeric(): doc_dec["bm"].discard(int(field)) return doc_dec.pop(field, None)
[docs]def pp( doc_dec: dict, spec: dict, desc_width: int = 36, stream: IO[AnyStr] = None ) -> None: r"""Pretty Print Python dict containing decoded ISO8583 data. Parameters ---------- doc_dec : dict Dict containing decoded ISO8583 data spec : dict A Python dict defining ISO8583 specification. See iso8583.specs module for examples. desc_width : int, optional Width of field description that's printed (default 36). Specify 0 to print no descriptions. stream : stream, optional An output stream. The only method used on the stream object is the file protocol's write() method. If not specified, the :func:`iso8583.pp` adopts `sys.stdout`. Notes ----- For :func:`iso8583.pp` to work in all circumstances it's recommended to be used after :func:`iso8583.encode` or :func:`iso8583.decode`. Examples -------- >>> import iso8583 >>> from iso8583.specs import default_ascii as spec >>> s = b"02004010100000000000161234567890123456123456840" >>> doc_dec, doc_enc = iso8583.decode(s, spec) >>> iso8583.pp(doc_dec, spec) 'bm' Enabled Fields : [2, 12, 20] 't' Message Type : [0200] 'p' Bitmap, Primary : [4010100000000000] '2' Primary Account Number (PAN) : 16 [1234567890123456] '12' Time, Local Transaction : [123456] '20' PAN Country Code : [840] """ if stream is None: stream = _sys.stdout try: bm = doc_dec["bm"] except KeyError: bm = set() stream.write( "{index:5s} {desc: <{desc_width}}: {val}\n".format( index=repr("bm"), desc="Enabled Fields"[:desc_width], desc_width=desc_width, val=sorted(bm), ) ) if "h" in doc_dec: _pp_field(doc_dec, spec, desc_width, stream, "h") if "t" in doc_dec: _pp_field(doc_dec, spec, desc_width, stream, "t") if "p" in doc_dec: _pp_field(doc_dec, spec, desc_width, stream, "p") # Sorted list of field numbers as strings for f_id in [str(i) for i in sorted(bm)]: _pp_field(doc_dec, spec, desc_width, stream, f_id)
def _pp_field( doc_dec: dict, spec: dict, desc_width: int, stream: IO[AnyStr], f_id: str ) -> None: stream.write( "{index:5s} {desc: <{desc_width}}: ".format( index=repr(f_id), desc=spec[f_id]["desc"][:desc_width], desc_width=desc_width, ) ) if spec[f_id]["len_type"] > 0: stream.write( "{length:0{length_type}d} ".format( length=len(doc_dec[f_id]), length_type=spec[f_id]["len_type"] ) ) stream.write("[{val}]\n".format(val=doc_dec[f_id]))