Skip to content

Instantly share code, notes, and snippets.

@gregorynicholas
Created February 6, 2013 18:42
Show Gist options
  • Save gregorynicholas/4724761 to your computer and use it in GitHub Desktop.
Save gregorynicholas/4724761 to your computer and use it in GitHub Desktop.
helper methods for working with appengine ndb models and dict / json serialization
from json import JSONEncoder, loads
from time import mktime
from datetime import date, datetime
from google.appengine.ext import ndb
from google.appengine.ext.ndb import query
def to_epoch(value):
"""
This is a view method to return the data in milli-seconds.
:param value: Instance of `datetime.datetime`.
:returns: `float` as the number of seconds since unix epoch.
"""
return mktime(value.utctimetuple()) * 1000
def from_epoch(value):
"""
:param value:
Instance of `float` as the number of seconds since unix epoch.
:returns:
Instance of `datetime.datetime`.
"""
return datetime.utcfromtimestamp(value / 1000)
def entity_to_dict(self, includes=None, excludes=None):
"""Encodes an `ndb.Model` to a `dict`. By default, only `ndb.Property`
attributes are included in the result.
:param include:
List of strings keys of class attributes. Can be the name of the
either a method or property.
:param exclude:
List of string keys to omit from the return value.
:returns: Instance of `dict`.
:raises: `ValueError` if any key in the `include` param doesn't exist.
"""
value = ndb.Model.to_dict(self)
# set the `id` of the entity's key by default..
if self.key:
value['key'] = self.key.urlsafe()
value['id'] = self.key.id()
if includes:
for inc in includes:
attr = getattr(self, inc, None)
if attr is None:
cls = self.__class__
logging.warn('entity_to_dict cannot encode `%s`. Property is \
not defined on `%s.%s`.', inc, cls.__module__, cls.__name__)
continue
if callable(attr):
value[inc] = attr()
else:
value[inc] = attr
if excludes:
# exclude items from the result dict, by popping the keys
# from the dict..
[value.pop(exc) for exc in excludes
if exc in value]
return value
def entity_from_dict(cls, value):
"""
:param cls: `ndb.Model` subclass.
:param value:
"""
def _decode(_result, _value):
"""
Deserializes `dict` values to `ndb.Property` values.
"""
for key, val in _value.iteritems():
prop = cls._properties.get(key)
# logging.error('prop: %s', dir(prop))
if prop is None:
logging.warn('entity_from_dict cannot decode: `%s`. Property is \
not defined on: `%s.%s`.', key, cls.__module__, cls.__name__)
continue
if isinstance(prop, (ndb.DateTimeProperty, ndb.DateProperty,
ndb.TimeProperty)):
if prop._repeated:
val = [from_epoch(v) for v in val]
else:
val = from_epoch(val)
if isinstance(prop, ndb.BlobKeyProperty):
if prop._repeated:
val = [ndb.BlobKey(urlsafe=v) for v in val]
else:
val = ndb.BlobKey(urlsafe=val)
if isinstance(prop, ndb.KeyProperty):
if prop._repeated:
val = [ndb.Key(urlsafe=v) for v in val]
else:
val = ndb.Key(urlsafe=val)
if isinstance(prop, ndb.BlobProperty):
pass
_result[key] = val
return _result
return cls(**_decode({}, value))
def entity_from_json(cls, value):
"""
Deserializes a json str to an instance of an `ndb.Model` subclass.
:param cls: `ndb.Model` subclass.
:param value:
"""
value = loads(value, strict=False)
if isinstance(value, list):
result = [entity_from_dict(cls, v) for v in value]
else:
result = entity_from_dict(cls, value)
return result
@claudiokc
Copy link

Thanks bro! Worked just fine 🎯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment