def get(self, request): """ Returns information about a specific patient, including a list of samples and aliquots derived from this patient. Takes a patient barcode (of length 12, *eg* TCGA-B9-7268) as a required parameter. User does not need to be authenticated. """ cursor = None db = None patient_barcode = request.get_assigned_value('patient_barcode') query_tuple = (str(patient_barcode),) clinical_query_str, sample_query_str, aliquot_query_str = PatientsGetQueryBuilder().build_queries() try: db = sql_connection() cursor = db.cursor(MySQLdb.cursors.DictCursor) # build clinical data message cursor.execute(clinical_query_str, query_tuple) row = cursor.fetchone() if row is None: cursor.close() db.close() logger.warn("Patient barcode {} not found in metadata_clinical table.".format(patient_barcode)) raise endpoints.NotFoundException("Patient barcode {} not found".format(patient_barcode)) constructor_dict = build_constructor_dict_for_message(MetadataItem(), row) clinical_data_item = MetadataItem(**constructor_dict) # get list of samples cursor.execute(sample_query_str, query_tuple) sample_list = [row['sample_barcode'] for row in cursor.fetchall()] # get list of aliquots cursor.execute(aliquot_query_str, query_tuple) aliquot_list = [row['AliquotBarcode'] for row in cursor.fetchall()] return PatientDetails(clinical_data=clinical_data_item, samples=sample_list, aliquots=aliquot_list) except (IndexError, TypeError), e: logger.info("Patient {} not found. Error: {}".format(patient_barcode, e)) raise endpoints.NotFoundException("Patient {} not found.".format(patient_barcode))
def annotations(self, request): """ Returns TCGA annotations about a specific aliquot, Takes a aliquot barcode (of length 28 *eg* TCGA-01-0628-11A-01D-0358-06) as a required parameter. User does not need to be authenticated. """ cursor = None db = None aliquot_barcode = request.get_assigned_value('aliquot_barcode') query_tuple = (str(aliquot_barcode),) # check to make sure aliquot_barcode is in correct form try: parts = aliquot_barcode.split('-') assert len(parts) == 7 assert len(parts[0]) == 4 assert len(parts[1]) == 2 assert len(parts[2]) == 4 assert len(parts[3]) == 3 assert len(parts[4]) in [2, 3] assert len(parts[5]) == 4 assert len(parts[6]) == 2 except AssertionError: raise endpoints.BadRequestException('{} is not the correct format for a aliquot barcode. ' 'Aliquot barcodes must be of the form XXXX-XX-XXXX-XXX-XXX-XXXX-XX ' 'or XXXX-XX-XXXX-XXX-XX-XXXX-XX.'.format(aliquot_barcode)) item_type_name = request.get_assigned_value('item_type_name') # check to make sure each item_type_name is valid if len(item_type_name) > 0: for itm in item_type_name: itm = itm.strip() if itm.lower() not in ['patient', 'aliquot', 'analyte', 'shipped portion', 'portion', 'slide', 'sample']: raise endpoints.BadRequestException("'{}' is not a valid entry for item_type_name. " "Valid entries include 'Patient', 'Aliquot', 'Analyte', 'Shipped Portion', " "'Portion', 'Slide', and 'Sample'".format(itm)) query_tuple += (itm,) query_str = AliquotsAnnotationsQueryBuilder().build_query(item_type_name=item_type_name) metadata_samples_query_str = AliquotsAnnotationsQueryBuilder().build_metadata_samples_query() try: db = sql_connection() cursor = db.cursor(MySQLdb.cursors.DictCursor) # build annotation message cursor.execute(query_str, query_tuple) rows = cursor.fetchall() cursor.execute(metadata_samples_query_str, (str(aliquot_barcode),)) metadata_sample_rows = cursor.fetchall() if len(rows) == 0: cursor.close() db.close() if len(metadata_sample_rows) == 0: msg = "Aliquot barcode {} not found in the database.".format(aliquot_barcode) logger.info(msg) else: msg = "No annotations found for aliquot barcode {}".format(aliquot_barcode) if item_type_name is not None: msg += " and item type name {}. Item type name must be one of the following: " \ "'Patient', 'Aliquot', 'Analyte', 'Shipped Portion', 'Portion', 'Slide', 'Sample'.".format(item_type_name) logger.info(msg) raise endpoints.NotFoundException(msg) items = [] for row in rows: constructor_dict = build_constructor_dict_for_message(MetadataAnnotationItem(), row) items.append(MetadataAnnotationItem(**constructor_dict)) return MetadataAnnotationList(items=items, count=len(items)) except (IndexError, TypeError), e: logger.info("Aliquot {} not found. Error: {}".format(aliquot_barcode, e)) raise endpoints.NotFoundException("Aliquot {} not found.".format(aliquot_barcode))
def get(self, request): """ Given a sample barcode (of length 16, *eg* TCGA-B9-7268-01A), this endpoint returns all available "biospecimen" information about this sample, the associated patient barcode, a list of associated aliquots, and a list of "data_details" blocks describing each of the data files associated with this sample """ cursor = None db = None sample_barcode = request.get_assigned_value('sample_barcode') pipeline = request.get_assigned_value('pipeline') platform = request.get_assigned_value('platform') aliquot_query_str = SamplesGetQueryBuilder().build_aliquot_query(platform=platform, pipeline=pipeline) biospecimen_query_str = SamplesGetQueryBuilder().build_biospecimen_query() data_query_str = SamplesGetQueryBuilder().build_data_query(platform=platform, pipeline=pipeline) patient_query_str = SamplesGetQueryBuilder().build_patient_query() query_tuple = (str(sample_barcode),) extra_query_tuple = query_tuple if pipeline is not None: extra_query_tuple += (pipeline,) if platform is not None: extra_query_tuple += (platform,) try: db = sql_connection() cursor = db.cursor(MySQLdb.cursors.DictCursor) # build biospecimen data message cursor.execute(biospecimen_query_str, query_tuple) row = cursor.fetchone() if row is None: cursor.close() db.close() error_message = "Sample barcode {} not found in metadata_biospecimen table.".format(sample_barcode) raise endpoints.NotFoundException(error_message) constructor_dict = build_constructor_dict_for_message(MetadataItem(), row) biospecimen_data_item = MetadataItem(**constructor_dict) # get list of aliquots cursor.execute(aliquot_query_str, extra_query_tuple) aliquot_list = [row['AliquotBarcode'] for row in cursor.fetchall()] # get patient barcode (superfluous?) cursor.execute(patient_query_str, query_tuple) row = cursor.fetchone() patient_barcode = str(row["case_barcode"]) # prepare to build list of data details messages cursor.execute(data_query_str, extra_query_tuple) cursor_rows = cursor.fetchall() # update every dictionary in cursor_rows to contain the full cloud_storage_path for each sample bad_repo_count, bad_repo_set = \ CohortsSamplesFilesMessageBuilder().get_GCS_file_paths_and_bad_repos(cursor_rows) if bad_repo_count > 0: logger.warn("not returning {count} row(s) in sample_details due to repositories: {bad_repo_list}" .format(count=bad_repo_count, bad_repo_list=list(bad_repo_set))) # build a data details message for each row returned from metadata_data table data_details_list = [] for row in cursor_rows: constructor_dict = build_constructor_dict_for_message(DataDetails(), row) data_details_item = DataDetails(**constructor_dict) data_details_list.append(data_details_item) if bad_repo_count > 0: logger.warn("not returning {count} row(s) in sample_details due to repositories: {bad_repo_list}" .format(count=bad_repo_count, bad_repo_list=list(bad_repo_set))) return SampleDetails(aliquots=aliquot_list, biospecimen_data=biospecimen_data_item, data_details=data_details_list, data_details_count=len(data_details_list), patient=patient_barcode) except (IndexError, TypeError) as e: logger.info("Sample details for barcode {} not found. Error: {}".format(sample_barcode, e)) raise endpoints.NotFoundException( "Sample details for barcode {} not found.".format(sample_barcode)) except MySQLdb.ProgrammingError as e: logger.warn(e) raise endpoints.BadRequestException("Error retrieving biospecimen, patient, or other data. {}".format(e)) finally: if cursor: cursor.close() if db and db.open: db.close()