Skip to content

adding User.jobs() #2035

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions qiita_db/processing_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,25 @@ def outputs(self):
name: qdb.artifact.Artifact(aid)
for aid, name in qdb.sql_connection.TRN.execute_fetchindex()}

@property
def processing_job_worflow(self):
"""The processing job worflow

Returns
-------
ProcessingWorkflow
The processing job workflow the job
"""
with qdb.sql_connection.TRN:
sql = """SELECT processing_job_workflow_id
FROM qiita.processing_job_workflow_root
WHERE processing_job_id = %s"""
qdb.sql_connection.TRN.add(sql, [self.id])
r = qdb.sql_connection.TRN.execute_fetchindex()

return (qdb.processing_job.ProcessingWorkflow(r[0][0]) if r
else None)


class ProcessingWorkflow(qdb.base.QiitaObject):
"""Models a workflow defined by the user
Expand Down
12 changes: 12 additions & 0 deletions qiita_db/test/test_processing_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,18 @@ def test_outputs(self):
[afp for _, afp, _ in
qdb.artifact.Artifact(exp_artifact_count).filepaths])

def test_processing_job_worflow(self):
# testing None
job = qdb.processing_job.ProcessingJob(
"063e553b-327c-4818-ab4a-adfe58e49860")
self.assertIsNone(job.processing_job_worflow)

# testing actual workflow
job = qdb.processing_job.ProcessingJob(
"b72369f9-a886-4193-8d3d-f7b504168e75")
self.assertEqual(job.processing_job_worflow,
qdb.processing_job.ProcessingWorkflow(1))


@qiita_test_checker()
class ProcessingWorkflowTests(TestCase):
Expand Down
11 changes: 11 additions & 0 deletions qiita_db/test/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,5 +450,16 @@ def test_user_artifacts(self):
qdb.artifact.Artifact(7)]}
self.assertEqual(obs, exp)

def test_jobs(self):
PJ = qdb.processing_job.ProcessingJob
# generates expected jobs
jobs = qdb.user.User('shared@foo.bar').jobs()
self.assertEqual(jobs, [
PJ('d19f76ee-274e-4c1b-b3a2-a12d73507c55'),
PJ('b72369f9-a886-4193-8d3d-f7b504168e75')])

# no jobs
self.assertEqual(qdb.user.User('admin@foo.bar').jobs(), [])

if __name__ == "__main__":
main()
22 changes: 22 additions & 0 deletions qiita_db/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class User(qdb.base.QiitaObject):
private_analyses
shared_analyses
unread_messages
jobs

Methods
-------
Expand Down Expand Up @@ -660,6 +661,27 @@ def delete_messages(self, messages):
qdb.sql_connection.TRN.add(sql)
qdb.sql_connection.TRN.execute()

def jobs(self):
"""Return jobs created by the user

Parameters
----------

Returns
-------
list of ProcessingJob

"""
with qdb.sql_connection.TRN:
sql_info = [self._id]
sql = """SELECT processing_job_id
FROM qiita.processing_job
WHERE email = %s
ORDER BY heartbeat DESC"""
qdb.sql_connection.TRN.add(sql, sql_info)
return [qdb.processing_job.ProcessingJob(p[0])
for p in qdb.sql_connection.TRN.execute_fetchindex()]


def validate_email(email):
"""Validates an email
Expand Down
3 changes: 2 additions & 1 deletion qiita_pet/handlers/api_proxy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
list_options_handler_get_req, workflow_handler_post_req,
workflow_handler_patch_req, workflow_run_post_req,
job_ajax_get_req)
from .user import (user_jobs_get_req)

__version__ = "0.2.0-dev"

Expand All @@ -64,4 +65,4 @@
'workflow_handler_patch_req', 'workflow_run_post_req',
'job_ajax_get_req', 'artifact_patch_request',
'sample_template_patch_request',
'get_sample_template_processing_status']
'get_sample_template_processing_status', 'user_jobs_get_req']
71 changes: 71 additions & 0 deletions qiita_pet/handlers/api_proxy/tests/test_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -----------------------------------------------------------------------------
# Copyright (c) 2014--, The Qiita Development Team.
#
# Distributed under the terms of the BSD 3-clause License.
#
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------
from unittest import TestCase, main
from os.path import exists, isdir
from os import remove
from shutil import rmtree

from qiita_core.util import qiita_test_checker
import qiita_db as qdb
from qiita_pet.handlers.api_proxy.user import (user_jobs_get_req)


@qiita_test_checker()
class TestSUserAPI(TestCase):
def setUp(self):
self._clean_up_files = []

def tearDown(self):
for fp in self._clean_up_files:
if exists(fp):
if isdir(fp):
rmtree(fp)
else:
remove(fp)

