Skip to content

Commit

Permalink
Merge pull request #1860 from biocore/simplify-restAPI
Browse files Browse the repository at this point in the history
WIP: Simplify rest api
  • Loading branch information
antgonza committed Jul 9, 2016
2 parents 1698e23 + 3381da6 commit 5977e9e
Show file tree
Hide file tree
Showing 64 changed files with 795 additions and 5,283 deletions.
3 changes: 0 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ install:
- source activate env_name
- pip install sphinx sphinx-bootstrap-theme coveralls 'ipython[all]==2.4.1'
- travis_retry pip install .
- pushd qiita_plugins/target_gene
- travis_retry pip install .
- popd
script:
- export MOI_CONFIG_FP=`pwd`/qiita_core/support_files/config_test.cfg
- if [ ${TRAVIS_PULL_REQUEST} == "false" ]; then
Expand Down
17 changes: 13 additions & 4 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,20 @@ Install Qiita (this occurs through setuptools' `setup.py` file in the qiita dire
pip install -e .
```

You will also need to install several plugins for Qiita to be fully functional. As they are already included in the repository, to install, simply execute:
At this point, Qiita will be installed and the system will start. However,
you will need to install plugins in order to process any kind of data. For a list
of available plugins, visit the [Qiita Spots](https://github.com/qiita-spots)
github organization. Currently, the `Type Plugins`
[qtp-biom](https://github.com/qiita-spots/qtp-biom) and
[qtp-target-gene](https://github.com/qiita-spots/qtp-target-gene) as well as
the `Plugin` [qp-target-gene](https://github.com/qiita-spots/qp-target-gene) are
required. To install these plugins, simply execute

```bash
pushd qiita_plugins/target_gene
pip install -e .
popd
pip install https://github.com/qiita-spots/qiita_client
pip install https://github.com/qiita-spots/qtp-biom
pip install https://github.com/qiita-spots/qtp-target-gene
pip install https://github.com/qiita-spots/qp-target-gene
```

## Configure Qiita
Expand Down
6 changes: 5 additions & 1 deletion qiita_core/tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
from unittest import TestCase, main

from qiita_core.util import (
send_email, qiita_test_checker, execute_as_transaction, get_qiita_version)
send_email, qiita_test_checker, execute_as_transaction, get_qiita_version,
is_test_environment)
import qiita_db as qdb


Expand All @@ -28,6 +29,9 @@ def test_send_email_fail(self):
send_email("antgonza@gmail.com", "This is a test",
"This is the body of the test")

def test_is_test_environment(self):
self.assertTrue(is_test_environment())

def test_qiita_test_checker(self):
"""testing qiita test checker"""
@qiita_test_checker()
Expand Down
29 changes: 23 additions & 6 deletions qiita_core/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,28 @@ def send_email(to, subject, body):
smtp.close()


def is_test_environment():
"""Checks if Qiita is running in a test environment
Returns
-------
bool
Whether Qiita is running in a test environment or not
Notes
-----
Qiita is running in a test environment if:
- It is connected to a test database, AND
- The config file indicates that this is a test environment
"""
# Check that we are not in a production environment
conn_handler = qdb.sql_connection.SQLConnectionHandler()
# It is possible that we are connecting to a production database
test_db = conn_handler.execute_fetchone("SELECT test FROM settings")[0]
# Or the loaded configuration file belongs to a production environment
return qiita_config.test_environment and test_db


def qiita_test_checker(test=False):
"""Decorator that allows the execution of all methods in a test class only
and only if Qiita is set up to work in a test environment.
Expand All @@ -70,12 +92,7 @@ def qiita_test_checker(test=False):
If Qiita is set up to work in a production environment
"""
def class_modifier(cls):
# First, we check that we are not in a production environment
conn_handler = qdb.sql_connection.SQLConnectionHandler()
# It is possible that we are connecting to a production database
test_db = conn_handler.execute_fetchone("SELECT test FROM settings")[0]
# Or the loaded configuration file belongs to a production environment
if not qiita_config.test_environment or not test_db or test:
if not is_test_environment() or test:
raise RuntimeError("Working in a production environment. Not "
"executing the tests to keep the production "
"database safe.")
Expand Down
132 changes: 77 additions & 55 deletions qiita_db/handlers/artifact.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
# -----------------------------------------------------------------------------

from tornado.web import HTTPError
from collections import defaultdict
from json import loads

import qiita_db as qdb
from .oauth2 import OauthBaseHandler, authenticate_oauth
Expand Down Expand Up @@ -43,39 +45,78 @@ def _get_artifact(a_id):
return artifact


class ArtifactFilepathsHandler(OauthBaseHandler):
class ArtifactHandler(OauthBaseHandler):
@authenticate_oauth
def get(self, artifact_id):
"""Retrieves the filepath information of the given artifact
"""Retrieves the artifact information
Parameters
----------
artifact_id : str
The id of the artifact whose filepath information is being
retrieved
The id of the artifact whose information is being retrieved
Returns
-------
dict
{'filepaths': list of (str, str)}
The filepaths attached to the artifact and their filepath types
The artifact information:
'name': artifact name
'timestamp': artifact creation timestamp
'visibility': artifact visibility
'type': artifact type
'data_type': artifact data type
'can_be_submitted_to_ebi': if the artifact can be submitted to ebi
'ebi_run_accessions': dict with the EBI run accessions attached to
the artifact
'can_be_submitted_to_vamps': if the artifact can be submitted to
vamps
'is_submitted_to_vamps': whether the artifact has been submitted
to vamps or not
'prep_information': list of prep information ids
'study': the study id
'processing_parameters': dict with the processing parameters used
to generate the artifact or None
'files': dict with the artifact files, keyed by filepath type
"""
with qdb.sql_connection.TRN:
artifact = _get_artifact(artifact_id)
response = {
'filepaths': [(fp, fp_type)
for _, fp, fp_type in artifact.filepaths]}
'name': artifact.name,
'timestamp': str(artifact.timestamp),
'visibility': artifact.visibility,
'type': artifact.artifact_type,
'data_type': artifact.data_type,
'can_be_submitted_to_ebi': artifact.can_be_submitted_to_ebi,
'can_be_submitted_to_vamps':
artifact.can_be_submitted_to_vamps,
'prep_information': [p.id for p in artifact.prep_templates],
'study': artifact.study.id}
params = artifact.processing_parameters
response['processing_parameters'] = (
params.values if params is not None else None)

response['ebi_run_accessions'] = (
artifact.ebi_run_accessions
if response['can_be_submitted_to_ebi'] else None)
response['is_submitted_to_vamps'] = (
artifact.is_submitted_to_vamps
if response['can_be_submitted_to_vamps'] else None)

# Instead of sending a list of files, provide the files as a
# dictionary keyed by filepath type
response['files'] = defaultdict(list)
for _, fp, fp_type in artifact.filepaths:
response['files'][fp_type].append(fp)

self.write(response)

@authenticate_oauth
def patch(self, artifact_id):
"""Patches the filepaths of the artifact
"""Patches the artifact information
Parameter
---------
artifact_id : str
The id of the artifact whose filepaths information is being updated
The id of the artifact whose information is being updated
"""
req_op = self.get_argument('op')
req_path = self.get_argument('path')
Expand All @@ -98,60 +139,41 @@ def patch(self, artifact_id):
self.finish()


class ArtifactMappingHandler(OauthBaseHandler):
class ArtifactAPItestHandler(OauthBaseHandler):
@authenticate_oauth
def get(self, artifact_id):
"""Retrieves the mapping file information of the given artifact
def post(self):
"""Creates a new artifact
Parameters
----------
artifact_id : str
The id of the artifact whose mapping file information is being
retrieved
filepaths : str
Json string with a list of filepaths and its types
type : str
The artifact type
prep_template: int
The id of the template that the new artifact belongs to
name : str, optional
The artifact name
Returns
-------
dict
{'mapping': str}
The filepath to the mapping file
"""
with qdb.sql_connection.TRN:
artifact = _get_artifact(artifact_id)
# In the current system, we don't have any artifact that
# is the result of two other artifacts, and there is no way
# of generating such artifact. This operation will be
# eventually supported, but in interest of time we are not
# going to implement that here.
prep_templates = artifact.prep_templates
if len(prep_templates) > 1:
raise NotImplementedError(
"Artifact %d has more than one prep template")
'artifact': the id of the new artifact
fp = prep_templates[0].qiime_map_fp

response = {'mapping': fp}

self.write(response)


class ArtifactTypeHandler(OauthBaseHandler):
@authenticate_oauth
def get(self, artifact_id):
"""Retrieves the artifact type information of the given artifact
See Also
--------
qiita_db.artifact.Artifact.create
"""
filepaths = loads(self.get_argument('filepaths'))
artifact_type = self.get_argument('type')
prep_template = self.get_argument('prep')
name = self.get_argument('name', None)

Parameters
----------
artifact_id : str
The id of the artifact whose information is being retrieved
if prep_template:
prep_template = qdb.metadata_template.prep_template.PrepTemplate(
prep_template)

Returns
-------
dict
{'type': str}
The artifact type
"""
with qdb.sql_connection.TRN:
artifact = _get_artifact(artifact_id)
response = {'type': artifact.artifact_type}
a = qdb.artifact.Artifact.create(
filepaths, artifact_type, name=name, prep_template=prep_template)

self.write(response)
self.write({'artifact': a.id})
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@
# The full license is in the file LICENSE, distributed with this software.
# -----------------------------------------------------------------------------

from .split_libraries import split_libraries
from .split_libraries_fastq import split_libraries_fastq
from .oauth2 import OauthBaseHandler, authenticate_oauth
import qiita_db as qdb

__all__ = ['split_libraries', 'split_libraries_fastq']

class ResetAPItestHandler(OauthBaseHandler):
@authenticate_oauth
def post(self):
qdb.environment_manager.drop_and_rebuild_tst_database()
6 changes: 5 additions & 1 deletion qiita_db/handlers/oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ def write_error(self, status_code, **kwargs):
'ERROR:\n%s\nTRACE:\n%s\nHTTP INFO:\n%s\n' %
(error, trace_info, request_info))

self.finish(exc_info[1].log_message)
message = exc_info[1].message
if hasattr(exc_info[1], 'log_message'):
message = exc_info[1].log_message

self.finish(message)

def head(self):
"""Adds proper response for head requests"""
Expand Down
Loading

0 comments on commit 5977e9e

Please sign in to comment.