Skip to content

Commit

Permalink
Allow where() and __contains__ with Tags. Closes #168.
Browse files Browse the repository at this point in the history
  • Loading branch information
polyatail committed Jan 29, 2019
1 parent 768ef34 commit 43a9150
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
3 changes: 3 additions & 0 deletions onecodex/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ def __eq__(self, other):
# two ResourceLists are equal if they refer to the same underlying Resource
return id(self._resource) == id(other._resource)

def __contains__(self, other):
return other.__hash__() in [x.__hash__() for x in self._res_list]

@property
def __repr__(self):
return self._res_list.__repr__
Expand Down
3 changes: 3 additions & 0 deletions onecodex/models/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def __repr__(self):
return '<{} {}: "{}">'.format(self.__class__.__name__, self.id,
truncate_string(self.name, 24))

def __hash__(self):
return hash(self.name)


class Users(OneCodexBase):
_resource_path = '/api/v1/users'
Expand Down
39 changes: 38 additions & 1 deletion onecodex/models/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from onecodex.exceptions import OneCodexException
from onecodex.lib.upload import upload
from onecodex.models import OneCodexBase, Projects
from onecodex.models import OneCodexBase, Projects, Tags
from onecodex.models.helpers import truncate_string


Expand All @@ -25,6 +25,40 @@ def where(cls, *filters, **keyword_filters):
instances_route = 'instances' if not public else 'instances_public'
limit = keyword_filters.get('limit', None if not public else 1000)

# handle conversion of tag UUIDs or names to Tags objects
tags = keyword_filters.pop('tags', [])

if not isinstance(tags, list):
tags = [tags]

new_tags = []

for t in tags:
if isinstance(t, Tags):
new_tags.append(t)
else:
# is it a uuid?
if len(t) == 16:
tag_obj = Tags.get(t)

if tag_obj is not None:
new_tags.append(tag_obj)
continue

# is it a name?
tag_obj = Tags.where(name=t)

if len(tag_obj) == 1:
new_tags.append(tag_obj[0])
continue
elif len(tag_obj) > 1:
raise OneCodexException('Multiple tags matched query: {}'.format(t))

raise OneCodexException('Unknown tag specified: {}'.format(t))

if new_tags:
keyword_filters['tags'] = new_tags

# we can only search metadata on our own samples currently
# FIXME: we need to add `instances_public` and `instances_project` metadata routes to
# mirror the ones on the samples
Expand Down Expand Up @@ -175,6 +209,9 @@ def download(self, path=None):
raise OneCodexException('Download failed with an HTTP status code {}.'.format(
exc.response.status_code))

def __hash__(self):
return hash(self.id)


class Metadata(OneCodexBase):
_resource_path = '/api/v1/metadata'
Expand Down

0 comments on commit 43a9150

Please sign in to comment.