Skip to content

Commit 7060545

Browse files
author
Yo Yehudi
authored
Merge pull request #66 from mbasil09/patch-1
Patch 1: Adds a dataframe feature for a query
2 parents b331f27 + 2e62758 commit 7060545

20 files changed

Lines changed: 7650 additions & 7263 deletions

intermine/constraints.py

Lines changed: 1220 additions & 1160 deletions
Large diffs are not rendered by default.

intermine/decorators.py

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
from functools import wraps
2-
from intermine.errors import ServiceError
3-
4-
def requires_version(required):
5-
6-
error_fmt = "Service must be at version %s, but is at %s"
7-
8-
def decorator(f):
9-
10-
@wraps(f)
11-
def wrapper(self, *args, **kwargs):
12-
if self.version < required:
13-
raise ServiceError(error_fmt % (required, self.version))
14-
return f(self, *args, **kwargs)
15-
16-
return wrapper
17-
18-
return decorator
19-
1+
from functools import wraps
2+
from intermine.errors import ServiceError
3+
4+
5+
def requires_version(required):
6+
7+
error_fmt = "Service must be at version %s, but is at %s"
8+
9+
def decorator(f):
10+
11+
@wraps(f)
12+
def wrapper(self, *args, **kwargs):
13+
if self.version < required:
14+
raise ServiceError(error_fmt % (required, self.version))
15+
return f(self, *args, **kwargs)
16+
17+
return wrapper
18+
19+
return decorator

intermine/errors.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
from intermine.util import ReadableException
2-
3-
class UnimplementedError(Exception):
4-
pass
5-
6-
class ServiceError(ReadableException):
7-
"""Errors in the creation and use of the Service object"""
8-
pass
9-
10-
class WebserviceError(IOError):
11-
"""Errors from interaction with the webservice"""
12-
pass
1+
from intermine.util import ReadableException
2+
3+
4+
class UnimplementedError(Exception):
5+
pass
6+
7+
8+
class ServiceError(ReadableException):
9+
"""Errors in the creation and use of the Service object"""
10+
pass
11+
12+
13+
class WebserviceError(IOError):
14+
"""Errors from interaction with the webservice"""
15+
pass

intermine/idresolution.py

