Skip to main content

Custom json serialization support.

Project description

Easily add custom JSON serialization

Code Example

Defaults

import serial_json as json
import datetime

value = b'Hello World!'  # Bytes are not supported by json normally
assert json.loads(json.dumps(value)) == value

dt = datetime.datetime.now()  # datetimes are not supported by json normally
assert json.loads(json.dumps(dt)) == dt

Custom

Custom serialization using a classes __getstate__ and __setstate__ methods.

import serial_json as json

@json.register
class MyClass(object):
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __eq__(self, other):
        """Compare objects."""
        try:
            return self.x == other.x and self.y == other.y
        except (AttributeError, Exception):
            return False

    def __getstate__(self):
        return {'x': self.x, 'y': self.y}

    def __setstate__(self, state):
        self.x = state.get('x', 0)
        self.y = state.get('y', 0)

my_value = MyClass()
assert json.loads(json.dumps(my_value)) == my_value

Custom serialization with functions instead of a class with getstate and setstate.

import serial_json

class MyClass(object):
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __eq__(self, other):
        """Compare objects."""
        try:
            return self.x == other.x and self.y == other.y
        except (AttributeError, Exception):
            return False

def cls_to_dict(obj):
    return {'x': obj.x, 'y': obj.y}

def cls_from_dict(obj):
    return MyClass(**obj)

# Register the serialize and deserialize functions
serial_json.register(MyClass, cls_to_dict, cls_from_dict)

my_value = MyClass()
assert serial_json.loads(serial_json.dumps(my_value)) == my_value

dataclass

Dataclasses can be used through inheritance with DataClass or through the decorator dataclass.

import serial_json
from serial_json import dataclass, field_property, field

@dataclass
class Point:
    x: int
    y: int
    z: int = field(default=0, skip_repr=0, skip_dict=0)  # Do not include in repr if value is 0

help(Point)

# p = Point()  # Raises error for required positional arguments
p = Point(1, 2)
assert p.x == 1
assert p.y == 2
assert p.z == 0

class Location(serial_json.DataClass):
    name: str
    point: Point = Point(0, 0, 0)

    @field_property(default=Point(1, 1, 0))
    def point2(self):
        return self._point2

    @point2.setter
    def point2(self, value):
        if isinstance(value, (list, tuple)) and len(value) >= 2:
            value = Point(*value)
        elif isinstance(value, dict):
            value = Point(**value)

        if not isinstance(value, Point):
            raise TypeError('Given value must be a Point!')
        self._point2 = value

help(Location)

l = Location('hello')
assert l.name == 'hello'
assert l.point == Point(0, 0, 0)
assert l.point2 == Point(1, 1, 0)

l2 = Location('111', point=Point(x=1, y=1, z=1), point2=(2, 2, 0))
assert l2.name == '111'
assert l2.point == Point(1, 1, 1)
assert l2.point2 == Point(2, 2, 0)
assert str(l2) == 'Location(name=111, point=Point(x=1, y=1, z=1), point2=Point(x=2, y=2))'  # skip repr

datetime property

Additional datetime, date, time, and weekdays properties are available

import datetime
from serial_json import dataclass, datetime_property, Weekdays, weekdays_property, weekdays_attr_property

@dataclass
class Item:
    created_on: datetime.datetime = datetime_property('created_on', default_factory=datetime.datetime.now)
    weekdays: Weekdays = weekdays_property('weekdays', default=Weekdays())

    sunday = weekdays_attr_property('weekdays', 'sunday')
    monday = weekdays_attr_property('weekdays', 'monday')
    tuesday = weekdays_attr_property('weekdays', 'tuesday')
    wednesday = weekdays_attr_property('weekdays', 'wednesday')
    thursday = weekdays_attr_property('weekdays', 'thursday')
    friday = weekdays_attr_property('weekdays', 'friday')
    saturday = weekdays_attr_property('weekdays', 'saturday')

it = Item(weekdays='monday')
assert it.created_on is not None
assert it.created_on >= datetime.datetime.today().replace(hour=0)
assert 'monday' in it.weekdays
assert 'sunday' not in it.weekdays
assert it.monday
assert not it.sunday

it = Item(weekdays=[], friday=True)
assert it.created_on is not None
assert it.created_on >= datetime.datetime.today().replace(hour=0)
assert 'friday' in it.weekdays
assert 'sunday' not in it.weekdays
assert it.friday
assert not it.sunday

it = Item(sunday=False)
assert it.created_on is not None
assert it.created_on >= datetime.datetime.today().replace(hour=0)
assert 'friday' in it.weekdays, it.weekdays
assert 'sunday' not in it.weekdays, it.weekdays
assert it.friday
assert not it.sunday

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for serial-json, version 1.2.7
Filename, size File type Python version Upload date Hashes
Filename, size serial_json-1.2.7-py3-none-any.whl (59.8 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size serial_json-1.2.7.tar.gz (17.2 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page