imported patch NDB

This commit is contained in:
Joe Gregorio
2013-02-08 15:36:21 -05:00
parent c1fb7100e2
commit 78787b61b9

View File

@@ -31,7 +31,6 @@ from google.appengine.api import app_identity
from google.appengine.api import memcache from google.appengine.api import memcache
from google.appengine.api import users from google.appengine.api import users
from google.appengine.ext import db from google.appengine.ext import db
from google.appengine.ext import ndb
from google.appengine.ext import webapp from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import login_required from google.appengine.ext.webapp.util import login_required
from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext.webapp.util import run_wsgi_app
@@ -49,6 +48,13 @@ from oauth2client.client import Flow
from oauth2client.client import OAuth2WebServerFlow from oauth2client.client import OAuth2WebServerFlow
from oauth2client.client import Storage from oauth2client.client import Storage
# TODO(dhermes): Resolve import issue.
# This is a temporary fix for a Google internal issue.
try:
from google.appengine.ext import ndb
except ImportError:
ndb = None
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
OAUTH2CLIENT_NAMESPACE = 'oauth2client#ns' OAUTH2CLIENT_NAMESPACE = 'oauth2client#ns'
@@ -84,23 +90,23 @@ class SiteXsrfSecretKey(db.Model):
""" """
secret = db.StringProperty() secret = db.StringProperty()
if ndb is not None:
class SiteXsrfSecretKeyNDB(ndb.Model):
"""NDB Model for storage for the sites XSRF secret key.
class SiteXsrfSecretKeyNDB(ndb.Model): Since this model uses the same kind as SiteXsrfSecretKey, it can be used
"""NDB Model for storage for the sites XSRF secret key. interchangeably. This simply provides an NDB model for interacting with the
same data the DB model interacts with.
Since this model uses the same kind as SiteXsrfSecretKey, it can be used There should only be one instance stored of this model, the one used for the
interchangeably. This simply provides an NDB model for interacting with the site.
same data the DB model interacts with. """
secret = ndb.StringProperty()
There should only be one instance stored of this model, the one used for the @classmethod
site. def _get_kind(cls):
""" """Return the kind name for this class."""
secret = ndb.StringProperty() return 'SiteXsrfSecretKey'
@classmethod
def _get_kind(cls):
"""Return the kind name for this class."""
return 'SiteXsrfSecretKey'
def _generate_new_xsrf_secret_key(): def _generate_new_xsrf_secret_key():
@@ -217,30 +223,31 @@ class FlowProperty(db.Property):
return not value return not value
class FlowNDBProperty(ndb.PickleProperty): if ndb is not None:
"""App Engine NDB datastore Property for Flow. class FlowNDBProperty(ndb.PickleProperty):
"""App Engine NDB datastore Property for Flow.
Serves the same purpose as the DB FlowProperty, but for NDB models. Since Serves the same purpose as the DB FlowProperty, but for NDB models. Since
PickleProperty inherits from BlobProperty, the underlying representation of PickleProperty inherits from BlobProperty, the underlying representation of
the data in the datastore will be the same as in the DB case. the data in the datastore will be the same as in the DB case.
Utility property that allows easy storage and retrieval of an Utility property that allows easy storage and retrieval of an
oauth2client.Flow oauth2client.Flow
"""
def _validate(self, value):
"""Validates a value as a proper Flow object.
Args:
value: A value to be set on the property.
Raises:
TypeError if the value is not an instance of Flow.
""" """
logger.info('validate: Got type %s', type(value))
if value is not None and not isinstance(value, Flow): def _validate(self, value):
raise TypeError('Property %s must be convertible to a flow ' """Validates a value as a proper Flow object.
'instance; received: %s.' % (self._name, value))
Args:
value: A value to be set on the property.
Raises:
TypeError if the value is not an instance of Flow.
"""
logger.info('validate: Got type %s', type(value))
if value is not None and not isinstance(value, Flow):
raise TypeError('Property %s must be convertible to a flow '
'instance; received: %s.' % (self._name, value))
class CredentialsProperty(db.Property): class CredentialsProperty(db.Property):
@@ -289,65 +296,66 @@ class CredentialsProperty(db.Property):
return value return value
# TODO(dhermes): Turn this into a JsonProperty and overhaul the Credentials if ndb is not None:
# and subclass mechanics to use new_from_dict, to_dict, # TODO(dhermes): Turn this into a JsonProperty and overhaul the Credentials
# from_dict, etc. # and subclass mechanics to use new_from_dict, to_dict,
class CredentialsNDBProperty(ndb.BlobProperty): # from_dict, etc.
"""App Engine NDB datastore Property for Credentials. class CredentialsNDBProperty(ndb.BlobProperty):
"""App Engine NDB datastore Property for Credentials.
Serves the same purpose as the DB CredentialsProperty, but for NDB models. Serves the same purpose as the DB CredentialsProperty, but for NDB models.
Since CredentialsProperty stores data as a blob and this inherits from Since CredentialsProperty stores data as a blob and this inherits from
BlobProperty, the data in the datastore will be the same as in the DB case. BlobProperty, the data in the datastore will be the same as in the DB case.
Utility property that allows easy storage and retrieval of Credentials and Utility property that allows easy storage and retrieval of Credentials and
subclasses. subclasses.
"""
def _validate(self, value):
"""Validates a value as a proper credentials object.
Args:
value: A value to be set on the property.
Raises:
TypeError if the value is not an instance of Credentials.
""" """
logger.info('validate: Got type %s', type(value)) def _validate(self, value):
if value is not None and not isinstance(value, Credentials): """Validates a value as a proper credentials object.
raise TypeError('Property %s must be convertible to a credentials '
'instance; received: %s.' % (self._name, value))
def _to_base_type(self, value): Args:
"""Converts our validated value to a JSON serialized string. value: A value to be set on the property.
Args: Raises:
value: A value to be set in the datastore. TypeError if the value is not an instance of Credentials.
"""
logger.info('validate: Got type %s', type(value))
if value is not None and not isinstance(value, Credentials):
raise TypeError('Property %s must be convertible to a credentials '
'instance; received: %s.' % (self._name, value))
Returns: def _to_base_type(self, value):
A JSON serialized version of the credential, else '' if value is None. """Converts our validated value to a JSON serialized string.
"""
if value is None:
return ''
else:
return value.to_json()
def _from_base_type(self, value): Args:
"""Converts our stored JSON string back to the desired type. value: A value to be set in the datastore.
Args: Returns:
value: A value from the datastore to be converted to the desired type. A JSON serialized version of the credential, else '' if value is None.
"""
if value is None:
return ''
else:
return value.to_json()
Returns: def _from_base_type(self, value):
A deserialized Credentials (or subclass) object, else None if the """Converts our stored JSON string back to the desired type.
value can't be parsed.
""" Args:
if not value: value: A value from the datastore to be converted to the desired type.
return None
try: Returns:
# Uses the from_json method of the implied class of value A deserialized Credentials (or subclass) object, else None if the
credentials = Credentials.new_from_json(value) value can't be parsed.
except ValueError: """
credentials = None if not value:
return credentials return None
try:
# Uses the from_json method of the implied class of value
credentials = Credentials.new_from_json(value)
except ValueError:
credentials = None
return credentials
class StorageByKeyName(Storage): class StorageByKeyName(Storage):
@@ -385,7 +393,7 @@ class StorageByKeyName(Storage):
# issubclass will fail if one of the arguments is not a class, only need # issubclass will fail if one of the arguments is not a class, only need
# worry about new-style classes since ndb and db models are new-style # worry about new-style classes since ndb and db models are new-style
if isinstance(self._model, type): if isinstance(self._model, type):
if issubclass(self._model, ndb.Model): if ndb is not None and issubclass(self._model, ndb.Model):
return True return True
elif issubclass(self._model, db.Model): elif issubclass(self._model, db.Model):
return False return False
@@ -469,23 +477,24 @@ class CredentialsModel(db.Model):
credentials = CredentialsProperty() credentials = CredentialsProperty()
class CredentialsNDBModel(ndb.Model): if ndb is not None:
"""NDB Model for storage of OAuth 2.0 Credentials class CredentialsNDBModel(ndb.Model):
"""NDB Model for storage of OAuth 2.0 Credentials
Since this model uses the same kind as CredentialsModel and has a property Since this model uses the same kind as CredentialsModel and has a property
which can serialize and deserialize Credentials correctly, it can be used which can serialize and deserialize Credentials correctly, it can be used
interchangeably with a CredentialsModel to access, insert and delete the same interchangeably with a CredentialsModel to access, insert and delete the
entities. This simply provides an NDB model for interacting with the same entities. This simply provides an NDB model for interacting with the
same data the DB model interacts with. same data the DB model interacts with.
Storage of the model is keyed by the user.user_id(). Storage of the model is keyed by the user.user_id().
""" """
credentials = CredentialsNDBProperty() credentials = CredentialsNDBProperty()
@classmethod @classmethod
def _get_kind(cls): def _get_kind(cls):
"""Return the kind name for this class.""" """Return the kind name for this class."""
return 'CredentialsModel' return 'CredentialsModel'
def _build_state_value(request_handler, user): def _build_state_value(request_handler, user):