Lines changed: 94 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,94 @@
1-
import weakref
2-
import time
3-
4-
# Use core json for 2.6+, simplejson for <=2.5
5-
try:
6-
import json
7-
except ImportError:
8-
import simplejson as json
9-
10-
def get_json(service, path, key):
11-
text = service.opener.read(service.root + path)
12-
data = json.loads(text)
13-
if data['error'] is not None:
14-
raise Exception(data['error'])
15-
if key not in data:
16-
raise Exception(key + " not returned from " + path)
17-
return data[key]
18-
19-
ONE_MINUTE = 60
20-
21-
COMPLETED = set(["SUCCESS", "ERROR"])
22-
23-
class Job(object):
24-
"""
25-
A Representation of an Identifier Resolution Job
26-
================================================
27-
28-
Users can submit requests to resolve sets of IDs to
29-
objects in the data-store. These jobs begin in a PENDING
30-
state, and transition through RUNNING to either SUCCESS
31-
or ERROR.
32-
33-
Upon completion, the results of the job may be fetched, and the
34-
job may be deleted on the server.
35-
"""
36-
37-
INITIAL_DECAY = 1.25
38-
INITIAL_BACKOFF = 0.05
39-
MAX_BACKOFF = ONE_MINUTE
40-
41-
def __init__(self, service, uid):
42-
self.service = weakref.proxy(service)
43-
self.uid = uid
44-
self.status = None
45-
self.backoff = Job.INITIAL_BACKOFF
46-
self.decay = Job.INITIAL_DECAY
47-
self.max_backoff = Job.MAX_BACKOFF
48-
if self.uid is None:
49-
raise Exception("No uid found")
50-
51-
def poll(self):
52-
"""
53-
Check to see if the job has been completed, updating the
54-
status of the job in the process.
55-
56-
@return: Boolean Whether or not the job is complete.
57-
"""
58-
if self.status not in COMPLETED:
59-
backoff = self.backoff
60-
self.backoff = min(self.max_backoff, backoff * self.decay)
61-
time.sleep(backoff)
62-
self.status = self.fetch_status()
63-
return self.status in COMPLETED
64-
65-
def fetch_status(self):
66-
"""
67-
Retrieve the results of this completed job from the server.
68-
69-
@rtype: dict
70-
"""
71-
return get_json(self.service, "/ids/{0}/status".format(self.uid), "status")
72-
73-
def delete(self):
74-
"""
75-
Delete the job from the server.
76-
77-
The job should not be used again once this method has been invoked.
78-
"""
79-
path = "/ids/" + self.uid
80-
response = self.service.opener.delete(self.service.root + path)
81-
response_data = json.loads(response)
82-
if response_data['error'] is not None:
83-
raise Exception(response_data['error'])
84-
85-
def fetch_results(self):
86-
"""
87-
Retrieve the current status of this job from the server.
88-
89-
@rtype String
90-
"""
91-
return get_json(self.service, "/ids/{0}/result".format(self.uid), "results")
1+
import weakref
2+
import time
3+
4+
# Use core json for 2.6+, simplejson for <=2.5
5+
try:
6+
import json
7+
except ImportError:
8+
import simplejson as json
9+
10+
11+
def get_json(service, path, key):
12+
text = service.opener.read(service.root + path)
13+
data = json.loads(text)
14+
if data['error'] is not None:
15+
raise Exception(data['error'])
16+
if key not in data:
17+
raise Exception(key + " not returned from " + path)
18+
return data[key]
19+
20+
21+
ONE_MINUTE = 60
22+
23+
COMPLETED = set(["SUCCESS", "ERROR"])
24+
25+
26+
class Job(object):
27+
"""
28+
A Representation of an Identifier Resolution Job
29+
================================================
30+
31+
Users can submit requests to resolve sets of IDs to
32+
objects in the data-store. These jobs begin in a PENDING
33+
state, and transition through RUNNING to either SUCCESS
34+
or ERROR.
35+
36+
Upon completion, the results of the job may be fetched, and the
37+
job may be deleted on the server.
38+
"""
39+
40+
INITIAL_DECAY = 1.25
41+
INITIAL_BACKOFF = 0.05
42+
MAX_BACKOFF = ONE_MINUTE
43+
44+
def __init__(self, service, uid):
45+
self.service = weakref.proxy(service)
46+
self.uid = uid
47+
self.status = None
48+
self.backoff = Job.INITIAL_BACKOFF
49+
self.decay = Job.INITIAL_DECAY
50+
self.max_backoff = Job.MAX_BACKOFF
51+
if self.uid is None:
52+
raise Exception("No uid found")
53+
54+
def poll(self):
55+
"""
56+
Check to see if the job has been completed, updating the
57+
status of the job in the process.
58+
59+
@return: Boolean Whether or not the job is complete.
60+
"""
61+
if self.status not in COMPLETED:
62+
backoff = self.backoff
63+
self.backoff = min(self.max_backoff, backoff * self.decay)
64+
time.sleep(backoff)
65+
self.status = self.fetch_status()
66+
return self.status in COMPLETED
67+
68+
def fetch_status(self):
69+
"""
70+
Retrieve the results of this completed job from the server.
71+
72+
@rtype: dict
73+
"""
74+
return get_json(self.service, "/ids/{0}/status".format(self.uid), "status")
75+
76+
def delete(self):
77+
"""
78+
Delete the job from the server.
79+
80+
The job should not be used again once this method has been invoked.
81+
"""
82+
path = "/ids/" + self.uid
83+
response = self.service.opener.delete(self.service.root + path)
84+
response_data = json.loads(response)
85+
if response_data['error'] is not None:
86+
raise Exception(response_data['error'])
87+
88+
def fetch_results(self):
89+
"""
90+
Retrieve the current status of this job from the server.
91+
92+
@rtype String
93+
"""
94+
return get_json(self.service, "/ids/{0}/result".format(self.uid), "results")

0 commit comments

Comments
 (0)