def post(self): plate_comment_keywords = self.get_argument("plate_comment_keywords") well_comment_keywords = self.get_argument("well_comment_keywords") operation = self.get_argument("operation") sample_names = json_decode(self.get_argument('sample_names')) res = { "data": [[p.id, p.external_id] for p in Plate.search(samples=sample_names, plate_notes=plate_comment_keywords, well_notes=well_comment_keywords, query_type=operation)] } self.write(res)
def test_search(self): with self.assertRaises(ValueError): Plate.search() with self.assertRaises(ValueError): Plate.search(samples=['1.SKB1.640202'], query_type='WRONG') plate21 = Plate(21) plate22 = Plate(22) plate23 = Plate(23) plate27 = Plate(27) plate30 = Plate(30) plate33 = Plate(33) self.assertEqual( Plate.search(samples=['1.SKB1.640202', '1.SKB2.640194']), [plate21, plate27, plate30, plate33]) self.assertEqual(Plate.search(samples=['1.SKB1.640202']), [plate21, plate27, plate30, plate33]) self.assertEqual(Plate.search(plate_notes='interesting'), []) # Add comments to a plate so we can actually test the # search functionality plate22.notes = 'Some interesting notes' plate23.notes = 'More boring notes' self.assertEqual(Plate.search(plate_notes='interesting'), [plate22]) self.assertCountEqual(Plate.search(plate_notes='interesting boring'), []) self.assertEqual( Plate.search(samples=['1.SKB1.640202'], plate_notes='interesting'), []) # sample '1.SKB1.640202' is on 4 sample plates, plus there is a # gdna plate with a note containing the word 'interesting' self.assertCountEqual( Plate.search(samples=['1.SKB1.640202'], plate_notes='interesting', query_type='UNION'), [plate21, plate22, plate27, plate30, plate33]) # The search engine ignores common english words self.assertEqual(Plate.search(plate_notes='more'), []) # Add comments to some wells plate23.get_well(1, 1).composition.notes = 'What else should I write?' self.assertEqual(Plate.search(well_notes='write'), [plate23]) self.assertEqual( Plate.search(plate_notes='interesting', well_notes='write'), []) self.assertCountEqual( Plate.search(plate_notes='interesting', well_notes='write', query_type='UNION'), [plate22, plate23])
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: labcontrol.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)