/jsonmarshal

marshal json to/from dataclasses

Primary LanguagePythonMIT LicenseMIT

Unit Tests

JSON Marshal

Marshal JSON to and from python dataclasses

Json Field

To support unmarshalling from json jsonmarshal extends the existing dataclass field with the following options:

  • "json" option specifies the string key to be used when marshalling/unmarshalling to/from json. When the "json" option is not specified, the key on the dataclass will be used.

  • "omitempty" option specifies that the field should be omitted from marshalling if the field is typed as an Optional[...] value, and is set to None.

Marshal

Marshal python dataclasses into json.

marshal(data: Any, datetime_fmt: Optional[str] = None, date_fmt: Optional[str] = None) -> Any

Given a dataclass X, marshal it into a json serializable format.

The "datetime_fmt" option allows the user to specify the format to use when marshalling a datetime object into a string.

The "date_fmt" option allows the user to specify the format to use when marshalling a date object into a string.

Both "datetime_fmt" and "date_fmt" options use the strftime/strptime behaviour: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior

Unmarshal

Unmarshal a response containing loaded json (json.load(s)) into a specified dataclass schema.

unmarshal(response: Any, schema: T, datetime_fmt: Optional[str] = None, date_fmt: Optional[str] = None) -> T

The "datetime_fmt" option allows the user to specify the format to use when unmarshalling a string into a datetime object.

The "date_fmt" option allows the user to specify the format to use when unmarshalling a string into a date object.

Both "datetime_fmt" and "date_fmt" options use the strftime/strptime behaviour: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior

Examples:

A plain dataclass:

@dataclass
class Item:
    first_key: str
    second_key: int

item = Item(first_key: "hello", second_key: 100)

data = marshal(item)
{"first_key": "hello", "second_key": 100}

unmarshal(data, Item)
Item(first_key: "hello", second_key: 100)

A dataclass defining the json option:

@dataclass
class Item:
    first_key: str = json_field(json="firstKey")
    second_key: int = json_field(json="secondKey")

item = Item(first_key: "hello", second_key: 100)

data = marshal(item)
{"firstKey": "hello", "secondKey": 100}

unmarshal(data, Item)
Item(first_key: "hello", second_key: 100)

A dataclass defining the omitempty option:

@dataclass
class Item:
    first_key: Optional[str] = json_field(omitempty=True)
    second_key: Optional[int] = json_field(omitempty=True)

item = Item(first_key: None, second_key: 100)

data = marshal(item)
{"second_key": 100}

unmarshal(data, Item)
Item(first_key: None, second_key: 100)

A dataclass supporting Enums:

class Colour(Enum):
    RED = "RED"
    GREEN = "GREEN"

@dataclass
class Item:
    first_key: Colour
    second_key: Colour

item = Item(first_key: Colour.RED, second_key: Colour.GREEN)

data = marshal(item)
{"first_key": "RED", "second_key": "GREEN"}

unmarshal(data, Item)
Item(first_key: Colour.RED", second_key: Colour.GREEN)

A dataclass with dates/datetimes:

@dataclass
class Item:
    first_key: datetime
    second_key: date

item = Item(first_key: datetime(2020, 6, 11, 14, 32), second_key: date(2020, 5, 14))

data = marshal(item)
{"first_key": "2020-06-11T14:32:00", "second_key": "2020-05-14"}

unmarshal(data, Item)
Item(first_key: datetime(2020, 6, 11, 14, 32), second_key: date(2020, 5, 14))

A dataclass with dates/datetime supporting custom formats:

@dataclass
class Item:
    first_key: datetime
    second_key: date

item = Item(first_key: datetime(2020, 6, 11, 14, 32), second_key: date(2020, 5, 14))

data = marshal(item, datetime_fmt="%d %b %Y %H:%M", date_fmt="%d %b %Y")
{"first_key": "11 Jun 2020 14:32", "second_key": "14 Jun 2020"}

unmarshal(data, Item)
Item(first_key: datetime(2020, 6, 11, 14, 32), second_key: date(2020, 5, 14))

UUIDs get automatically marshalled to UUID type

@dataclass
class Item:
    first_key: UUID

item = Item(first_key: UUID("8b302ccb-fd97-4ce0-823a-eddd9ec1247d"))

data = marshal(item)
{"first_key": "8b302ccb-fd97-4ce0-823a-eddd9ec1247d"}

unmarshal(data, Item)
Item(first_key: UUID("8b302ccb-fd97-4ce0-823a-eddd9ec1247d"))