Skip to content

Instantly share code, notes, and snippets.

@SCP002
Last active April 26, 2021 13:19
Show Gist options
  • Save SCP002/58d096a280fc8a9b2c6efab971d53045 to your computer and use it in GitHub Desktop.
Save SCP002/58d096a280fc8a9b2c6efab971d53045 to your computer and use it in GitHub Desktop.
Python: Dump & Load partially known / dynamic JSON. Using dataclasses (type safe).
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Requirements:
# Python 3.7+
# pip install dataclasses-json
import dataclasses as dc
import os
import sys
import traceback
from typing import List
import dataclasses_json as dcjson
@dcjson.dataclass_json(letter_case=dcjson.LetterCase.CAMEL, undefined=dcjson.Undefined.INCLUDE)
@dc.dataclass()
class Nested:
nested_known_key: int = dc.field(metadata=dcjson.config(field_name='nestedKnownKey'))
# Unknown fields go here:
unknown: dcjson.CatchAll
# Field sample for internal needs, excluded from JSON processing:
excluded: int = dc.field(default=0, metadata=dcjson.config(exclude=dcjson.cfg.Exclude.ALWAYS))
@dcjson.dataclass_json(letter_case=dcjson.LetterCase.CAMEL, undefined=dcjson.Undefined.INCLUDE)
@dc.dataclass()
class Top:
top_known_key: int = dc.field(metadata=dcjson.config(field_name='topKnownKey'))
nested_known_array: List[Nested] = dc.field(metadata=dcjson.config(field_name='nestedKnownArray'))
# Unknown fields go here:
unknown: dcjson.CatchAll
# Field sample for internal needs, excluded from JSON processing:
excluded: int = dc.field(default=0, metadata=dcjson.config(exclude=dcjson.cfg.Exclude.ALWAYS))
class App:
@staticmethod
def main() -> None:
json_str: str = """
{
"topKnownKey": 1,
"topUnknownKey": 2,
"nestedKnownArray": [
{
"nestedKnownKey": 3,
"nestedUnknownKey": 4
},
{
"nestedKnownKey": 5,
"nestedUnknownKey": 6
}
],
"nestedUnknownArray": [
{
"nestedKnownKey": 7,
"nestedUnknownKey": 8
}
]
}
"""
# Decode.
# noinspection Mypy
top: Top = Top.from_json(json_str)
# Modify.
top.top_known_key = 100
top.excluded = 200
top.nested_known_array[0].nested_known_key = 300
top.nested_known_array[0].excluded = 400
# Encode.
# noinspection Mypy
out: str = top.to_json(indent=2)
# Print output.
print(out)
input('Press <Enter> to exit...\n')
# Main start point.
if __name__ == '__main__':
# noinspection PyBroadException
try:
os.chdir(sys.path[0])
App.main()
except Exception:
traceback.print_exc()
input('Press <Enter> to exit...\n')
exit(1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment