1
- """
2
- SQLAlchemy-JSONAPI
3
- Serializer
1
+ """SQLAlchemy-JSONAPI Serializer.
2
+
4
3
Colton J. Provias
5
4
MIT License
6
5
"""
19
18
from ._version import __version__
20
19
21
20
22
- class AttributeActions (Enum ):
23
- """ The actions that can be done to an attribute. """
24
-
25
- GET = 0
26
- SET = 1
21
+ class Actions (Enum ):
22
+ """ The actions that can be performed on an attribute or relationship. """
27
23
28
-
29
- class RelationshipActions (Enum ):
30
- """ The actions that can be performed on a relationship. """
31
-
32
- GET = 10
33
- APPEND = 11
34
- SET = 12
35
- DELETE = 13
24
+ GET = 1
25
+ APPEND = 2
26
+ SET = 3
27
+ REMOVE = 4
36
28
37
29
38
30
class Permissions (Enum ):
39
31
""" The permissions that can be set. """
40
32
41
- VIEW = 100
42
- CREATE = 101
43
- EDIT = 102
44
- DELETE = 103
33
+ VIEW = 1
34
+ CREATE = 2
35
+ EDIT = 3
36
+ DELETE = 4
45
37
46
38
47
39
ALL_PERMISSIONS = {
@@ -52,58 +44,26 @@ class Permissions(Enum):
52
44
}
53
45
54
46
55
- def attr_descriptor (action , * names ):
56
- """
57
- Wrap a function that allows for getting or setting of an attribute. This
58
- allows for specific handling of an attribute when it comes to serializing
59
- and deserializing.
60
-
61
- :param action: The AttributeActions that this descriptor performs
62
- :param names: A list of names of the attributes this references
63
- """
64
- if isinstance (action , AttributeActions ):
47
+ def jsonapi_action (action , * names ):
48
+ if isinstance (action , Actions ):
65
49
action = [action ]
66
50
67
51
def wrapped (fn ):
68
52
if not hasattr (fn , '__jsonapi_action__' ):
69
53
fn .__jsonapi_action__ = set ()
70
- fn .__jsonapi_desc_for_attrs__ = set ()
71
- fn .__jsonapi_desc_for_attrs__ |= set (names )
72
- fn .__jsonapi_action__ |= set (action )
73
- return fn
74
-
75
- return wrapped
76
-
77
-
78
- def relationship_descriptor (action , * names ):
79
- """
80
- Wrap a function for modification of a relationship. This allows for
81
- specific handling for serialization and deserialization.
82
-
83
- :param action: The RelationshipActions that this descriptor performs
84
- :param names: A list of names of the relationships this references
85
- """
86
- if isinstance (action , RelationshipActions ):
87
- action = [action ]
88
-
89
- def wrapped (fn ):
90
- if not hasattr (fn , '__jsonapi_action__' ):
91
- fn .__jsonapi_action__ = set ()
92
- fn .__jsonapi_desc_for_rels__ = set ()
93
- fn .__jsonapi_desc_for_rels__ |= set (names )
54
+ fn .__jsonapi_desc__ = set ()
55
+ fn .__jsonapi_desc__ |= set (names )
94
56
fn .__jsonapi_action__ |= set (action )
95
57
return fn
96
58
97
59
return wrapped
98
60
99
61
100
62
class PermissionTest (object ):
101
- """ Authorize access to a model, resource, or specific field. """
63
+ """Authorize access to a model, resource, or specific field."""
102
64
103
65
def __init__ (self , permission , * names ):
104
- """
105
- Decorates a function that returns a boolean representing if access is
106
- allowed.
66
+ """Decorate a function that returns a boolean representing access.
107
67
108
68
:param permission: The permission to check for
109
69
:param names: The names to test for. None represents the model.
@@ -128,14 +88,14 @@ def __call__(self, fn):
128
88
return fn
129
89
130
90
#: More consistent name for the decorators
131
- permission_test = PermissionTest
91
+ jsonapi_access = PermissionTest
132
92
133
93
134
94
class JSONAPIResponse (object ):
135
- """ Wrapper for JSON API Responses. """
95
+ """Wrapper for JSON API Responses."""
136
96
137
97
def __init__ (self ):
138
- """ Default the status code and data. """
98
+ """Default the status code and data."""
139
99
self .status_code = 200
140
100
self .data = {
141
101
'jsonapi' : {'version' : '1.0' },
@@ -158,8 +118,7 @@ def get_permission_test(model, field, permission, instance=None):
158
118
159
119
def check_permission (instance , field , permission ):
160
120
"""
161
- Check a permission for a given instance or field. Raises an error if
162
- denied.
121
+ Check a permission for a given instance or field. Raises error if denied.
163
122
164
123
:param instance: The instance to check
165
124
:param field: The field name to check or None for instance
@@ -175,10 +134,10 @@ def get_attr_desc(instance, attribute, action):
175
134
176
135
:param instance: Model instance
177
136
:param attribute: Name of the attribute
178
- :param action: AttributeAction
137
+ :param action: Action
179
138
"""
180
139
descs = instance .__jsonapi_attribute_descriptors__ .get (attribute , {})
181
- if action == AttributeActions .GET :
140
+ if action == Actions .GET :
182
141
check_permission (instance , attribute , Permissions .VIEW )
183
142
return descs .get (action , lambda x : getattr (x , attribute ))
184
143
check_permission (instance , attribute , Permissions .EDIT )
@@ -194,13 +153,13 @@ def get_rel_desc(instance, key, action):
194
153
:param action: RelationshipAction
195
154
"""
196
155
descs = instance .__jsonapi_rel_desc__ .get (key , {})
197
- if action == RelationshipActions .GET :
156
+ if action == Actions .GET :
198
157
check_permission (instance , key , Permissions .VIEW )
199
158
return descs .get (action , lambda x : getattr (x , key ))
200
- elif action == RelationshipActions .APPEND :
159
+ elif action == Actions .APPEND :
201
160
check_permission (instance , key , Permissions .CREATE )
202
161
return descs .get (action , lambda x , v : getattr (x , key ).append (v ))
203
- elif action == RelationshipActions .SET :
162
+ elif action == Actions .SET :
204
163
check_permission (instance , key , Permissions .EDIT )
205
164
return descs .get (action , lambda x , v : setattr (x , key , v ))
206
165
else :
@@ -300,7 +259,8 @@ def _lazy_relationship(self, api_type, obj_id, rel_key):
300
259
return {
301
260
'self' : '{}/{}/{}/relationships/{}' .format (self .prefix , api_type ,
302
261
obj_id , rel_key ),
303
- 'related' : '{}/{}/{}/{}' .format (self .prefix , api_type , obj_id , rel_key )
262
+ 'related' : '{}/{}/{}/{}' .format (self .prefix , api_type , obj_id ,
263
+ rel_key )
304
264
}
305
265
306
266
def _get_relationship (self , resource , rel_key , permission ):
@@ -367,8 +327,8 @@ def _render_full_resource(self, instance, include, fields):
367
327
attrs_to_ignore = {'__mapper__' , 'id' }
368
328
if api_type in fields .keys ():
369
329
local_fields = list (map ((
370
- lambda x : instance .__jsonapi_map_to_py__ [ x ]) , fields [
371
- api_type ] ))
330
+ lambda x : instance .__jsonapi_map_to_py__ . get ( x )) , fields . get (
331
+ api_type ) ))
372
332
else :
373
333
local_fields = orm_desc_keys
374
334
@@ -379,7 +339,7 @@ def _render_full_resource(self, instance, include, fields):
379
339
api_key = instance .__jsonapi_map_to_api__ [key ]
380
340
381
341
try :
382
- desc = get_rel_desc (instance , key , RelationshipActions .GET )
342
+ desc = get_rel_desc (instance , key , Actions .GET )
383
343
except PermissionDeniedError :
384
344
continue
385
345
@@ -446,7 +406,7 @@ def _render_full_resource(self, instance, include, fields):
446
406
447
407
for key in set (orm_desc_keys ) - attrs_to_ignore :
448
408
try :
449
- desc = get_attr_desc (instance , key , AttributeActions .GET )
409
+ desc = get_attr_desc (instance , key , Actions .GET )
450
410
if key in local_fields :
451
411
to_ret ['attributes' ][instance .__jsonapi_map_to_api__ [
452
412
key ]] = desc (instance )
0 commit comments