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')
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])
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)