Skip to content

Commit bf7343a

Browse files
authored
Merge pull request #1 from Kamsiy/master
Add python api
2 parents f3a5340 + 560a8cd commit bf7343a

File tree

4 files changed

+484
-0
lines changed

4 files changed

+484
-0
lines changed

api/__init__.py

Whitespace-only changes.

api/boa_client.py

+378
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,378 @@
1+
import xmlrpc.client
2+
import traceback
3+
import util
4+
5+
BOA_PROXY = "http://boa.cs.iastate.edu/boa/?q=boa/api"
6+
7+
class NotLoggedInException(Exception):
8+
pass
9+
10+
class BoaException(Exception):
11+
pass
12+
13+
class BoaClient(object):
14+
""" A client class for accessing boa's api
15+
16+
Attributes:
17+
server (xmlrpc.client.ServerProxy):
18+
trans (xmlrpc.client.Transport)
19+
"""
20+
21+
def __init__(self):
22+
"""Create a new Boa API client, using the standard domain/path."""
23+
self.trans = util.CookiesTransport()
24+
self.__logged_in = False
25+
self.server = xmlrpc.client.ServerProxy(BOA_PROXY, transport=self.trans)
26+
27+
def login(self, username, password):
28+
"""log into the boa framework using the remote api
29+
30+
Args:
31+
username (str): username for boa account
32+
password (str): password for boa account
33+
"""
34+
try:
35+
self.__logged_in = True
36+
response = self.server.user.login(username, password)
37+
self.trans.add_csrf(response["token"])
38+
return response
39+
except xmlrpc.client.Fault as e:
40+
raise BoaException(e).with_traceback(e.__traceback__)
41+
42+
def close(self):
43+
"""Log out of the boa framework using the remote api
44+
45+
Raises:
46+
BoaException: if theres an issue reading from the server
47+
"""
48+
self.ensure_logged_in()
49+
try:
50+
self.server.user.logout()
51+
self.__logged_in = False
52+
except xmlrpc.client.Fault as e:
53+
raise BoaException(e).with_traceback(e.__traceback__)
54+
55+
def ensure_logged_in(self):
56+
"""Checks if a user is currently logged in through the remote api
57+
58+
Returns:
59+
bool: True if user is logged in, false if otherwise
60+
61+
Raises:
62+
NotLoggedInException: if user is not currently logged in
63+
"""
64+
if not self.__logged_in:
65+
raise NotLoggedInException("User not currently logged in")
66+
67+
def datasets(self):
68+
""" Retrieves datasetsets currently provided by boa
69+
70+
Returns:
71+
list: a list of boa datasets
72+
73+
Raises:
74+
BoaException: if theres an issue reading from the server
75+
"""
76+
self.ensure_logged_in()
77+
try:
78+
return self.server.boa.datasets()
79+
except xmlrpc.client.Fault as e:
80+
raise BoaException(e).with_traceback(e.__traceback__)
81+
82+
def dataset_names(self):
83+
"""Retrieves a list of names of all datasets provided by boa
84+
85+
Returns:
86+
list: the dataset names
87+
88+
Raises:
89+
BoaException: if theres an issue reading from the server
90+
"""
91+
self.ensure_logged_in()
92+
try:
93+
dataset_names = []
94+
datasets = self.datasets()
95+
for x in datasets:
96+
dataset_names.append(x['name'])
97+
return dataset_names
98+
except xmlrpc.client.Fault as e:
99+
raise BoaException(e).with_traceback(e.__traceback__)
100+
101+
def get_dataset(self, name):
102+
"""Retrieves a dataset given a name.
103+
104+
Args:
105+
name (str): The name of the input dataset to return.
106+
107+
Returns:
108+
dict: a dictionary with the keys id and name
109+
110+
Raises:
111+
BoaException: if theres an issue reading from the server
112+
"""
113+
self.ensure_logged_in()
114+
try:
115+
for x in self.datasets():
116+
if x['name'] == name:
117+
return x
118+
return None
119+
except xmlrpc.client.Fault as e:
120+
raise BoaException(e).with_traceback(e.__traceback__)
121+
122+
def last_job(self):
123+
"""Retrieves the most recently submitted job
124+
125+
Returns:
126+
JobHandle: the last submitted job
127+
128+
Raises:
129+
BoaException: if theres an issue reading from the server
130+
"""
131+
self.ensure_logged_in()
132+
try:
133+
jobs = self.job_list(False, 0, 1)
134+
return jobs[0]
135+
except xmlrpc.client.Fault as e:
136+
raise BoaException(e).with_traceback(e.__traceback__)
137+
138+
def job_count(self, pub_only=False):
139+
"""Retrieves the number of jobs submitted by a user
140+
141+
Args:
142+
pub_only (bool, optional): if true, return only public jobs
143+
otherwise return all jobs
144+
145+
Returns:
146+
int: the number of jobs submitted by a user
147+
148+
Raises:
149+
BoaException: if theres an issue reading from the server
150+
"""
151+
self.ensure_logged_in()
152+
try:
153+
return self.server.boa.count(pub_only)
154+
except xmlrpc.client.Fault as e:
155+
raise BoaException(e).with_traceback(e.__traceback__)
156+
157+
def query(self, query, dataset=None):
158+
"""Submits a new query to Boa to query the specified and returns a handle to the new job.
159+
160+
Args:
161+
query (str): a boa query represented as a string.
162+
dataset (str, optional): the name of the input dataset.
163+
164+
Returns:
165+
(JobHandle) a job
166+
167+
Raises:
168+
BoaException: if theres an issue reading from the server
169+
"""
170+
self.ensure_logged_in()
171+
try:
172+
id = 0 if dataset is None else dataset.get_id()
173+
job = self.server.boa.submit(query, self.datasets()[id]['id'])
174+
return util.parse_job(self, job)
175+
except xmlrpc.client.Fault as e:
176+
raise BoaException(e).with_traceback(e.__traceback__)
177+
178+
def get_job(self, id):
179+
"""Retrieves a job given an id.
180+
181+
Args:
182+
id (int): the id of the job you want to retrieve
183+
184+
Returns:
185+
JobHandle: the desired job.
186+
187+
Raises:
188+
BoaException: if theres an issue reading from the server
189+
"""
190+
self.ensure_logged_in()
191+
try:
192+
return util.parse_job(self, self.server.boa.job(id))
193+
except xmlrpc.client.Fault as e:
194+
raise BoaException(e).with_traceback(e.__traceback__)
195+
196+
def job_list(self, pub_only=False, offset=0, length=1000):
197+
"""Returns a list of the most recent jobs, based on an offset and length.
198+
199+
This includes public and private jobs. Returned jobs are ordered from newest to oldest
200+
201+
Args:
202+
pub_only (bool, optional): if true, only return public jobs otherwise return all jobs
203+
offset (int, optional): the starting offset
204+
length (int, optional): the number of jobs (at most) to return
205+
206+
Returns:
207+
list: a list of jobs where each element is a jobHandle
208+
209+
Raises:
210+
BoaException: if theres an issue reading from the server
211+
"""
212+
self.ensure_logged_in()
213+
try:
214+
list = self.server.boa.jobs(pub_only, offset, length)
215+
newDict = []
216+
if(len(list) > 0):
217+
for i in list:
218+
newDict.append(util.parse_job(self, i))
219+
return newDict
220+
except xmlrpc.client.Fault as e:
221+
raise BoaException(e).with_traceback(e.__traceback__)
222+
223+
def stop(self, job):
224+
"""Stops the execution of a job
225+
226+
Args:
227+
job (JobHandle): the job whose execution you want to stop
228+
229+
Raises:
230+
BoaException: if theres an issue reading from the server
231+
"""
232+
self.ensure_logged_in()
233+
try:
234+
self.server.job.stop(job.id)
235+
except xmlrpc.client.Fault as e:
236+
raise BoaException(e).with_traceback(e.__traceback__)
237+
238+
def resubmit(self, job):
239+
"""Resubmits a job to the framework
240+
241+
Args:
242+
job (JobHandle): The job you want to resubmit
243+
244+
Raises:
245+
BoaException: if theres an issue reading from the server
246+
"""
247+
self.ensure_logged_in()
248+
try:
249+
self.server.job.resubmit(job.id)
250+
except xmlrpc.client.Fault as e:
251+
raise BoaException(e).with_traceback(e.__traceback__)
252+
253+
def delete(self, job):
254+
"""Deletes this job from the framework.
255+
256+
Args:
257+
job (JobHandle): the job you want to delete
258+
259+
Raises:
260+
BoaException: if theres an issue reading from the server
261+
"""
262+
self.ensure_logged_in()
263+
try:
264+
self.server.job.delete(job.id)
265+
except xmlrpc.client.Fault as e:
266+
raise BoaException(e).with_traceback(e.__traceback__)
267+
268+
def set_public(self, job, is_public):
269+
"""Modifies the public/private status of this job.
270+
271+
Args:
272+
is_public (bool): 'True' to make it public, False to make it private
273+
job (JobHandle)
274+
275+
Raises:
276+
BoaException: if theres an issue reading from the server
277+
"""
278+
self.ensure_logged_in()
279+
try:
280+
if is_public is True:
281+
self.server.job.setpublic(job.id, 1)
282+
else:
283+
self.server.job.setpublic(job.id, 0)
284+
except xmlrpc.client.Fault as e:
285+
raise BoaException(e).with_traceback(e.__traceback__)
286+
287+
def public_status(self, job):
288+
"""Get the jobs public/private status.
289+
290+
Args:
291+
job (JobHandle)
292+
293+
Raises:
294+
BoaException: if theres an issue reading from the server
295+
"""
296+
self.ensure_logged_in()
297+
try:
298+
result = self.server.job.public(job.id)
299+
if result is 1:
300+
return True
301+
else:
302+
return False
303+
except xmlrpc.client.Fault as e:
304+
raise BoaException(e).with_traceback(e.__traceback__)
305+
306+
def get_url(self, job):
307+
"""Retrieves the jobs URL.
308+
309+
Args:
310+
job (JobHandle)
311+
312+
Raises:
313+
BoaException: if theres an issue reading from the server
314+
"""
315+
self.ensure_logged_in()
316+
try:
317+
return self.server.job.url(job.id)
318+
except xmlrpc.client.Fault as e:
319+
raise BoaException(e).with_traceback(e.__traceback__)
320+
321+
def public_url(self, job):
322+
"""Get the jobs public page URL.
323+
324+
Args:
325+
job (JobHandle)
326+
327+
Raises:
328+
BoaException: if theres an issue reading from the server
329+
"""
330+
self.ensure_logged_in()
331+
try:
332+
return self.server.job.publicurl(job.id)
333+
except xmlrpc.client.Fault as e:
334+
raise BoaException(e).with_traceback(e.__traceback__)
335+
336+
def get_compiler_errors(self, job):
337+
"""Return any errors from trying to compile the job.
338+
339+
Args:
340+
job (JobHandle)
341+
342+
Raises:
343+
BoaException: if theres an issue reading from the server
344+
"""
345+
self.ensure_logged_in()
346+
try:
347+
return self.server.job.compilerErrors(job.id)
348+
except xmlrpc.client.Fault as e:
349+
raise BoaException(e).with_traceback(e.__traceback__)
350+
351+
def source(self, job):
352+
"""Return the source query for this job.
353+
354+
Args:
355+
job (JobHandle)
356+
357+
Raises:
358+
BoaException: if theres an issue reading from the server
359+
"""
360+
self.ensure_logged_in()
361+
try:
362+
return self.server.job.source(job.id)
363+
except xmlrpc.client.Fault as e:
364+
raise BoaException(e).with_traceback(e.__traceback__)
365+
366+
def output(self, job):
367+
"""Return the output for this job, if it finished successfully and has an output.
368+
369+
Raises:
370+
BoaException: if theres an issue reading from the server
371+
"""
372+
self.ensure_logged_in()
373+
try:
374+
if job.exec_status != "Finished":
375+
return "Job is currently running"
376+
return self.server.job.output(job.id)
377+
except xmlrpc.client.Fault as e:
378+
raise BoaException(e).with_traceback(e.__traceback__)

0 commit comments

Comments
 (0)