Keyword argument 'args' interfering with JSON Data Conversion. How can I deal with this?

Question:

Though I’ve read many threads describing JSON to Python object conversion, I could not find anything about the specific issue I’m trying to deal with. I’m new to Python so please excuse me in advance if I’m asking a dumb question or if I’m overexplaining in this post.

What I’m trying to accomplish:
I’m writing a script that listens to & handles events emitted by a smart contract, which then retrieves the event data in JSON format and converts it to Python object for further additional processing.

The problem:
The data received from the smart contract is unable to pass through the __init__(): function that converts it due to the way it’s formatted with the extra keyword ‘ "args": ‘ wrapped around the data, which causes a TypeError. I need to know how to change the formatting of my function to accommodate this.

Possible Solution:
It would seem that rather than declaring the arguments that pass through the conversion function individually, I should be passing "args": through as list containing the individual pieces of data enclosed within it. I am simply unfamiliar with how this is done. And I’m not sure if there’s something else that I’m missing as well…

An example:
Here is a sample of some JSON data that would pass through the function. It’s the very first word that is getting in my way. If I manually remove the ‘ "args": ‘ wrapping and then manually pass data through the function, it works as intended. But this is not possible when data is received directly from the contract.

{"args": {"host": "0x22892249CC60D7e17B12e2944Ae399eA33b4cc31", "bettor": "0x6D9224B34A72F4a59FD144Ad27fc78C12282242f", "requestId": 74240729112436359689875643194069807893866473208010485695632547688542158919953, "amountSettled": 91200000000000000, "didUserWin": true}, "event": "SettledCoinFlip", "logIndex": 0, "transactionIndex": 0, "transactionHash": "0x6df3ed3d1188394c2c39d8f27ca857d311dc6a473cd198154530002f229f095e", "address": "0x41071889D63E3Dd45b362C14ac71E3FF137Fbee7", "blockHash": "0x8313afdf3abd8a71112f3dd784477fdaebd5ec4c5de3807e1ac2e48c20b5d60b", "blockNumber": 19677422}

Here is the code for the function I’m trying to pass the data through:

def handle_event(event):

    print('<Event Detected, Receiving JSON Data>...')
    json_string = Web3.toJSON(event)
    print(Web3.toJSON(event))
    print('<Converting JSON Data>...')
    
    
    class Bet:
      def __init__(self, host, bettor, requestId, amountSettled, didUserWin, event, logIndex, transactionIndex, transactionHash, address, blockHash, blockNumber):
        self.host = host
        self.bettor = bettor
        self.requestId = requestId
        self.amountWagered = amountWagered
        self.didUserWin = didUserWin


      @classmethod
      def from_json(cls, json_string):
        json_dict = json.loads(json_string)
        return cls(**json_dict)

      def __repr__(self):
        return f'<Bet ID: { self.requestId }>'


    bet = Bet.from_json(json_string)
    print(bet)
    print(bet.host)
    print(bet.bettor)
    print(bet.amountSettled)
    print(bet.didUserWin)
    print('<Conversion Complete>') 
Asked By: Bandersnatch

||

Answers:

You could flatten the dictionary by unpacking first the popped args sub-dictionary and then the remainder of the dictionary i.e.

{ **json_dict.pop('args'), **json_dict }
Answered By: Nick