def post(self): parser = RequestParsers.study_type_report_parser() studytype = None args = parser.parse_args(req=request) studytype = args['studytype'] slim = args['slim'] verbose = args['verbose'] drive = args['drive'] if studytype: studytype = studytype.strip() else: abort(400) # User authentication user_token = None if "user_token" in request.headers: user_token = request.headers["user_token"] else: abort(401) wsc = WsClient() is_curator, __, __, __, study_location, __, __, __ = wsc.get_permissions('MTBLS1', user_token) if is_curator is False: abort(413) reporting_path = app.config.get('MTBLS_FTP_ROOT') + app.config.get('REPORTING_PATH') + 'global/' msg = AnalyticalMethodBuilder( original_study_location=study_location, studytype=studytype, slim=slim, reporting_path=reporting_path, verbose=verbose, g_drive=drive ).build() logger.info(msg) return jsonify({'message': msg})
# you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. from flask import request, abort from flask_restful import Resource from flask_restful_swagger import swagger from app.ws.mtblsWSclient import WsClient from app.ws.utils import * from app.ws.isaApiClient import IsaApiClient logger = logging.getLogger('wslog') wsc = WsClient() iac = IsaApiClient() class Convert2ISAtab(Resource): @swagger.operation( summary="Convert mzML files into ISA-Tab", notes= '''</P><B>Be aware that any ISA-Tab files will be overwritten for this study</P> This process can run for a long while, please be patient</B>''', parameters=[{ "name": "study_id", "description": "Existing Study Identifier for generating new ISA-Tab files", "required": True, "allowMultiple": False,
def __init__(self): self.inv_filename = "i_Investigation.txt" self.wsc = WsClient() # MetaboLights (Java-Based) WebService client return
class IsaApiClient: def __init__(self): self.inv_filename = "i_Investigation.txt" self.wsc = WsClient() # MetaboLights (Java-Based) WebService client return def get_isa_json(self, study_id, api_key, study_location=None): """ Get an ISA-API Investigation object reading directly from the ISA-Tab files :param study_id: MTBLS study identifier :param api_key: User API key for accession check :param study_location: The filesystem location of the study :return: an ISA-API Investigation object """ start = time.time() if study_location is None: logger.info( "Study location is not set, will have load study from filesystem" ) path = self.wsc.get_study_location(study_id, api_key) else: logger.info("Study location is: " + study_location) path = study_location # try the new parser first isa_json = None try: isa_json = isatab2json.convert(path, validate_first=False, use_new_parser=True) except Exception: # on failure, use the old one try: isa_json = isatab2json.convert(path, validate_first=False, use_new_parser=False) except Exception: # if it fails too if isa_json is None: abort(500) else: logger.info('... get_isa_json() processing (I): %s sec.', time.time() - start) return isa_json else: logger.info('... get_isa_json() processing (II): %s sec.', time.time() - start) return isa_json @staticmethod def create_new_study(title, description, sub_date, pub_rel_date, mtbls_accession, technology): """ Create a new MTBLS Study :param title: :param description: :param sub_date: Submission date (now) :param pub_rel_date: Public release date :param mtbls_accession: MTBLS id :param technology: MS or NMR :return: an ISA-JSON representation of the Study """ inv_file_name = 'i_investigation.txt' study_file_name = 's_study.txt' assay_file_name = 'a_assay.txt' if mtbls_accession is not None: study_file_name = 's_' + mtbls_accession + '_' + technology + '.txt' assay_file_name = 'a_' + mtbls_accession + '_' + technology + '.txt' # investigation file investigation = Investigation(filename=inv_file_name) investigation.title = title investigation.description = description investigation.submission_date = sub_date investigation.public_release_date = pub_rel_date # study file study = Study(filename=study_file_name) study.identifier = mtbls_accession study.title = title study.description = description study.submission_date = sub_date study.public_release_date = pub_rel_date # investigation.studies.append(study) protocol = Protocol() # assay file assay = Assay(filename=assay_file_name) assay.technology_platform = technology # TODO, ontology term # assay.technology_type = technology study.assays.append(assay) # Add it all together investigation.studies.append(study) return investigation def get_isa_study(self, study_id, api_key, skip_load_tables=True, study_location=None, failing_gracefully=False): """ Get an ISA-API Investigation object reading directly from the ISA-Tab files :param study_id: MTBLS study identifier :param api_key: User API key for accession check :param skip_load_tables: speed-up reading by skiping loading assay and sample tables :param study_location: filessystem location of the study :return: a tuple consisting in ISA-Study obj, ISA-Investigation obj and path to the Study in the file system """ if skip_load_tables == 'false': skip_load_tables = False if study_location is None: logger.info( "Study location is not set, will have load study from filesystem" ) std_path = self.wsc.get_study_location(study_id, api_key) else: logger.info("Study location is: " + study_location) std_path = study_location try: i_filename = glob.glob(os.path.join(std_path, "i_*.txt"))[0] fp = open(i_filename, encoding='utf-8', errors='ignore') # loading tables also load Samples and Assays isa_inv = load(fp, skip_load_tables) # ToDo. Add MAF to isa_study isa_study = isa_inv.studies[0] except IndexError as e: logger.exception("Failed to find Investigation file from %s", study_id, std_path) logger.error(str(e)) if failing_gracefully: return None, None, None else: abort(417) except Exception as e: logger.exception("Failed to find Investigation file from %s", study_id, std_path) logger.error(str(e)) if failing_gracefully: return None, None, None else: abort(417) else: return isa_study, isa_inv, std_path def write_isa_study(self, inv_obj, api_key, std_path, save_investigation_copy=True, save_samples_copy=False, save_assays_copy=False): """ Write back an ISA-API Investigation object directly into ISA-Tab files :param inv_obj: ISA-API Investigation object :param api_key: User API key for accession check :param std_path: file system path to destination folder :param save_investigation_copy: Keep track of changes saving a copy of the unmodified i_*.txt file :param save_samples_copy: Keep track of changes saving a copy of the unmodified s_*.txt file :param save_assays_copy: Keep track of changes saving a copy of the unmodified a_*.txt and m_*.tsv files :return: """ # dest folder name is a timestamp update_path_suffix = app.config.get('UPDATE_PATH_SUFFIX') update_path = os.path.join(std_path, update_path_suffix) if save_investigation_copy or save_samples_copy or save_assays_copy: # Only create audit folder when requested dest_path = new_timestamped_folder(update_path) # make a copy before applying changes if save_investigation_copy: src_file = os.path.join(std_path, self.inv_filename) dest_file = os.path.join(dest_path, self.inv_filename) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) if save_samples_copy: for sample_file in glob.glob(os.path.join(std_path, "s_*.txt")): sample_file_name = os.path.basename(sample_file) src_file = sample_file dest_file = os.path.join(dest_path, sample_file_name) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) if save_assays_copy: for assay_file in glob.glob(os.path.join(std_path, "a_*.txt")): assay_file_name = os.path.basename(assay_file) src_file = assay_file dest_file = os.path.join(dest_path, assay_file_name) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) # Save the MAF for maf in glob.glob(os.path.join(std_path, "m_*.tsv")): maf_file_name = os.path.basename(maf) src_file = maf dest_file = os.path.join(dest_path, maf_file_name) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) logger.info("Writing %s to %s", self.inv_filename, std_path) i_file_name = self.inv_filename dump(inv_obj, std_path, i_file_name=i_file_name, skip_dump_tables=False) return
class IsaApiClient: def __init__(self): self.inv_filename = "i_Investigation.txt" self.wsc = WsClient() # MetaboLights (Java-Based) WebService client return def get_isa_json(self, study_id, api_key, study_location=None): """ Get an ISA-API Investigation object reading directly from the ISA-Tab files :param study_id: MTBLS study identifier :param api_key: User API key for accession check :param study_location: The filesystem location of the study :return: an ISA-API Investigation object """ start = time.time() if study_location is None: logger.info("Study location is not set, will have load study from filesystem") path = self.wsc.get_study_location(study_id, api_key) else: logger.info("Study location is: " + study_location) path = study_location # try the new parser first isa_json = None try: isa_json = isatab2json.convert(path, validate_first=False, use_new_parser=True) except Exception: # on failure, use the old one try: isa_json = isatab2json.convert(path, validate_first=False, use_new_parser=False) except Exception: # if it fails too if isa_json is None: abort(500) else: logger.info('... get_isa_json() processing (I): %s sec.', time.time() - start) return isa_json else: logger.info('... get_isa_json() processing (II): %s sec.', time.time() - start) return isa_json @staticmethod def create_new_study(title, description, sub_date, pub_rel_date, mtbls_accession, technology): """ Create a new MTBLS Study :param title: :param description: :param sub_date: Submission date (now) :param pub_rel_date: Public release date :param mtbls_accession: MTBLS id :param technology: MS or NMR :return: an ISA-JSON representation of the Study """ inv_file_name = 'i_investigation.txt' study_file_name = 's_study.txt' assay_file_name = 'a_assay.txt' if mtbls_accession is not None: study_file_name = 's_' + mtbls_accession + '_' + technology + '.txt' assay_file_name = 'a_' + mtbls_accession + '_' + technology + '.txt' # investigation file investigation = Investigation(filename=inv_file_name) investigation.title = title investigation.description = description investigation.submission_date = sub_date investigation.public_release_date = pub_rel_date # study file study = Study(filename=study_file_name) study.identifier = mtbls_accession study.title = title study.description = description study.submission_date = sub_date study.public_release_date = pub_rel_date # investigation.studies.append(study) protocol = Protocol() # assay file assay = Assay(filename=assay_file_name) assay.technology_platform = technology # TODO, ontology term # assay.technology_type = technology study.assays.append(assay) # Add it all together investigation.studies.append(study) return investigation def get_isa_study(self, study_id, api_key, skip_load_tables=True, study_location=None): """ Get an ISA-API Investigation object reading directly from the ISA-Tab files :param study_id: MTBLS study identifier :param api_key: User API key for accession check :param skip_load_tables: speed-up reading by skiping loading assay and sample tables :param study_location: filessystem location of the study :return: a tuple consisting in ISA-Study obj, ISA-Investigation obj and path to the Study in the file system """ if study_location is None: logger.info("Study location is not set, will have load study from filesystem") std_path = self.wsc.get_study_location(study_id, api_key) else: logger.info("Study location is: " + study_location) std_path = study_location try: i_filename = glob.glob(os.path.join(std_path, "i_*.txt"))[0] fp = open(i_filename) # loading tables also load Samples and Assays isa_inv = load(fp, skip_load_tables) isa_study = isa_inv.studies[0] except IndexError as e: logger.exception("Failed to find Investigation file from %s", study_id, std_path) logger.error(str(e)) abort(400) except Exception as e: logger.exception("Failed to find Investigation file from %s", study_id, std_path) logger.error(str(e)) abort(400) else: return isa_study, isa_inv, std_path def write_isa_study(self, inv_obj, api_key, std_path, save_investigation_copy=True, save_samples_copy=False, save_assays_copy=False): """ Write back an ISA-API Investigation object directly into ISA-Tab files :param inv_obj: ISA-API Investigation object :param api_key: User API key for accession check :param std_path: file system path to destination folder :param save_investigation_copy: Keep track of changes saving a copy of the unmodified i_*.txt file :param save_samples_copy: Keep track of changes saving a copy of the unmodified s_*.txt file :param save_assays_copy: Keep track of changes saving a copy of the unmodified a_*.txt and m_*.tsv files :return: """ # dest folder name is a timestamp update_path_suffix = app.config.get('UPDATE_PATH_SUFFIX') update_path = os.path.join(std_path, update_path_suffix) if save_investigation_copy or save_samples_copy or save_assays_copy: # Only create audit folder when requested dest_path = new_timestamped_folder(update_path) # make a copy before applying changes if save_investigation_copy: src_file = os.path.join(std_path, self.inv_filename) dest_file = os.path.join(dest_path, self.inv_filename) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) if save_samples_copy: for sample_file in glob.glob(os.path.join(std_path, "s_*.txt")): sample_file_name = os.path.basename(sample_file) src_file = sample_file dest_file = os.path.join(dest_path, sample_file_name) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) if save_assays_copy: for assay_file in glob.glob(os.path.join(std_path, "a_*.txt")): assay_file_name = os.path.basename(assay_file) src_file = assay_file dest_file = os.path.join(dest_path, assay_file_name) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) # Save the MAF for maf in glob.glob(os.path.join(std_path, "m_*.tsv")): maf_file_name = os.path.basename(maf) src_file = maf dest_file = os.path.join(dest_path, maf_file_name) logger.info("Copying %s to %s", src_file, dest_file) copy_file(src_file, dest_file) logger.info("Writing %s to %s", self.inv_filename, std_path) i_file_name = self.inv_filename dump(inv_obj, std_path, i_file_name=i_file_name, skip_dump_tables=False) return