Esempio n. 1
0
    def test_translate_ids_with_sample_id(self):
        # Tests sample_id_to_specimen_id and specimen_id_to_sample_id when
        # there is no specimen identifier set for the study
        s = Study(1)

        obs = s.sample_id_to_specimen_id('1.SKM4.640180')
        self.assertEqual(obs, '1.SKM4.640180')

        # doesn't even need to be a valid sample id
        obs = s.sample_id_to_specimen_id('SKM3')
        self.assertEqual(obs, 'SKM3')

        with self.assertRaisesRegex(ValueError, 'Could not find "SKM4"'):
            s.specimen_id_to_sample_id('SKM4')

        with self.assertRaisesRegex(ValueError, 'Could not find "SSSS"'):
            s.specimen_id_to_sample_id('SSSS')
Esempio n. 2
0
    def test_translate_ids_with_specimen_id(self):
        s = Study(1)
        # HACK: the Study object in labman can't modify specimen_id_column
        # hence we do this directly in SQL, if a test fails the transaction
        # will rollback, otherwise we reset the column to NULL.
        sql = """UPDATE qiita.study
                 SET specimen_id_column = %s
                 WHERE study_id = 1"""
        with sql_connection.TRN as TRN:
            TRN.add(sql, ['anonymized_name'])

            obs = s.sample_id_to_specimen_id('1.SKM4.640180')
            self.assertEqual(obs, 'SKM4')

            obs = s.specimen_id_to_sample_id('SKM4')
            self.assertEqual(obs, '1.SKM4.640180')

            # should be an exact match
            with self.assertRaisesRegex(ValueError,
                                        'Could not find \"1\.skm4\.640180\"'):
                s.sample_id_to_specimen_id('1.skm4.640180')
            with self.assertRaisesRegex(ValueError, 'Could not find \"skm4\"'):
                s.specimen_id_to_sample_id('skm4')

            # raise an error in the rare case that the specimen_id_column was
            # set to something that's not unique (this could only accidentally
            # happen)
            TRN.add(sql, ['taxon_id'])
            with self.assertRaisesRegex(
                    RuntimeError, 'There are several '
                    'matches found for "1118232"; there is'
                    ' a problem with the specimen id '
                    'column'):
                s.specimen_id_to_sample_id('1118232')

            TRN.add(sql, [None])
Esempio n. 3
0
def sample_plating_process_handler_patch_request(
        user, process_id, req_op, req_path, req_value, req_from):
    """Performs the patch operation on the sample plating process

    Parameters
    ----------
    user: labman.db.user.User
        User performing the request
    process_id: int
        The SamplePlatingProcess to apply the patch operation
    req_op: string
        JSON PATCH op parameter
    req_path: string
        JSON PATCH path parameter
    req_value: string
        JSON PATCH value parameter
    req_from: string
        JSON PATCH from parameter

    Returns
    -------
    dict
        The results of the patch operation

    Raises
    ------
    HTTPError
        400: If req_op is not a supported operation
        400: If req_path is incorrect
    """
    if req_op == 'replace':
        req_path = [v for v in req_path.split('/') if v]
        if len(req_path) != 5:
            raise HTTPError(400, 'Incorrect path parameter')
        attribute = req_path[0]

        if attribute == 'well':
            row = req_path[1]
            col = req_path[2]
            study_id = int(req_path[3])
            well_attribute = req_path[4]

            # The default values of the variables sample_id and
            # blank_or_unknown are set before the try, and these are the values
            # that are used if either (a) study_id is not 0 OR (b) the try
            # fails with a ValueError (see comment in try below). If the try
            # fails with anything other than a ValueError then the entire
            # function bails, so it doesn't matter what these variables are set
            # to. If and only if the try succeeds are these variables set to
            # the values within the try.
            sample_id = req_value
            blank_or_unknown = True

            # It actually IS possible to plate a plate without specifying
            # separate study id(s); can plate just all blanks, or can provide
            # the fully qualified sample id(s)--i.e., <studyid>.<sampleid>.
            if study_id != 0:
                try:
                    # Note that the try fails iff the
                    # Study(study_id).specimen_id_to_sample_id() call fails,
                    # as the blank_or_unknown = False can't really fail ...
                    # this assures that we can't realistically end up in an
                    # inconsistent situation where sample_id has been set
                    # during the try but blank_or_unknown has not.
                    #
                    # Thus, the ordering of these two statements within the try
                    # is really important: do not change it unless you
                    # understand all of the above!
                    the_study = Study(study_id)
                    sample_id = the_study.specimen_id_to_sample_id(
                        req_value)
                    blank_or_unknown = False
                except ValueError:
                    pass
                # end try/except
            # end if

            if well_attribute == 'sample':
                if req_value is None or not req_value.strip():
                    raise HTTPError(
                        400, 'A new value for the well should be provided')

                plates = Plate.search(samples=[sample_id])
                process = SamplePlatingProcess(process_id)
                plates = set(plates) - {process.plate}
                prev_plates = [{'plate_id': p.id, 'plate_name': p.external_id}
                               for p in plates]
                content, sample_ok = process.update_well(row, col, sample_id)

                if blank_or_unknown:
                    req_value = content

                return {'sample_id': req_value, 'previous_plates': prev_plates,
                        'sample_ok': sample_ok}
            elif well_attribute == 'notes':
                if req_value is not None:
                    # If the user provides an empty string, just store None
                    # in the database
                    req_value = (req_value.strip()
                                 if req_value.strip() else None)
                SamplePlatingProcess(process_id).comment_well(
                    row, col, req_value)
                return {'comment': req_value}
            else:
                raise HTTPError(
                    404, 'Well attribute %s not found' % well_attribute)
        else:
            raise HTTPError(404, 'Attribute %s not found' % attribute)

    else:
        raise HTTPError(400, 'Operation %s not supported. Current supported '
                             'operations: replace' % req_op)