Пример #1
0
def sample_template_patch_request(user_id,
                                  req_op,
                                  req_path,
                                  req_value=None,
                                  req_from=None):
    """Modifies an attribute of the artifact

    Parameters
    ----------
    user_id : str
        The id of the user performing the patch operation
    req_op : str
        The operation to perform on the artifact
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Returns
    -------
    dict of {str, str}
        A dictionary with the following keys:
        - status: str, whether if the request is successful or not
        - message: str, if the request is unsuccessful, a human readable error
    """
    if req_op == 'remove':
        req_path = [v for v in req_path.split('/') if v]

        if len(req_path) != 3:
            return {'status': 'error', 'message': 'Incorrect path parameter'}

        st_id = req_path[0]
        attribute = req_path[1]
        attr_id = req_path[2]

        # Check if the user actually has access to the template
        st = SampleTemplate(st_id)
        access_error = check_access(st.study_id, user_id)
        if access_error:
            return access_error

        # Offload the deletion of the sample or column to the cluster
        job_id = safe_submit(user_id, delete_sample_or_column, SampleTemplate,
                             int(st_id), attribute, attr_id)
        # Store the job id attaching it to the sample template id
        r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % st_id,
                     dumps({'job_id': job_id}))

        return {'status': 'success', 'message': ''}

    else:
        return {
            'status':
            'error',
            'message':
            'Operation "%s" not supported. '
            'Current supported operations: remove' % req_op
        }
Пример #2
0
def artifact_delete_req(artifact_id, user_id):
    """Deletes the artifact

    Parameters
    ----------
    artifact_id : int
        Artifact being acted on
    user_id : str
        The user requesting the action

    Returns
    -------
    dict
        Status of action, in the form {'status': status, 'message': msg}
        status: status of the action, either success or error
        message: Human readable message for status
    """
    pd = Artifact(int(artifact_id))
    pt_id = pd.prep_templates[0].id
    access_error = check_access(pd.study.id, user_id)
    if access_error:
        return access_error

    job_id = safe_submit(user_id, delete_artifact, artifact_id)
    r_client.set(PREP_TEMPLATE_KEY_FORMAT % pt_id, dumps({'job_id': job_id}))

    return {'status': 'success', 'message': ''}
Пример #3
0
def artifact_post_req(user, artifact_id):
    """Deletes the artifact

    Parameters
    ----------
    user : qiita_db.user.User
        The user requesting the action
    artifact_id : int
        Id of the artifact being deleted
    """
    artifact_id = int(artifact_id)
    artifact = Artifact(artifact_id)
    check_artifact_access(user, artifact)

    analysis = artifact.analysis

    if analysis:
        # Do something when deleting in the analysis part to keep track of it
        redis_key = "analysis_%s" % analysis.id
    else:
        pt_id = artifact.prep_templates[0].id
        redis_key = PREP_TEMPLATE_KEY_FORMAT % pt_id

    job_id = safe_submit(user.id, delete_artifact, artifact_id)
    r_client.set(redis_key, dumps({'job_id': job_id, 'is_qiita_job': False}))
Пример #4
0
def artifact_delete_req(artifact_id, user_id):
    """Deletes the artifact

    Parameters
    ----------
    artifact_id : int
        Artifact being acted on
    user_id : str
        The user requesting the action

    Returns
    -------
    dict
        Status of action, in the form {'status': status, 'message': msg}
        status: status of the action, either success or error
        message: Human readable message for status
    """
    pd = Artifact(int(artifact_id))
    pt_id = pd.prep_templates[0].id
    access_error = check_access(pd.study.id, user_id)
    if access_error:
        return access_error

    job_id = safe_submit(user_id, delete_artifact, artifact_id)
    r_client.set(PREP_TEMPLATE_KEY_FORMAT % pt_id,
                 dumps({'job_id': job_id}))

    return {'status': 'success',
            'message': ''}
Пример #5
0
def sample_template_delete_req(study_id, user_id):
    """Deletes the sample template attached to the study

    Parameters
    ----------
    study_id : int
        The current study object id
    user_id : str
        The current user object id

    Returns
    -------
    dict
        results dictonary in the format
        {'status': status,
         'message': msg}

    status can be success, warning, or error depending on result
    message has the warnings or errors
    """
    exists = _check_sample_template_exists(int(study_id))
    if exists['status'] != 'success':
        return exists
    access_error = check_access(int(study_id), user_id)
    if access_error:
        return access_error

    # Offload the deletion of the sample template to the cluster
    job_id = safe_submit(user_id, delete_sample_template, int(study_id))
    # Store the job id attaching it to the sample template id
    r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % study_id,
                 dumps({'job_id': job_id}))

    return {'status': 'success', 'message': ''}
