-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathserializers.py
139 lines (112 loc) · 5.05 KB
/
serializers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# -*- coding: utf-8 -*-
#
# This file is part of CERN Analysis Preservation Framework.
# Copyright (C) 2016 CERN.
#
# CERN Analysis Preservation Framework is free software; you can redistribute
# it and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# CERN Analysis Preservation Framework is distributed in the hope that it will
# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with CERN Analysis Preservation Framework; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.
"""Models for schemas."""
import copy
from flask import url_for
from cap.utils import url_to_api_url
from invenio_jsonschemas.proxies import current_jsonschemas
from marshmallow import Schema, ValidationError, fields, pre_load, validate
from .validators import JSONSchemaValidator
EDITABLE_FIELDS = [
'fullname',
'use_deposit_as_record',
'deposit_mapping',
'record_mapping',
'deposit_options',
'record_options',
]
class SchemaSerializer(Schema):
"""Default schema JSON serializer."""
name = fields.Str(required=True)
version = fields.Str(required=True,
validate=validate.Regexp(regex=r"(\d+).(\d+).(\d+)"))
fullname = fields.Str()
is_indexed = fields.Boolean(default=False)
use_deposit_as_record = fields.Boolean(default=False)
deposit_schema = fields.Dict(validate=JSONSchemaValidator())
deposit_options = fields.Dict()
deposit_mapping = fields.Dict()
record_schema = fields.Dict(validate=JSONSchemaValidator())
record_options = fields.Dict()
record_mapping = fields.Dict()
links = fields.Method('build_links', dump_only=True)
@pre_load
def filter_out_fields_that_cannot_be_updated(self, data, **kwargs):
"""Remove non editable fields from serialized data."""
if not data:
raise ValidationError('Empty data')
return data
def build_links(self, obj):
"""Construct schema links."""
deposit_path = url_for('invenio_jsonschemas.get_schema',
schema_path=obj.deposit_path, _external=True)
record_path = url_for('invenio_jsonschemas.get_schema',
schema_path=obj.record_path, _external=True)
links = {
'deposit': url_to_api_url(deposit_path),
'record': url_to_api_url(record_path)
}
links['self'] = url_to_api_url(
url_for('cap_schemas.schemas',
name=obj.name,
version=obj.version,
_method='PUT',
_external=True))
return links
class UpdateSchemaSerializer(SchemaSerializer):
"""Schema serializer with resolved jsonschemas."""
@pre_load
def filter_out_fields_that_cannot_be_updated(self, data, **kwargs):
"""Remove non editable fields from serialized data."""
data = {k: v for k, v in data.iteritems() if k in EDITABLE_FIELDS}
if not data:
raise ValidationError('Empty data')
return data
class SimplifiedSchemaSerializer(Schema):
"""Simplified serializer for schema."""
name = fields.Str(dump_only=True, required=True)
version = fields.Str(dump_only=True, required=True,
validate=validate.Regexp(regex=r"(\d+).(\d+).(\d+)"))
fullname = fields.Str(dump_only=True)
class ResolvedSchemaSerializer(SchemaSerializer):
"""Schema serializer with resolved jsonschemas."""
deposit_schema = fields.Method('get_resolved_deposit_schema',
dump_only=True)
record_schema = fields.Method('get_resolved_record_schema', dump_only=True)
def get_resolved_deposit_schema(self, obj):
"""Resolve refs in deposit schema."""
schema = current_jsonschemas.get_schema(obj.deposit_path,
with_refs=True,
resolved=True)
return copy.deepcopy(schema) # so all the JSONRefs get resoved
def get_resolved_record_schema(self, obj):
"""Resolve refs in record schema."""
schema = current_jsonschemas.get_schema(obj.record_path,
with_refs=True,
resolved=True)
return copy.deepcopy(schema) # so all the JSONRefs get resoved
schema_serializer = SchemaSerializer()
simplified_schema_serializer = SimplifiedSchemaSerializer()
update_schema_serializer = UpdateSchemaSerializer()
resolved_schemas_serializer = ResolvedSchemaSerializer()