def test_user_jobs_get_req(self):
obs = user_jobs_get_req(qdb.user.User('shared@foo.bar'))
exp = {
'status': 'success',
'message': '',
'jobs': [
{'id': 'd19f76ee-274e-4c1b-b3a2-a12d73507c55',
'status': 'error',
'heartbeat': '2015-11-22 21:30:00',
'params': {
'reference': 1,
'similarity': 0.97,
'sortmerna_e_value': 1,
'sortmerna_max_pos': 10000,
'input_data': 2,
'threads': 1,
'sortmerna_coverage': 0.97},
'name': 'Pick closed-reference OTUs',
'processing_job_workflow_id': ''},
{'id': 'b72369f9-a886-4193-8d3d-f7b504168e75',
'status': 'success',
'heartbeat': '2015-11-22 21:15:00',
'params': {
'max_barcode_errors': 1.5,
'sequence_max_n': 0,
'max_bad_run_length': 3,
'phred_offset': u'auto',
'rev_comp': False,
'phred_quality_threshold': 3,
'input_data': 1,
'rev_comp_barcode': False,
'rev_comp_mapping_barcodes': True,
'min_per_read_length_fraction': 0.75,
'barcode_type': u'golay_12'},
'name': 'Split libraries FASTQ',
'processing_job_workflow_id': 1}]}
self.assertEqual(obs, exp)


if __name__ == '__main__':
main()
49 changes: 49 additions & 0 deletions qiita_pet/handlers/api_proxy/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# -----------------------------------------------------------------------------
# Copyright (c) 2014--, The Qiita Development Team.
#
# Distributed under the terms of the BSD 3-clause License.
#
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------
from __future__ import division

from qiita_core.util import execute_as_transaction


@execute_as_transaction
def user_jobs_get_req(user):
"""Gets the json of jobs

Parameters
----------
prep_id : int
PrepTemplate id to get info for
user_id : str
User requesting the sample template info

Returns
-------
dict of objects
{'status': status,
'message': message,
'template': {sample: {column: value, ...}, ...}
"""

response = []
for j in user.jobs():
name = j.command.name
hb = j.heartbeat
hb = "" if hb is None else hb.strftime("%Y-%m-%d %H:%M:%S")
pjw = j.processing_job_worflow
wid = '' if pjw is None else pjw.id
response.append({
'id': j.id,
'name': name,
'params': j.parameters.values,
'status': j.status,
'heartbeat': hb,
'processing_job_workflow_id': wid})

return {'status': 'success',
'message': '',
'jobs': response}
8 changes: 8 additions & 0 deletions qiita_pet/handlers/user_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from wtforms import Form, StringField, validators

from qiita_pet.handlers.base_handlers import BaseHandler
from qiita_pet.handlers.api_proxy import user_jobs_get_req
from qiita_db.user import User
from qiita_db.logger import LogEntry
from qiita_db.exceptions import QiitaDBUnknownIDError, QiitaDBError
Expand Down Expand Up @@ -185,3 +186,10 @@ def post(self):

self.render("user_messages.html",
messages=self.current_user.messages())


class UserJobs(BaseHandler):
@authenticated
def get(self):
response = user_jobs_get_req(self.current_user)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this executes as a transaction and has the potential to block as it is performing IO. Should this method be a tornado coroutine instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, changing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this needs take the result of a yield?

http://www.tornadoweb.org/en/stable/gen.html

self.write(response)
6 changes: 6 additions & 0 deletions qiita_pet/test/test_user_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,11 @@ def test_post_profile(self):
response = self.post('/profile/', post_args)
self.assertEqual(response.code, 200)


class TestUserJobsHandler(TestHandlerBase):
def test_get(self):
response = self.get('/user/jobs/')
self.assertEqual(response.code, 200)

if __name__ == "__main__":
main()
3 changes: 2 additions & 1 deletion qiita_pet/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
AuthCreateHandler, AuthLoginHandler, AuthLogoutHandler, AuthVerifyHandler)
from qiita_pet.handlers.user_handlers import (
ChangeForgotPasswordHandler, ForgotPasswordHandler, UserProfileHandler,
UserMessagesHander)
UserMessagesHander, UserJobs)
from qiita_pet.handlers.analysis_handlers import (
SelectCommandsHandler, AnalysisWaitHandler, AnalysisResultsHandler,
ShowAnalysesHandler, ResultsHandler, SelectedSamplesHandler,
Expand Down Expand Up @@ -88,6 +88,7 @@ def __init__(self):
(r"/auth/reset/(.*)", ChangeForgotPasswordHandler),
(r"/profile/", UserProfileHandler),
(r"/user/messages/", UserMessagesHander),
(r"/user/jobs/", UserJobs),
(r"/results/(.*)", ResultsHandler,
{"path": RES_PATH}),
(r"/static/(.*)", tornado.web.StaticFileHandler,
Expand Down