Пример #6
0
def sample_template_delete_req(study_id, user_id):
    """Deletes the sample template attached to the study

    Parameters
    ----------
    study_id : int
        The current study object id
    user_id : str
        The current user object id

    Returns
    -------
    dict
        results dictonary in the format
        {'status': status,
         'message': msg}

    status can be success, warning, or error depending on result
    message has the warnings or errors
    """
    exists = _check_sample_template_exists(int(study_id))
    if exists['status'] != 'success':
        return exists
    access_error = check_access(int(study_id), user_id)
    if access_error:
        return access_error

    # Offload the deletion of the sample template to the cluster
    job_id = safe_submit(user_id, delete_sample_template, int(study_id))
    # Store the job id attaching it to the sample template id
    r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % study_id,
                 dumps({'job_id': job_id}))

    return {'status': 'success', 'message': ''}
Пример #7
0
def sample_template_post_req(study_id, user_id, data_type,
                             sample_template):
    """Creates the sample template from the given file

    Parameters
    ----------
    study_id : int
        The current study object id
    user_id : str
        The current user object id
    data_type : str
        Data type for the sample template
    sample_template : str
        filename to use for creation

    Returns
    -------
    dict
        results dictonary in the format
        {'status': status,
         'message': msg,
         'file': sample_template}

    status can be success, warning, or error depending on result
    message has the warnings or errors
    file has the file name
    """
    access_error = check_access(int(study_id), user_id)
    if access_error:
        return access_error
    fp_rsp = check_fp(study_id, sample_template)
    if fp_rsp['status'] != 'success':
        # Unknown filepath, so return the error message
        return fp_rsp
    fp_rsp = fp_rsp['file']

    # Define here the message and message level in case of success
    msg = ''
    status = 'success'
    is_mapping_file = looks_like_qiime_mapping_file(fp_rsp)
    if is_mapping_file and not data_type:
        return {'status': 'error',
                'message': 'Please, choose a data type if uploading a '
                           'QIIME mapping file',
                'file': sample_template}

    study = Study(int(study_id))

    # Offload the creation of the sample template to the cluster
    job_id = safe_submit(user_id, create_sample_template, fp_rsp, study,
                         is_mapping_file, data_type)
    # Store the job id attaching it to the sample template id
    r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % study.id,
                 dumps({'job_id': job_id}))

    return {'status': status,
            'message': msg,
            'file': sample_template}
Пример #8
0
def sample_template_post_req(study_id, user_id, data_type, sample_template):
    """Creates the sample template from the given file

    Parameters
    ----------
    study_id : int
        The current study object id
    user_id : str
        The current user object id
    data_type : str
        Data type for the sample template
    sample_template : str
        filename to use for creation

    Returns
    -------
    dict
        results dictonary in the format
        {'status': status,
         'message': msg,
         'file': sample_template}

    status can be success, warning, or error depending on result
    message has the warnings or errors
    file has the file name
    """
    access_error = check_access(int(study_id), user_id)
    if access_error:
        return access_error
    fp_rsp = check_fp(study_id, sample_template)
    if fp_rsp['status'] != 'success':
        # Unknown filepath, so return the error message
        return fp_rsp
    fp_rsp = fp_rsp['file']

    # Define here the message and message level in case of success
    msg = ''
    status = 'success'
    is_mapping_file = looks_like_qiime_mapping_file(fp_rsp)
    if is_mapping_file and not data_type:
        return {
            'status': 'error',
            'message': 'Please, choose a data type if uploading a '
            'QIIME mapping file',
            'file': sample_template
        }

    study = Study(int(study_id))

    # Offload the creation of the sample template to the cluster
    job_id = safe_submit(user_id, create_sample_template, fp_rsp, study,
                         is_mapping_file, data_type)
    # Store the job id attaching it to the sample template id
    r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % study.id,
                 dumps({'job_id': job_id}))

    return {'status': status, 'message': msg, 'file': sample_template}
Пример #9
0
    def post(self, job_id):
        """Updates the job to one of the completed statuses: 'success', 'error'

        Parameters
        ----------
        job_id : str
            The job to complete
        """
        with qdb.sql_connection.TRN:
            job = _get_job(job_id)

            if job.status != 'running':
                raise HTTPError(403,
                                "Can't complete job: not in a running state")

            payload = loads(self.request.body)
            safe_submit(job.user.email, _job_completer, job_id, payload)

        self.finish()
