'Return a Model instance given the entity key.
It will use the context cache if the cache policy for the given
key is enabled.
Args:
key: Key instance.
**ctx_options: Context options.
Returns:
A Model instance if the key exists in the datastore; None otherwise.'

@tasklets.tasklet
def get(self, key, **ctx_options):

    options = _make_ctx_options(ctx_options)
    use_cache = self._use_cache(key, options)
    if use_cache:
        self._load_from_cache_if_available(key)
    use_datastore = self._use_datastore(key, options)
    if (use_datastore and isinstance(self._conn, datastore_rpc.TransactionalConnection)):
        use_memcache = False
    else:
        use_memcache = self._use_memcache(key, options)
    ns = key.namespace()
    memcache_deadline = None
    if use_memcache:
        mkey = (self._memcache_prefix + key.urlsafe())
        memcache_deadline = self._get_memcache_deadline(options)
        mvalue = (yield self.memcache_get(mkey, for_cas=use_datastore, namespace=ns, use_cache=True, deadline=memcache_deadline))
        if use_cache:
            self._load_from_cache_if_available(key)
        if (mvalue not in (_LOCKED, None)):
            cls = model.Model._lookup_model(key.kind(), self._conn.adapter.default_model)
            pb = entity_pb.EntityProto()
            try:
                pb.MergePartialFromString(mvalue)
            except ProtocolBuffer.ProtocolBufferDecodeError:
                logging.warning(('Corrupt    memcache    entry    found    with    key    %s    and    namespace    %s' % (mkey, ns)))
                mvalue = None
            else:
                entity = cls._from_pb(pb)
                entity._key = key
                if use_cache:
                    self._cache[key] = entity
                raise tasklets.Return(entity)
        if ((mvalue is None) and use_datastore):
            (yield self.memcache_set(mkey, _LOCKED, time=_LOCK_TIME, namespace=ns, use_cache=True, deadline=memcache_deadline))
            (yield self.memcache_gets(mkey, namespace=ns, use_cache=True, deadline=memcache_deadline))
    if (not use_datastore):
        raise tasklets.Return(None)
    if use_cache:
        entity = (yield self._get_batcher.add_once(key, options))
    else:
        entity = (yield self._get_batcher.add(key, options))
    if (entity is not None):
        if (use_memcache and (mvalue != _LOCKED)):
            pbs = entity._to_pb(set_key=False).SerializePartialToString()
            if (len(pbs) <= memcache.MAX_VALUE_SIZE):
                timeout = self._get_memcache_timeout(key, options)
                (yield self.memcache_cas(mkey, pbs, time=timeout, namespace=ns, deadline=memcache_deadline))
    if use_cache:
        self._cache[key] = entity
    raise tasklets.Return(entity)
