Skip to content

Commit

Permalink
Merge pull request #31 from solvebio/feature/annotate-broken
Browse files Browse the repository at this point in the history
Feature/annotate broken
  • Loading branch information
rocky committed Oct 16, 2014
2 parents 0708d08 + cfd7c22 commit 57a3b3e
Show file tree
Hide file tree
Showing 21 changed files with 191 additions and 141 deletions.
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ipython
nose
4 changes: 1 addition & 3 deletions solvebio/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,7 @@ def emit(self, record):

from . import version
from .errors import SolveError
from .resource import (User, Depository, DepositoryVersion, Dataset, # noqa
DatasetField, Annotation, Sample)
from .query import Query, PagingQuery, BatchQuery, Filter, RangeFilter # noqa
from .query import Query, PagingQuery, Filter, RangeFilter

__all__ = ['version',
'Annotation'
Expand Down
17 changes: 9 additions & 8 deletions solvebio/resource/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"""Glues together all SolveObjects"""
# For the future...
# from Dataset import Dataset
# from DatasetField import DatasetField
from depository import Depository
from depositoryversion import DepositoryVersion
from resource import Dataset, User, \
ListObject, DatasetField
# __package__ = 'solvebio.resource'

from .depository import Depository
from .depositoryversion import DepositoryVersion
from .resource import ListObject
from .annotation import Annotation
from .sample import Sample
from .sample import Sample
from .user import User
from .dataset import Dataset
from .datasetfield import DatasetField


types = {
Expand Down
77 changes: 77 additions & 0 deletions solvebio/resource/dataset.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
"""Dataset Class"""
import re

# __package__ = 'solvebio.resource'
from ..client import client
from ..help import open_help
from ..query import Query, PagingQuery

from .solveobject import convert_to_solve_object
from .resource import CreateableAPIResource, ListableAPIResource, \
UpdateableAPIResource
from .datasetfield import DatasetField


class Dataset(CreateableAPIResource, ListableAPIResource,
UpdateableAPIResource):
"""
Datasets are access points to data. Dataset names are unique
within versions of a depository.
"""
ALLOW_FULL_NAME_ID = True
FULL_NAME_REGEX = r'^([\w\d\-\.]+/){2}[\w\d\-\.]+$'

@classmethod
def retrieve(cls, id, **params):
"""Supports lookup by full name"""
if isinstance(id, unicode) or isinstance(id, str):
_id = unicode(id).strip()
id = None
if re.match(cls.FULL_NAME_REGEX, _id):
params.update({'full_name': _id})
else:
raise Exception('Unrecognized full name.')

return super(Dataset, cls).retrieve(id, **params)

def depository_version(self):
from .depositoryversion import DepositoryVersion
return DepositoryVersion.retrieve(self['depository_version'])

def depository(self):
from .depository import Depository
return Depository.retrieve(self['depository'])

def fields(self, name=None, **params):
if 'fields_url' not in self:
raise Exception(
'Please use Dataset.retrieve({ID}) before doing looking '
'up fields')

if name:
# construct the field's full_name if a field name is provided
return DatasetField.retrieve(
'/'.join([self['full_name'], name]))

response = client.request('get', self.fields_url, params)
return convert_to_solve_object(response)

def _data_url(self):
if 'data_url' not in self:
if 'id' not in self or not self['id']:
raise Exception(
'No Dataset ID was provided. '
'Please instantiate the Dataset '
'object with an ID or full_name.')
# automatically construct the data_url from the ID
return self.instance_url() + u'/data'
return self['data_url']

def query(self, paging=False, **params):
self._data_url() # raises an exception if there's no ID
query_klass = PagingQuery if paging else Query
q = query_klass(self['id'], **params)
return q.filter(params.get('filters')) if params.get('filters') else q

def help(self):
open_help(self['full_name'])
39 changes: 39 additions & 0 deletions solvebio/resource/datasetfield.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""DatasetField Class"""
import re

from ..client import client

from .solveobject import convert_to_solve_object
from .resource import CreateableAPIResource, ListableAPIResource, \
UpdateableAPIResource


class DatasetField(CreateableAPIResource, ListableAPIResource,
UpdateableAPIResource):
"""
Each SolveBio dataset has a different set of fields, some of
which can be used as filters. Dataset field resources provide
users with documentation about each field.
"""
ALLOW_FULL_NAME_ID = True
FULL_NAME_REGEX = r'^([\w\d\-\.]+/){3}[\w\d\-\.]+$'

@classmethod
def retrieve(cls, id, **params):
"""Supports lookup by ID or full name"""
if isinstance(id, unicode) or isinstance(id, str):
_id = unicode(id).strip()
id = None
if re.match(cls.FULL_NAME_REGEX, _id):
params.update({'full_name': _id})
else:
raise Exception('Unrecognized full name.')

return super(DatasetField, cls).retrieve(id, **params)

def facets(self, **params):
response = client.request('get', self.facets_url, params)
return convert_to_solve_object(response)

def help(self):
return self.facets()
14 changes: 10 additions & 4 deletions solvebio/resource/depository.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
"""Depository Class"""

from resource import CreateableAPIResource, ListableAPIResource, \
SearchableAPIResource, UpdateableAPIResource
from solveobject import convert_to_solve_object
# __package__ = 'solvebio.resource'
import re

from ..client import client
from ..help import open_help

from .solveobject import convert_to_solve_object
from .resource import CreateableAPIResource, ListableAPIResource, \
SearchableAPIResource, UpdateableAPIResource
from .depositoryversion import DepositoryVersion


class Depository(CreateableAPIResource, ListableAPIResource,
SearchableAPIResource, UpdateableAPIResource):
"""
Expand Down
13 changes: 9 additions & 4 deletions solvebio/resource/depositoryversion.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
"""DepositoryVersion Class"""

from resource import CreateableAPIResource, ListableAPIResource, \
UpdateableAPIResource
from solveobject import convert_to_solve_object
import re

from ..client import client
from ..help import open_help

from .solveobject import convert_to_solve_object
from .resource import CreateableAPIResource, ListableAPIResource, \
UpdateableAPIResource
from .dataset import Dataset


class DepositoryVersion(CreateableAPIResource, ListableAPIResource,
UpdateableAPIResource):

Expand Down
95 changes: 0 additions & 95 deletions solvebio/resource/resource.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
# -*- coding: utf-8 -*-
import urllib
import re

from ..client import client
from ..query import Query, PagingQuery
from ..help import open_help

from .util import class_to_api_name
from .solveobject import SolveObject, convert_to_solve_object


class APIResource(SolveObject):
# from pydbgr.api import debug; debug()
# types[self.__class__.__name__] = self

@classmethod
def retrieve(cls, id, **params):
Expand Down Expand Up @@ -159,93 +154,3 @@ class DeletableAPIResource(APIResource):
def delete(self, **params):
self.refresh_from(self.request('delete', self.instance_url(), params))
return self


# API resources

class User(SingletonAPIResource):
pass

class Dataset(CreateableAPIResource, ListableAPIResource,
UpdateableAPIResource):
ALLOW_FULL_NAME_ID = True
FULL_NAME_REGEX = r'^([\w\d\-\.]+/){2}[\w\d\-\.]+$'

@classmethod
def retrieve(cls, id, **params):
"""Supports lookup by full name"""
if isinstance(id, unicode) or isinstance(id, str):
_id = unicode(id).strip()
id = None
if re.match(cls.FULL_NAME_REGEX, _id):
params.update({'full_name': _id})
else:
raise Exception('Unrecognized full name.')

return super(Dataset, cls).retrieve(id, **params)

def depository_version(self):
return DepositoryVersion.retrieve(self['depository_version'])

def depository(self):
return Depository.retrieve(self['depository'])

def fields(self, name=None, **params):
if 'fields_url' not in self:
raise Exception(
'Please use Dataset.retrieve({ID}) before doing looking '
'up fields')

if name:
# construct the field's full_name if a field name is provided
return DatasetField.retrieve(
'/'.join([self['full_name'], name]))

response = client.request('get', self.fields_url, params)
return convert_to_solve_object(response)

def _data_url(self):
if 'data_url' not in self:
if 'id' not in self or not self['id']:
raise Exception(
'No Dataset ID was provided. '
'Please instantiate the Dataset '
'object with an ID or full_name.')
# automatically construct the data_url from the ID
return self.instance_url() + u'/data'
return self['data_url']

def query(self, paging=False, **params):
self._data_url() # raises an exception if there's no ID
query_klass = PagingQuery if paging else Query
q = query_klass(self['id'], **params)
return q.filter(params.get('filters')) if params.get('filters') else q

def help(self):
open_help(self['full_name'])


class DatasetField(CreateableAPIResource, ListableAPIResource,
UpdateableAPIResource):
ALLOW_FULL_NAME_ID = True
FULL_NAME_REGEX = r'^([\w\d\-\.]+/){3}[\w\d\-\.]+$'

@classmethod
def retrieve(cls, id, **params):
"""Supports lookup by ID or full name"""
if isinstance(id, unicode) or isinstance(id, str):
_id = unicode(id).strip()
id = None
if re.match(cls.FULL_NAME_REGEX, _id):
params.update({'full_name': _id})
else:
raise Exception('Unrecognized full name.')

return super(DatasetField, cls).retrieve(id, **params)

def facets(self, **params):
response = client.request('get', self.facets_url, params)
return convert_to_solve_object(response)

def help(self):
return self.facets()
3 changes: 2 additions & 1 deletion solvebio/resource/sample.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ def create(cls, genome_build, **params):
"""
if 'vcf_url' in params:
if 'vcf_file' in params:
raise TypeError('Specified both vcf_url and vcf_file; use only one')
raise TypeError('Specified both vcf_url and vcf_file; ' +
'use only one')
return Sample.create_from_url(genome_build, params['vcf_url'])
elif 'vcf_file' in params:
return Sample.create_from_file(genome_build, params['vcf_file'])
Expand Down
1 change: 1 addition & 0 deletions solvebio/resource/solveobject.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
from ..client import client

from .util import json


Expand Down
6 changes: 6 additions & 0 deletions solvebio/resource/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
from .resource import SingletonAPIResource


class User(SingletonAPIResource):
pass
20 changes: 14 additions & 6 deletions solvebio/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,27 @@


def all_names():
for _, modname, _ in pkgutil.iter_modules(__path__):
for i, modname, j in pkgutil.iter_modules(__path__):
print i, j
print modname
# FIXME: figure out why test loader can't resolve
# solvebio.test.test_conversion
if modname == 'test_conversion':
continue
if modname.startswith('test_modify_'):
continue
# if modname in ('test_conversion',
# # 'test_annotation_access',
# # 'test_query',
# # 'test_query_batch',
# # 'test_query_paging',
# # 'test_sample_access',
# # 'test_sample',
# 'test_annotation'):
# continue
if modname.startswith('test_'):
yield 'solvebio.test.' + modname


def all():
return unittest.defaultTestLoader.loadTestsFromNames(all_names())
names = [name for name in all_names()]
return unittest.defaultTestLoader.loadTestsFromNames(names)

# def unit():
# unit_names = [name for name in all_names() if 'integration' not in name]
Expand Down
1 change: 1 addition & 0 deletions solvebio/test/query_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import re
import unittest

import solvebio

TEST_DATASET_NAME = 'ClinVar/2.0.0-1/Variants'
Expand Down
3 changes: 2 additions & 1 deletion solvebio/test/test_annotation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import unittest
import os

from solvebio import Annotation, SolveError
from solvebio.errors import SolveError
from solvebio.resource import Annotation


class AnnotationTest(unittest.TestCase):
Expand Down
2 changes: 1 addition & 1 deletion solvebio/test/test_annotation_access.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import unittest
import os

from solvebio import Annotation
from solvebio.resource import Annotation


@unittest.skipUnless('TEST_SOLVEBIO_API_UPDATE' in os.environ,
Expand Down

0 comments on commit 57a3b3e

Please sign in to comment.