Пример #10
0
    def post(self, job_id):
        """Updates the job to one of the completed statuses: 'success', 'error'

        Parameters
        ----------
        job_id : str
            The job to complete
        """
        with qdb.sql_connection.TRN:
            job = _get_job(job_id)

            if job.status != 'running':
                raise HTTPError(
                    403, "Can't complete job: not in a running state")

            payload = loads(self.request.body)
            safe_submit(job.user.email, _job_completer, job_id, payload)

        self.finish()
Пример #11
0
def sample_template_patch_request(user_id, req_op, req_path, req_value=None,
                                  req_from=None):
    """Modifies an attribute of the artifact

    Parameters
    ----------
    user_id : str
        The id of the user performing the patch operation
    req_op : str
        The operation to perform on the artifact
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Returns
    -------
    dict of {str, str}
        A dictionary with the following keys:
        - status: str, whether if the request is successful or not
        - message: str, if the request is unsuccessful, a human readable error
    """
    if req_op == 'remove':
        req_path = [v for v in req_path.split('/') if v]

        if len(req_path) != 3:
            return {'status': 'error',
                    'message': 'Incorrect path parameter'}

        st_id = req_path[0]
        attribute = req_path[1]
        attr_id = req_path[2]

        # Check if the user actually has access to the template
        st = SampleTemplate(st_id)
        access_error = check_access(st.study_id, user_id)
        if access_error:
            return access_error

        # Offload the deletion of the sample or column to the cluster
        job_id = safe_submit(user_id, delete_sample_or_column, SampleTemplate,
                             int(st_id), attribute, attr_id)
        # Store the job id attaching it to the sample template id
        r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % st_id,
                     dumps({'job_id': job_id}))

        return {'status': 'success', 'message': ''}

    else:
        return {'status': 'error',
                'message': 'Operation "%s" not supported. '
                           'Current supported operations: remove' % req_op}
Пример #12
0
def sample_template_put_req(study_id, user_id, sample_template):
    """Updates a sample template using the given file

    Parameters
    ----------
    study_id : int
        The current study object id
    user_id : str
        The current user object id
    sample_template : str
        filename to use for updating

    Returns
    -------
    dict
        results dictonary in the format
        {'status': status,
         'message': msg,
         'file': sample_template}

    status can be success, warning, or error depending on result
    message has the warnings or errors
    file has the file name
    """
    exists = _check_sample_template_exists(int(study_id))
    if exists['status'] != 'success':
        return exists
    access_error = check_access(int(study_id), user_id)
    if access_error:
        return access_error

    fp_rsp = check_fp(study_id, sample_template)
    if fp_rsp['status'] != 'success':
        # Unknown filepath, so return the error message
        return fp_rsp
    fp_rsp = fp_rsp['file']

    msg = ''
    status = 'success'

    # Offload the update of the sample template to the cluster
    job_id = safe_submit(user_id, update_sample_template, int(study_id),
                         fp_rsp)
    # Store the job id attaching it to the sample template id
    r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % study_id,
                 dumps({'job_id': job_id}))

    return {'status': status,
            'message': msg,
            'file': sample_template}
Пример #13
0
def sample_template_put_req(study_id, user_id, sample_template):
    """Updates a sample template using the given file

    Parameters
    ----------
    study_id : int
        The current study object id
    user_id : str
        The current user object id
    sample_template : str
        filename to use for updating

    Returns
    -------
    dict
        results dictonary in the format
        {'status': status,
         'message': msg,
         'file': sample_template}

    status can be success, warning, or error depending on result
    message has the warnings or errors
    file has the file name
    """
    exists = _check_sample_template_exists(int(study_id))
    if exists['status'] != 'success':
        return exists
    access_error = check_access(int(study_id), user_id)
    if access_error:
        return access_error

    fp_rsp = check_fp(study_id, sample_template)
    if fp_rsp['status'] != 'success':
        # Unknown filepath, so return the error message
        return fp_rsp
    fp_rsp = fp_rsp['file']

    msg = ''
    status = 'success'

    # Offload the update of the sample template to the cluster
    job_id = safe_submit(user_id, update_sample_template, int(study_id),
                         fp_rsp)
    # Store the job id attaching it to the sample template id
    r_client.set(SAMPLE_TEMPLATE_KEY_FORMAT % study_id,
                 dumps({'job_id': job_id}))

    return {'status': status, 'message': msg, 'file': sample_template}
Пример #14
0
def artifact_post_req(user_id,
                      filepaths,
                      artifact_type,
                      name,
                      prep_template_id,
                      artifact_id=None):
    """Creates the initial artifact for the prep template

    Parameters
    ----------
    user_id : str
        User adding the atrifact
    filepaths : dict of str
        Comma-separated list of files to attach to the artifact,
        keyed by file type
    artifact_type : str
        The type of the artifact
    name : str
        Name to give the artifact
    prep_template_id : int or str castable to int
        Prep template to attach the artifact to
    artifact_id : int or str castable to int, optional
        The id of the imported artifact

    Returns
    -------
    dict of objects
        A dictionary containing the new artifact ID
        {'status': status,
         'message': message,
         'artifact': id}
    """
    prep = PrepTemplate(int(prep_template_id))
    study_id = prep.study_id

    # First check if the user has access to the study
    access_error = check_access(study_id, user_id)
    if access_error:
        return access_error

    if artifact_id:
        # if the artifact id has been provided, import the artifact
        job_id = safe_submit(user_id, copy_raw_data, prep, artifact_id)
    else:
        uploads_path = get_mountpoint('uploads')[0][1]
        path_builder = partial(join, uploads_path, str(study_id))
        cleaned_filepaths = []
        for ftype, file_list in viewitems(filepaths):
            # JavaScript sends us this list as a comma-separated list
            for fp in file_list.split(','):
                # JavaScript will send this value as an empty string if the
                # list of files was empty. In such case, the split will
                # generate a single element containing the empty string. Check
                # for that case here and, if fp is not the empty string,
                # proceed to check if the file exists
                if fp:
                    # Check if filepath being passed exists for study
                    full_fp = path_builder(fp)
                    exists = check_fp(study_id, full_fp)
                    if exists['status'] != 'success':
                        return {
                            'status': 'error',
                            'message': 'File does not exist: %s' % fp
                        }
                    cleaned_filepaths.append((full_fp, ftype))

        # This should never happen, but it doesn't hurt to actually have
        # a explicit check, in case there is something odd with the JS
        if not cleaned_filepaths:
            return {
                'status': 'error',
                'message': "Can't create artifact, no files provided."
            }

        job_id = safe_submit(user_id,
                             create_raw_data,
                             artifact_type,
                             prep,
                             cleaned_filepaths,
                             name=name)

    r_client.set(PREP_TEMPLATE_KEY_FORMAT % prep.id, dumps({'job_id': job_id}))

    return {'status': 'success', 'message': ''}
Пример #15
0
def artifact_post_req(user_id, filepaths, artifact_type, name,
                      prep_template_id, artifact_id=None):
    """Creates the initial artifact for the prep template

    Parameters
    ----------
    user_id : str
        User adding the atrifact
    filepaths : dict of str
        Comma-separated list of files to attach to the artifact,
        keyed by file type
    artifact_type : str
        The type of the artifact
    name : str
        Name to give the artifact
    prep_template_id : int or str castable to int
        Prep template to attach the artifact to
    artifact_id : int or str castable to int, optional
        The id of the imported artifact

    Returns
    -------
    dict of objects
        A dictionary containing the new artifact ID
        {'status': status,
         'message': message,
         'artifact': id}
    """
    prep = PrepTemplate(int(prep_template_id))
    study_id = prep.study_id

    # First check if the user has access to the study
    access_error = check_access(study_id, user_id)
    if access_error:
        return access_error

    if artifact_id:
        # if the artifact id has been provided, import the artifact
        job_id = safe_submit(user_id, copy_raw_data, prep, artifact_id)
    else:
        uploads_path = get_mountpoint('uploads')[0][1]
        path_builder = partial(join, uploads_path, str(study_id))
        cleaned_filepaths = []
        for ftype, file_list in viewitems(filepaths):
            # JavaScript sends us this list as a comma-separated list
            for fp in file_list.split(','):
                # JavaScript will send this value as an empty string if the
                # list of files was empty. In such case, the split will
                # generate a single element containing the empty string. Check
                # for that case here and, if fp is not the empty string,
                # proceed to check if the file exists
                if fp:
                    # Check if filepath being passed exists for study
                    full_fp = path_builder(fp)
                    exists = check_fp(study_id, full_fp)
                    if exists['status'] != 'success':
                        return {'status': 'error',
                                'message': 'File does not exist: %s' % fp}
                    cleaned_filepaths.append((full_fp, ftype))

        # This should never happen, but it doesn't hurt to actually have
        # a explicit check, in case there is something odd with the JS
        if not cleaned_filepaths:
            return {'status': 'error',
                    'message': "Can't create artifact, no files provided."}

        job_id = safe_submit(user_id, create_raw_data, artifact_type, prep,
                             cleaned_filepaths, name=name)

    r_client.set(PREP_TEMPLATE_KEY_FORMAT % prep.id, dumps({'job_id': job_id}))

    return {'status': 'success',
            'message': ''}
Пример #16
0
def prep_template_patch_req(user_id, req_op, req_path, req_value=None,
                            req_from=None):
    """Modifies an attribute of the prep template

    Parameters
    ----------
    user_id : str
        The id of the user performing the patch operation
    req_op : str
        The operation to perform on the prep information
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Returns
    -------
    dict of {str, str}
        A dictionary with the following keys:
        - status: str, whether if the request is successful or not
        - message: str, if the request is unsuccessful, a human readable error
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        # The structure of the path should be /prep_id/attribute_to_modify/
        # so if we don't have those 2 elements, we should return an error
        if len(req_path) != 2:
            return {'status': 'error',
                    'message': 'Incorrect path parameter'}
        prep_id = int(req_path[0])
        attribute = req_path[1]

        # Check if the user actually has access to the prep template
        prep = PrepTemplate(prep_id)
        access_error = check_access(prep.study_id, user_id)
        if access_error:
            return access_error

        status = 'success'
        msg = ''
        if attribute == 'investigation_type':
            prep.investigation_type = req_value
        elif attribute == 'data':
            fp = check_fp(prep.study_id, req_value)
            if fp['status'] != 'success':
                return fp
            fp = fp['file']
            job_id = safe_submit(user_id, update_prep_template, prep_id, fp)
            r_client.set(PREP_TEMPLATE_KEY_FORMAT % prep_id, job_id)
        else:
            # We don't understand the attribute so return an error
            return {'status': 'error',
                    'message': 'Attribute "%s" not found. '
                               'Please, check the path parameter' % attribute}

        return {'status': status, 'message': msg}
    else:
        return {'status': 'error',
                'message': 'Operation "%s" not supported. '
                           'Current supported operations: replace' % req_op}
Пример #17
0
def prep_template_patch_req(user_id, req_op, req_path, req_value=None,
                            req_from=None):
    """Modifies an attribute of the prep template

    Parameters
    ----------
    user_id : str
        The id of the user performing the patch operation
    req_op : str
        The operation to perform on the prep information
    req_path : str
        The prep information and attribute to patch
    req_value : str, optional
        The value that needs to be modified
    req_from : str, optional
        The original path of the element

    Returns
    -------
    dict of {str, str}
        A dictionary with the following keys:
        - status: str, whether if the request is successful or not
        - message: str, if the request is unsuccessful, a human readable error
    """
    req_path = [v for v in req_path.split('/') if v]
    if req_op == 'replace':
        # The structure of the path should be /prep_id/attribute_to_modify/
        # so if we don't have those 2 elements, we should return an error
        if len(req_path) != 2:
            return {'status': 'error',
                    'message': 'Incorrect path parameter'}
        prep_id = int(req_path[0])
        attribute = req_path[1]

        # Check if the user actually has access to the prep template
        prep = PrepTemplate(prep_id)
        access_error = check_access(prep.study_id, user_id)
        if access_error:
            return access_error

        status = 'success'
        msg = ''
        if attribute == 'investigation_type':
            prep.investigation_type = req_value
        elif attribute == 'data':
            fp = check_fp(prep.study_id, req_value)
            if fp['status'] != 'success':
                return fp
            fp = fp['file']
            job_id = safe_submit(user_id, update_prep_template, prep_id, fp)
            r_client.set(PREP_TEMPLATE_KEY_FORMAT % prep_id,
                         dumps({'job_id': job_id}))
        else:
            # We don't understand the attribute so return an error
            return {'status': 'error',
                    'message': 'Attribute "%s" not found. '
                               'Please, check the path parameter' % attribute}

        return {'status': status, 'message': msg}
    elif req_op == 'remove':
        # The structure of the path should be /prep_id/{columns|samples}/name
        if len(req_path) != 3:
            return {'status': 'error',
                    'message': 'Incorrect path parameter'}
        prep_id = int(req_path[0])
        attribute = req_path[1]
        attr_id = req_path[2]

        # Check if the user actually has access to the study
        pt = PrepTemplate(prep_id)
        access_error = check_access(pt.study_id, user_id)
        if access_error:
            return access_error

        # Offload the deletion of the column to the cluster
        job_id = safe_submit(user_id, delete_sample_or_column, PrepTemplate,
                             prep_id, attribute, attr_id)
        # Store the job id attaching it to the sample template id
        r_client.set(PREP_TEMPLATE_KEY_FORMAT % prep_id,
                     dumps({'job_id': job_id}))
        return {'status': 'success', 'message': ''}
    else:
        return {'status': 'error',
                'message': 'Operation "%s" not supported. '
                           'Current supported operations: replace, remove'
                           % req_op}