Question

I'm trying to make a method which will allow me to query an endpoint by a users email. Is there a better way to do so then what I'm doing below? One that only return one or zero records perhaps.

    @User.query_method(query_fields=('email',),
                       path='get_by_mail',
                       name='user.get_by_email')
    def get_by_email(self, query):
        return query
Was it helpful?

Solution

I'm assuming User is some custom model that inherits from EndpointsModel. If not, this will fail. In other words, you've done something like this:

from google.appengine.ext import ndb
from endpoints_proto_datastore.ndb import EndpointsModel

class User(EndpointsModel):
    email = ndb.StringProperty()
    ...

There are two primary approaches to solving this problem, you could either use the email as the key for the entity or roll your own query and try to fetch two entities to see if your result is unique and exists.

OPTION 1: Use email as the key

Instead of doing a full-on query, you could do a simple get.

from google.appengine.ext import endpoints

@endpoints.api(...)
class SomeClass(...):

    @User.method(request_fields=('email',),
                 path='get_by_mail/{email}',
                 http_method='GET', name='user.get_by_email')
    def get_by_email(self, user):
        if not user.from_datastore:
            raise endpoints.NotFoundException('User not found.')
        return user

by using the email as the datastore key for each entity, as is done in the custom alias properties sample. For example:

from endpoints_proto_datastore.ndb import EndpointsAliasProperty

class User(EndpointsModel):
    # remove email here, as it will be an alias property 
    ...

    def EmailSet(self, value):
        # Validate the value any way you like
        self.UpdateFromKey(ndb.Key(User, value))

    @EndpointsAliasProperty(setter=IdSet, required=True)
    def email(self):
        if self.key is not None: return self.key.string_id()

OPTION 2: Roll your own query

    @User.method(request_fields=('email',),
                 path='get_by_mail/{email}',
                 http_method='GET', name='user.get_by_email')
    def get_by_email(self, user):
        query = User.query(User.email == user.email)
        # We fetch 2 to make sure we have
        matched_users = query.fetch(2)
        if len(matched_users == 0):
            raise endpoints.NotFoundException('User not found.')
        elif len(matched_users == 2):
            raise endpoints.BadRequestException('User not unique.')
        else:
            return matched_users[0]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top