advanced dstruct usage


1. we repeate a part of the basic example to make an account summary


In [1]:
from dstruct import DataStructFromJSON, DataField, datafield

In [2]:
# taken from the basic example
class AccountSummaryFromFile(DataStructFromJSON):
    
    user = DataField()
    type = DataField('account', 'account-type')
    ballance = DataField('account', 'account-ballance')
    # you can pass functions under the keyword "parser" to parse raw data parsing
    account_number = DataField('account', 'account-number', parser=lambda s: 'X'*len(s[:-4])+s[-4:])

In [3]:
AccountSummaryFromFile('data_files/bank_data.json')


Out[3]:
{"ballance": 1234.56, "type": "checking", "user": "John F. Doe", "account_number": "XXXXX6789"}

2. use nested DataStructs

  • nesting DataStructs allows for much more complex parsing patterns.

In [4]:
from dstruct import DataStruct
from datetime import datetime

In [5]:
class Transaction(DataStruct):
    
    amount = DataField()

    @datafield(path=None)
    def time(self, data):
        s = data['utc-unix']
        tz = data['time-zone']
        if 'UTC' not in tz:
            raise ValueError("Unknow time-zone standard: '%s'" % tz)
        else:
            dif = tz.replace('UTC', '')
            # trick for adding time-zone
            s = eval(str(s)+dif+'*60*60')

        dt = datetime.fromtimestamp(s)
        # return the parsed epoch time
        # for the given time-zone
        return dt.strftime('%Y-%m-%d %H:%M:%S')
    
    @datafield('source')
    def source(self, data):
        t = data['type']
        # we use the transaction type
        # to identify which kind of
        # `DataStruct` should be used
        if '-' in t:
            s = ''
            for sub in t.split('-'):
                s += sub.capitalize()
        else:
            s = t.capitalize()
        
        # we use `eval` to grab
        # the appropriate struct
        cls = eval(s)
        return cls(data)
    

class TransactionSource(DataStruct):
    
    ref = DataField()
    
class Purchase(TransactionSource):

    type = DataField()
    at = DataField('name')
    card = DataField(parser=lambda s: 'X'*len(s[:-4])+s[-4:])
    
class MobileDeposit(TransactionSource):

    type = DataField()
    note = DataField()
    check_number = DataField('check-number')


class DetailedAccountSummary(AccountSummaryFromFile):
    
    last_withdraw = DataField('account', 'withdrawn', '0', parser=Transaction)
    last_deposit = DataField('account', 'deposited', '0', parser=Transaction)

The Parsed Account Summary


In [6]:
print(DetailedAccountSummary('data_files/bank_data.json'))


{
    "account_number": "XXXXX6789",
    "ballance": 1234.56,
    "last_deposit": {
        "amount": 1057.21,
        "source": {
            "check_number": "1229361",
            "note": "bi-weekly paycheck",
            "ref": " #IB3GFRZG31",
            "type": "mobile-deposit"
        },
        "time": "2016-03-08 06:34:51"
    },
    "last_withdraw": {
        "amount": 23.03,
        "source": {
            "at": "Average-Restaurant",
            "card": "XXXXXXXXXXXX1112",
            "ref": "S567013305806010",
            "type": "purchase"
        },
        "time": "2016-03-08 06:34:51"
    },
    "type": "checking",
    "user": "John F. Doe"
}

The Raw JSON Data:

{
    "user": "John F. Doe",
    "billing-address": "123 Any Street Apt. 45 / Smallville, KS 1235",
    "account": {
        "account-type": "checking",
        "routing-number": "056004241",
        "account-number": "123456789",
        "account-ballance": 1234.56,
        "deposited": {
            "0": {
                "amount": 1057.21,
                "utc-unix": 1457476491,
                "time-zone": "UTC-8",
                "source": {
                    "type": "mobile-deposit",
                    "ref": " #IB3GFRZG31",
                    "routing-number": "944145221",
                    "account-number": "123123123",
                    "check-number": "1229361",
                    "note": "bi-weekly paycheck"
                }
            },
            "1": {
                "amount": "500.00",
                "utc-unix": 1459376666,
                "time-zone": "UTC-8",
                "source": {
                    "type": "online-transfer",
                    "ref": "#IBS5RWGWMM",
                    "routing-number": "044072324",
                    "account-number": "987654321",
                    "note": "monthly refill"
                }
            }

        },
        "withdrawn": {
            "0": {
                "amount": 23.03,
                "utc-unix": 1457476491,
                "time-zone": "UTC-8",
                "source": {
                    "card": "0123456789101112",
                    "type": "purchase",
                    "ref": "S567013305806010",
                    "name": "Average-Restaurant"
                }
            },
            "1": {
                "amount": 5.37,
                "utc-unix": 1457447400,
                "time-zone": "UTC-8",
                "card": "0123456789101112",
                "source": {
                    "type": "purchase",
                    "ref": "S466013457060112",
                    "name": "That-Super-Market"
                }
            }
        }
    }
}

In [ ]: