Source code for jsonmodels.parsers

"""Parsers to change model structure into different ones."""
import inspect

from . import fields, builders, errors


[docs]def to_struct(model): """Cast instance of model to python structure. :param model: Model to be casted. :rtype: ``dict`` """ model.validate() resp = {} for _, name, field in model.iterate_with_name(): value = field.__get__(model) if value is None: continue value = field.to_struct(value) resp[name] = value return resp
[docs]def to_json_schema(cls): """Generate JSON schema for given class. :param cls: Class to be casted. :rtype: ``dict`` """ builder = build_json_schema(cls) return builder.build()
[docs]def build_json_schema(value, parent_builder=None): from .models import Base cls = value if inspect.isclass(value) else value.__class__ if issubclass(cls, Base): return build_json_schema_object(cls, parent_builder) else: return build_json_schema_primitive(cls, parent_builder)
[docs]def build_json_schema_object(cls, parent_builder=None): builder = builders.ObjectBuilder(cls, parent_builder) if builder.count_type(builder.type) > 1: return builder for _, name, field in cls.iterate_with_name(): if isinstance(field, fields.EmbeddedField): builder.add_field(name, field, _parse_embedded(field, builder)) elif isinstance(field, fields.ListField): builder.add_field(name, field, _parse_list(field, builder)) else: builder.add_field( name, field, _create_primitive_field_schema(field)) return builder
def _parse_list(field, parent_builder): builder = builders.ListBuilder( parent_builder, field.nullable, default=field._default) for type in field.items_types: builder.add_type_schema(build_json_schema(type, builder)) return builder def _parse_embedded(field, parent_builder): builder = builders.EmbeddedBuilder( parent_builder, field.nullable, default=field._default) for type in field.types: builder.add_type_schema(build_json_schema(type, builder)) return builder
[docs]def build_json_schema_primitive(cls, parent_builder): builder = builders.PrimitiveBuilder(cls, parent_builder) return builder
def _create_primitive_field_schema(field): if isinstance(field, fields.StringField): obj_type = 'string' elif isinstance(field, fields.IntField): obj_type = 'number' elif isinstance(field, fields.FloatField): obj_type = 'float' elif isinstance(field, fields.BoolField): obj_type = 'boolean' else: raise errors.FieldNotSupported( 'Field {field} is not supported!'.format( field=type(field).__class__.__name__)) if field.nullable: obj_type = [obj_type, 'null'] schema = {'type': obj_type} if field.has_default: schema["default"] = field._default return schema