This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
devicehub-teal/ereuse_devicehub/resources/schemas.py

82 lines
2.3 KiB
Python

from enum import Enum
from typing import Any
from marshmallow import post_load
from marshmallow.fields import DateTime, List, String
from marshmallow.schema import SchemaMeta
from teal.marshmallow import URL
from teal.resource import Schema
from ereuse_devicehub.resources import models as m
class UnitCodes(Enum):
mbyte = '4L'
mbps = 'E20'
mhz = 'MHZ'
gbyte = 'E34'
ghz = 'A86'
bit = 'A99'
kgm = 'KGM'
m = 'MTR'
def __str__(self):
return self.name
# The following SchemaMeta modifications allow us to generate
# documentation using our directive. This is their only purpose.
# Marshmallow's meta class removes variables from our defined
# classes, so we put some home made proxies in order to intercept
# those values and safe them in our classes.
# What we do is:
# 1. Make our ``Meta`` class be the superclass of Marshmallow's
# SchemaMeta and provide a new that stores in class, so we
# can save some vars.
# 2. Substitute SchemaMeta.get_declared_fields with our own method
# that saves more variables.
# Then the directive in our docs/config.py file reads these variables
# generating the documentation.
class Meta(type):
def __new__(cls, *args, **kw) -> Any:
base_name = args[1][0].__name__
y = super().__new__(cls, *args, **kw)
y._base_class = base_name
return y
SchemaMeta.__bases__ = Meta,
@classmethod
def get_declared_fields(mcs, klass, cls_fields, inherited_fields, dict_cls):
klass._own = cls_fields
klass._inherited = inherited_fields
return dict_cls(inherited_fields + cls_fields)
SchemaMeta.get_declared_fields = get_declared_fields
_type_description = """The name of the type of Thing,
like "Device" or "Receive". This is the same as JSON-LD ``@type``.
This field is required when submitting values
so Devicehub knows the type of object. Devicehub always returns this
value.
"""
class Thing(Schema):
type = String(description=_type_description)
same_as = List(URL(dump_only=True),
dump_only=True,
data_key='sameAs')
updated = DateTime('iso', dump_only=True, description=m.Thing.updated.comment)
created = DateTime('iso', dump_only=True, description=m.Thing.created.comment)
@post_load
def remove_type(self, data: dict):
data.pop('type', None)