So you may have been frustrated when the Python repl and your IDEs should have autocompletion, but they simply don't autocomplete dictionary keys of a parsed json object while you're working with a novel or one off json object.
To see what I mean consider this repl session:
>>> import json
>>> params="""{"required_jobs":["bills"],"org_name":"Bank","allocation":{"targets":[]},
"end_user_id":"ffffffff-be11-c0de-beeb-b00lleafdead","deposit_forms":"n/a","end_user":{"chef":null},
"has_user_authentication_data":true,"cards":[{"card_name":"Credit"},
{"card_name":"Debit"}],"solution":"Bills","features":["bills"],"for_api_version":"2025-01-01"}"""
>>> p=json.loads(params)
>>> p['solution']
'Bills'
>>> p['org_name']
'Bank'
>>> p[⭲
KeyboardInterrupt
>>> p.⭲
KeyboardInterrupt p.get( p.pop( p.update(
>>> py() p.items() p.popitem() p.values()See how you can't autocomplete valid keys in p? At the ⭲ it won't give you any of the
dictionary keys, and was ^C interrupted, but it does give you attributes and methods.
The text over-wrote KeyboardInterrupt and >>> over the first two lines of suggestions
and cleared the rest of the suggested items.
If p were an object you could get autocompletion of the data IN your JSON object.
There's a fun way you can make that happen:
>>> from dataclasses import make_dataclass
>>> def mk_dc_obj(d: dict) -> object:
... _C = make_dataclass('_'.join(d.keys()), d.keys())
... return _C(**d)
...
>>> import json
>>> obj_params = json.loads(params, object_hook=mk_dc_obj)
>>> p.org_name
'Bank'
>>> obj_params.⭲
KeyboardInterrupttion obj_params.for_api_version
>>> params.cards obj_params.has_user_authentication_dataNote again, it had shown all of the suggestions but overwrote the interrupt and the prompt there. It looks like (note double tabbing):
>>> obj_params.⭲
[ not unique ]⭲
obj_params.allocation obj_params.for_api_version
obj_params.cards obj_params.has_user_authentication_data
obj_params.deposit_forms obj_params.org_name
obj_params.end_user obj_params.required_jobs
obj_params.end_user_id obj_params.solution
obj_params.features
and because you do it WITH the help of json.loads(..., object_hook=...) it goes deep enough
to auto-complete within objects, like:
>>> obj_params.a⭲
>>> obj_params.allocation.⭲
>>> obj_params.allocation.targets
[]
This is probably not a good idea for a large project, as your class names are generated based on the keys and might conflict with in use classes (probably not, if you follow the casing styles). And in the repl it sort of loses track of the type inside a list, objects in lists don't autocomplete their attributes, fields, members, unless you assign them to a name and try completing on the name.
>>> obj_params.__class__.__name__
'required_jobs_org_name_allocation_end_user_id_deposit_forms_end_user_has_user_authentication_data_cards_solution_features_for_api_version'
>>> obj_params.allocation.__class__.__name__
'targets'
>>> obj_params.end_user.__class__.__name__
'platform_matching'
>>> obj_params.cards[0].__class__.__name__
'card_name'
>>>
>>> card0 = obj_params.cards[0].⭲ # Does not autocomplete anything here
>>> card0 = obj_params.cards[0]
>>> card0.⭲ # Does autocomplete as shown below
>>> card0.card_name
'Credit'
>>>