Skip to content

Commit

Permalink
Add support for include and exclude attribute filtering on teh API model
Browse files Browse the repository at this point in the history
__json__ method.

This method gets called just before the response back to the user and
serializing API object to JSON.
Kami committed Aug 9, 2018
1 parent 5c80580 commit 80f1d40
Showing 2 changed files with 39 additions and 5 deletions.
4 changes: 4 additions & 0 deletions 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
2018-07-23 08:15:07,950 INFO [-] Installing pack "libcloude"
2018-07-23 08:15:07,953 DEBUG [-] Starting new HTTPS connection (1): index.stackstorm.org
2018-07-23 08:15:08,099 DEBUG [-] https://index.stackstorm.org:443 "GET /v1/index.json HTTP/1.1" 200 73045
2018-07-23 08:15:08,156 ERROR [-] Failed to install pack "libcloude": No record of the "libcloude" pack in the index.
40 changes: 35 additions & 5 deletions st2common/st2common/models/api/base.py
Original file line number Diff line number Diff line change
@@ -35,9 +35,14 @@
@six.add_metaclass(abc.ABCMeta)
class BaseAPI(object):
schema = abc.abstractproperty
include_attributes = ['name', 'pack']
exclude_attributes = None

def __init__(self, **kw):
for key, value in kw.items():
def __init__(self, include_attributes=None, exclude_attributes=None, **attrs):
self.include_attributes = include_attributes
self.exclude_attributes = exclude_attributes

for key, value in attrs.items():
setattr(self, key, value)

def __repr__(self):
@@ -53,7 +58,27 @@ def __str__(self):
return "%s[%s]" % (name, attrs)

def __json__(self):
return vars(self)
# Handle include and exclude attributes before returning the JSON response
attrs = vars(self)

include_attributes = self.include_attributes
exclude_attributes = self.exclude_attributes

# Common scenario - include and exclude attributes not provided
if not include_attributes and exclude_attributes:
return attrs

result = {}
for name, value in six.iteritems(attrs):
if include_attributes and name not in include_attributes:
continue

if exclude_attributes and name in exclude_attributes:
continue

result[name] = value

return result

def validate(self):
"""
@@ -68,6 +93,9 @@ def validate(self):
schema = getattr(self, 'schema', {})
attributes = vars(self)

del attributes['include_attributes']
del attributes['exclude_attributes']

cleaned = util_schema.validate(instance=attributes, schema=schema,
cls=util_schema.CustomValidator, use_default=True,
allow_default_none=True)
@@ -88,7 +116,8 @@ def _from_model(cls, model, mask_secrets=False):
return doc

@classmethod
def from_model(cls, model, mask_secrets=False):
def from_model(cls, model, mask_secrets=False, include_attributes=None,
exclude_attributes=None):
"""
Create API model class instance for the provided DB model instance.
@@ -101,7 +130,8 @@ def from_model(cls, model, mask_secrets=False):
doc = cls._from_model(model=model, mask_secrets=mask_secrets)
attrs = {attr: value for attr, value in six.iteritems(doc) if value is not None}

return cls(**attrs)
return cls(include_attributes=include_attributes, exclude_attributes=exclude_attributes,
**attrs)

@classmethod
def to_model(cls, doc):

0 comments on commit 80f1d40

Please sign in to comment.