def test_parse_tube_rack_csv(app_db_less): with app_db_less.app_context(): rack_size, tube_dict = parse_tube_rack_csv("DN_48_valid") assert rack_size == 48 assert tube_dict == { "rack_barcode": "DN_48_valid", "layout": { "FR05653780": "A1", "FR05653808": "A2", "FR05653791": "A3", "FR05653668": "A4", "FR05653832": "A5", "FR05653743": "A6", "FR05653698": "A7", "FR05653716": "A8", "FR05653773": "B1", "FR05653774": "B2", "FR05653756": "B3", "FR05653730": "B4", "FR05653765": "B5", "FR05653687": "B6", "FR05653753": "B7", "FR05653747": "B8", "FR05653671": "C1", "FR05653623": "C2", "FR05653758": "C3", "FR05653845": "C4", "FR05653704": "C5", "FR05653642": "C6", "FR05653770": "C7", "FR05653630": "C8", "FR05653796": "D1", "FR05653795": "D2", "FR05653769": "D3", "FR05653777": "D4", "FR05653734": "D5", "FR05653703": "D6", "FR05653783": "D7", "FR05653748": "D8", "FR05653735": "E1", "FR05653824": "E2", "FR05653725": "E3", "FR05653789": "E4", "FR05653797": "E5", "FR05653624": "E6", "FR05653812": "E7", "FR05653784": "E8", "FR05653628": "F1", "FR05653658": "F2", "FR05653733": "F3", "FR05653678": "F4", "FR05653699": "F5", "FR05653785": "F6", "FR05653736": "F7", "FR05653732": "F8", }, } with raises(FileNotFoundError): parse_tube_rack_csv("blah")
def get_tubes_from_rack_barcode( tube_rack_barcode: str) -> Tuple[Dict[str, str], int]: """A Flask route which expects a tube rack barcode and returns the tubes in the rack with their coordinates. Arguments: tube_rack_barcode {str} -- the barcode on the tube rack Raises: CsvNotFoundError: raised when the CSV file is not found for this barcode Returns: Dict -- a dict with the results or description of the error with "error" as the key """ try: logger.info( f"Looking for tube rack with barcode '{tube_rack_barcode}'") if not csv_file_exists(f"{tube_rack_barcode}.csv"): raise CsvNotFoundError(tube_rack_barcode) _, tubes_layout = parse_tube_rack_csv(tube_rack_barcode) return tubes_layout, HTTPStatus.OK except CsvNotFoundError as e: logger.exception(e) return {}, HTTPStatus.NO_CONTENT except Exception as e: logger.exception(e) return ( { "error": f"Server error: {type(e).__name__}" }, HTTPStatus.INTERNAL_SERVER_ERROR, )
def test_parse_tube_rack_csv_ignores_no_read(app_db_less, client, tmpdir): with app_db_less.app_context(): expected_output = { "rack_barcode": "DN_48_no_read", "layout": {"FR05653780": "A1", "FR05653808": "A2", "FR05653801": "F8"}, } rack_size, tube_dict = parse_tube_rack_csv("DN_48_no_read") assert rack_size == 48 assert tube_dict == expected_output
def wrangle_labware(labware_barcode: str) -> Tuple[Dict[str, str], int]: """Wrangles with the provided labware barcode. - It first retrieves data from the MLWH for the barcode. If there is data, it determines what type of labware it is - If the labware is a tube rack, it looks for the CSV file expected for that tube rack - If the CSV file is present and valid, it creates and send a new tube rack request to Sequencescape - If the CSV is not present or fails validation, it raises an exception - If the labware is a plate, it creates and sends a request to Sequencescape - If there is no data in the MLWH, it raises an exception Arguments: labware_barcode {str} -- the labware to look for and wrangle with Returns: Dict -- the body of the request to send to Sequencescape """ # get data from the MLWH for the barcode cursor = get_db() cursor.execute(f"SELECT * FROM {app.config['MLWH_DB_TABLE']} " f"WHERE container_barcode = '{labware_barcode}'") logger.debug(f"Number of records found: {cursor.rowcount}") # if there is data in the MLWH, determine what type of labware it is if cursor.rowcount > 0: results = list(cursor) pretty(logger, results) labware_type = determine_labware_type(labware_barcode, results) logger.info(f"Determined labware type: {labware_type}") sample_type = determine_sample_type(labware_barcode, results) logger.info(f"Determined sample type: {sample_type}") purpose_name = determine_purpose_name(labware_barcode, labware_type, sample_type) logger.info(f"Determined purpose name: {purpose_name}") # Assuming study is the same for all wells/tubes in a container study_name = results[0]["study"] logger.info(f"Study name: {study_name}") if labware_type == LabwareType.TUBE_RACK: if csv_file_exists(f"{labware_barcode}.csv"): _, tubes_and_coordinates = parse_tube_rack_csv(labware_barcode) db_tube_barcodes = [row["tube_barcode"] for row in results] validate_tubes(labware_barcode, tubes_and_coordinates["layout"].keys(), db_tube_barcodes) tube_rack_body = create_tube_rack_body( labware_barcode, results, purpose_uuid=get_entity_uuid(PLATE_PURPOSE_ENTITY, purpose_name), study_uuid=get_entity_uuid(STUDY_ENTITY, study_name), ) return create_tube_rack(tube_rack_body) else: raise CsvNotFoundError(labware_barcode) if labware_type == LabwareType.PLATE: plate_body = create_plate_body( labware_barcode, results, purpose_uuid=get_entity_uuid(PLATE_PURPOSE_ENTITY, purpose_name), study_uuid=get_entity_uuid(STUDY_ENTITY, study_name), ) return create_plate(plate_body) return {}, HTTPStatus.INTERNAL_SERVER_ERROR else: raise BarcodeNotFoundError(labware_barcode)