Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Support serialisation of dataclass properties #54

Closed
s-knibbs opened this issue May 21, 2019 · 1 comment · Fixed by #105
Closed

Support serialisation of dataclass properties #54

s-knibbs opened this issue May 21, 2019 · 1 comment · Fixed by #105
Labels
enhancement New feature or request

Comments

@s-knibbs
Copy link
Owner

It would be useful to be able to serialise dataclass properties as read-only properties in the json schema.

I propose to create a serialised_property subclass of property to do this, for example:

@dataclass
class Rectangle(JsonSchemaMixin):
    width: int
    height: int

    @serialised_property
    def area(self) -> int:
        return width * height

print(Rectangle(width=5, height=6).to_dict())
# Prints: {'width': 5, 'height': 6, 'area': 30}

This would generate the following json schema:

    "properties": {
        "width": {"type": "number"},
        "height": {"type": "number"},
        "area": {"type": "number", "readOnly": true},
    },
    "required": ["width", "height"]
}
@s-knibbs s-knibbs added the enhancement New feature or request label May 21, 2019
@s-knibbs
Copy link
Owner Author

Actually, I'm not sure the overriding @property is the best approach to implement this. This could potentially cause issues with code inspection tools.

Instead, a class argument could be added to enable this:

# Serialise all properties defined in the class
@dataclass
class Rectangle(JsonSchemaMixin, serialise_properties=True):
    width: int
    height: int

    @property
    def area(self) -> int:
        return width * height


# Serialise only the named properties
@dataclass
class Rectangle(JsonSchemaMixin, serialise_properties=("area",)):
    width: int
    height: int

    @property
    def area(self) -> int:
        return width * height

The following will iterate through the property type annotations:

def get_property_annotations(klass):
    members = inspect.getmembers(klass, inspect.isdatadescriptor)
    for name, member in members:
        if name != "__weakref__":
            yield (name, member.fget.__annotations__['return'])

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant