def post(self): """Saves the given file if the user has a valid API key """ if request.method == 'POST': api_key = request.headers.get('x-api-key') if api_key is None: return BARUtils.error_exit('Invalid API key'), 403 elif SummarizationGeneExpressionUtils.decrement_uses(api_key): now = datetime.now() dt_string = now.strftime("%d-%m-%Y_%H-%M-%S") if 'file' in request.files: file = request.files['file'] extension = '' if file.content_type == 'text/xml': extension = '.xml' elif file.content_type == 'image/svg+xml': extension = '.svg' else: return BARUtils.error_exit('Invalid file type'), 400 filename = os.path.join(DATA_FOLDER, api_key, dt_string + extension) file.save(filename) return BARUtils.success_exit(True) else: return BARUtils.error_exit('No file attached'), 400 else: return BARUtils.error_exit('Invalid API key')
def post(self): """This end point returns gene expression data for a single gene and multiple samples.""" json_data = request.get_json() # Validate json try: json_data = RNASeqSchema().load(json_data) except ValidationError as err: return BARUtils.error_exit(err.messages), 400 species = json_data['species'] database = json_data['database'] gene_id = json_data['gene_id'] sample_ids = json_data['sample_ids'] results = RNASeqUtils.get_data(species, database, gene_id, sample_ids) if results['success']: # Return results if there are data if len(results['data']) > 0: return BARUtils.success_exit(results['data']) else: return BARUtils.error_exit( 'There are no data found for the given gene') else: return BARUtils.error_exit(results['error']), results['error_code']
def post(self): """Takes a CSV file containing expression data and inserts the data into the database """ if request.method == 'POST': if 'file' not in request.files: return BARUtils.error_exit('No file attached'), 400 file = request.files['file'] if file: filename = secure_filename(file.filename) key = request.headers.get('X-Api-Key') file.save(os.path.join(DATA_FOLDER + '/' + key + '/', filename)) if SummarizationGeneExpressionUtils.decrement_uses(key): inputs = """ { 'csvUpload.insertDataScript': './insertData.py', 'csvUpload.id': """ + key + """, 'csvUpload.csv': """ + os.path.join( DATA_FOLDER, key, filename) + """, } """ path = os.path.join(SUMMARIZATION_FILES_PATH, 'csvUpload.wdl') files = { 'workflowSource': ('csvUpload.wdl', open(path, 'rb')), 'workflowInputs': ('rpkm_inputs.json', inputs) } requests.post(CROMWELL_URL + '/api/workflows/v1', files=files) return BARUtils.success_exit(key) else: return BARUtils.error_exit('Invalid API key')
def post(self): """Returns list of pending requests from the database """ if request.method == 'POST': response_json = request.get_json() password = response_json['password'] if ApiManagerUtils.check_admin_pass(password): table = Requests() values = [] try: rows = table.query.filter_by().all() except SQLAlchemyError: return BARUtils.error_exit('Internal server error'), 500 [ values.append({ 'first_name': row.first_name, 'last_name': row.last_name, 'email': row.email, 'telephone': row.telephone, 'contact_type': row.contact_type, 'notes': row.notes }) for row in rows ] return BARUtils.success_exit(values) else: return BARUtils.error_exit('Forbidden'), 403
def post(self): """Takes a CSV file containing expression data and inserts the data into the database""" if request.method == "POST": if "file" not in request.files: return BARUtils.error_exit("No file attached"), 400 file = request.files["file"] if file: filename = secure_filename(file.filename) key = request.headers.get("X-Api-Key") file.save(os.path.join(DATA_FOLDER, key, filename)) if SummarizationGeneExpressionUtils.decrement_uses(key): inputs = (""" { "csvUpload.insertDataScript": "./insertData.py", "csvUpload.id": """ + key + """, "csvUpload.csv": """ + os.path.join(DATA_FOLDER, key, filename) + """, } """) path = os.path.join(SUMMARIZATION_FILES_PATH, "csvUpload.wdl") files = { "workflowSource": ("csvUpload.wdl", open(path, "rb")), "workflowInputs": ("rpkm_inputs.json", inputs), } requests.post(CROMWELL_URL + "/api/workflows/v1", files=files) return BARUtils.success_exit(key) else: return BARUtils.error_exit("Invalid API key")
def post(self): """Returns list of pending requests from the database""" if request.method == "POST": response_json = request.get_json() password = response_json["password"] if ApiManagerUtils.check_admin_pass(password): table = Requests() values = [] try: rows = table.query.filter_by().all() except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500 [ values.append({ "first_name": row.first_name, "last_name": row.last_name, "email": row.email, "telephone": row.telephone, "contact_type": row.contact_type, "notes": row.notes, }) for row in rows ] return BARUtils.success_exit(values) else: return BARUtils.error_exit("Forbidden"), 403
def get(self, table_id=""): """Checks if a given table exists""" con = db.get_engine(bind="summarization") if con.dialect.has_table(con, table_id): return BARUtils.success_exit(True) else: return BARUtils.success_exit(False)
def post(self): """Takes a Google Drive folder ID (containing BAM files) and submits them to the Cromwell server for summarization """ if request.method == 'POST': json = request.get_json() key = request.headers.get('X-Api-Key') if SummarizationGeneExpressionUtils.decrement_uses(key): inputs = """ { 'geneSummarization.gtf': './data/Araport11_GFF3_genes_transposons.201606.gtf', 'geneSummarization.summarizeGenesScript': './summarize_genes.R', 'geneSummarization.downloadFilesScript': './downloadDriveFiles.py', 'geneSummarization.insertDataScript': './insertData.py', 'geneSummarization.credentials': './data/credentials.json', 'geneSummarization.token': './data/token.pickle', 'geneSummarization.aliases': './data/aliases.txt', 'geneSummarization.folderId': """ + json[ 'folderId'] + """, 'geneSummarization.id': """ + key + """ } """ # Create DB # Send request to Cromwell path = os.path.join(SUMMARIZATION_FILES_PATH, 'rpkm.wdl') files = { 'workflowSource': ('rpkm.wdl', open(path, 'rb')), 'workflowInputs': ('rpkm_inputs.json', inputs) } requests.post(CROMWELL_URL + '/api/workflows/v1', files=files) # Return ID for future accessing return BARUtils.success_exit(key), 200 else: return BARUtils.error_exit('Invalid API key')
def get(self, gene_id=""): """This end point retrieves publications from ThaleMine given an AGI ID""" gene_id = escape(gene_id) # Is data valid if not BARUtils.is_arabidopsis_gene_valid(gene_id): return BARUtils.error_exit("Invalid gene id"), 400 query = ( '<query name="" model="genomic" view="Gene.publications.firstAuthor Gene.publications.issue ' "Gene.publications.journal Gene.publications.pages Gene.publications.pubMedId Gene.publications.title " 'Gene.publications.volume Gene.publications.year" longDescription="" ' 'sortOrder="Gene.publications.firstAuthor asc"><constraint path="Gene.primaryIdentifier" op="=" value="{' '}"/></query> ') query = query.format(gene_id) # Now query the web service payload = {"format": "json", "query": query} resp = requests.post( "https://bar.utoronto.ca/thalemine/service/query/results", data=payload, headers=request_headers, ) return resp.json()
def test_is_poplar_gene_valid(self): # Valid gene result = BARUtils.is_poplar_gene_valid('Potri.019G123900.1') self.assertTrue(result) # Invalid gene result = BARUtils.is_poplar_gene_valid('abc') self.assertFalse(result)
def post(self): """Verify admin password""" if request.method == "POST": response_json = request.get_json() password = response_json["password"] if ApiManagerUtils.check_admin_pass(password): return BARUtils.success_exit(True) else: return BARUtils.success_exit(False)
def post(self): """Verify admin password """ if request.method == 'POST': response_json = request.get_json() user_key = response_json['key'] if ApiManagerUtils.check_admin_pass(user_key): return BARUtils.success_exit(True) else: return BARUtils.success_exit(False)
def get(self, table_id=""): """Returns the list of samples in the table with the given ID""" con = db.get_engine(bind="summarization") tbl = SummarizationGeneExpressionUtils.get_table_object(table_id) values = [] try: rows = con.execute(db.select([tbl.c.Sample]).distinct()) except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500 [values.append(row.Sample) for row in rows] return BARUtils.success_exit(values)
def test_is_integer(self): # Valid result result = BARUtils.is_integer('5') self.assertTrue(result) # Valid but too large result = BARUtils.is_integer('99999999999999') self.assertFalse(result) # Invalid result = BARUtils.is_integer('abc') self.assertFalse(result)
def test_is_integer(self): # Valid result result = BARUtils.is_integer("5") self.assertTrue(result) # Valid but too large result = BARUtils.is_integer("99999999999999") self.assertFalse(result) # Invalid result = BARUtils.is_integer("abc") self.assertFalse(result)
def test_is_arabidopsis_gene_valid(self): # Valid gene result = BARUtils.is_arabidopsis_gene_valid('At1g01010') self.assertTrue(result) result = BARUtils.is_arabidopsis_gene_valid('At1g01010.1') self.assertTrue(result) # Invalid gene result = BARUtils.is_arabidopsis_gene_valid('abc') self.assertFalse(result) result = BARUtils.is_arabidopsis_gene_valid('At1g01010.11') self.assertFalse(result)
def test_is_arabidopsis_gene_valid(self): # Valid gene result = BARUtils.is_arabidopsis_gene_valid("At1g01010") self.assertTrue(result) result = BARUtils.is_arabidopsis_gene_valid("At1g01010.1") self.assertTrue(result) # Invalid gene result = BARUtils.is_arabidopsis_gene_valid("abc") self.assertFalse(result) result = BARUtils.is_arabidopsis_gene_valid("At1g01010.11") self.assertFalse(result)
def get(self, gene_id=''): """ Endpoint returns annotated SNP poplar data in order of (to match A th API format): AA pos (zero-indexed), sample id, 'missense_variant','MODERATE', 'MISSENSE', codon/DNA base change, AA change (DH), pro length, gene ID, 'protein_coding', 'CODING', transcript id, biotype values with single quotes are fixed """ results_json = [] # Escape input gene_id = escape(gene_id) if BARUtils.is_poplar_gene_valid(gene_id) is False: return BARUtils.error_exit('Invalid gene id'), 400 try: rows = db.session.query(ProteinReference, SnpsToProtein, SnpsReference). \ select_from(ProteinReference). \ join(SnpsToProtein). \ join(SnpsReference). \ filter(ProteinReference.gene_identifier == gene_id).all() # BAR A Th API format is chr, AA pos (zero-indexed), sample id, 'missense_variant', # 'MODERATE', 'MISSENSE', codon/DNA base change, AA change (DH), # pro length, gene ID, 'protein_coding', 'CODING', transcript id, biotype for protein, snpsjoin, snpstbl in rows: itm_lst = [ snpstbl.chromosome, # snpstbl.chromosomal_loci, snpsjoin.aa_pos - 1, # zero index-ed snpstbl.sample_id, 'missense_variant', 'MODERATE', 'MISSENSE', str(snpsjoin.transcript_pos) + snpsjoin.ref_DNA + '>' + snpsjoin.alt_DNA, snpsjoin.ref_aa + snpsjoin.alt_aa, None, re.sub(r".\d$", '', protein.gene_identifier), 'protein_coding', 'CODING', protein.gene_identifier, None, ] results_json.append(itm_lst) except OperationalError: return BARUtils.error_exit('An internal error has occurred'), 500 # Return results if there are data if len(results_json) > 0: return BARUtils.success_exit(results_json) else: return BARUtils.error_exit( 'There are no data found for the given gene')
def get(self, table_id="", user_string=""): """Returns all genes that contain a given string as part of their name""" con = db.get_engine(bind="summarization") tbl = SummarizationGeneExpressionUtils.get_table_object(table_id) values = [] try: rows = con.execute( db.select([tbl.c.Gene]).where( tbl.c.Gene.contains(user_string)).distinct()) except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500 [values.append(row.Gene) for row in rows] return BARUtils.success_exit(values)
def get(self, table_id=""): """Returns the list of genes in the table with the given ID""" key = request.headers.get("x-api-key") if SummarizationGeneExpressionUtils.decrement_uses(key): con = db.get_engine(bind="summarization") tbl = SummarizationGeneExpressionUtils.get_table_object(table_id) values = [] try: rows = con.execute(db.select([tbl.c.Gene]).distinct()) except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500 [values.append(row.Gene) for row in rows] return BARUtils.success_exit(values) else: return BARUtils.error_exit("Invalid API key")
def get(self, table_id=''): """Drops the table with the given ID """ if request.remote_addr != '127.0.0.1': return BARUtils.error_exit('Forbidden'), 403 tbl = SummarizationGeneExpressionUtils.get_table_object(table_id) tbl.drop()
def post(self): if request.method == 'POST': response_json = request.get_json() df = pandas.DataFrame.from_records([response_json]) con = db.get_engine(bind='summarization') try: reqs = Requests() users = Users() row_req = reqs.query.filter_by(email=df.email[0]).first() row_users = users.query.filter_by(email=df.email[0]).first() if row_req is None and row_users is None: df.to_sql('requests', con, if_exists='append', index=False) else: return BARUtils.error_exit('E-mail already in use'), 409 except SQLAlchemyError: return BARUtils.error_exit('Internal server error'), 500
def post(self): """Returns a list of files stored in the user's folder """ if request.method == 'POST': api_key = request.headers.get('x-api-key') files = [] for file in os.walk(DATA_FOLDER + api_key): files.append(file[2]) return BARUtils.success_exit(files)
def get(self, file_id): """Returns a specific file stored in the user's folder""" if request.method == "GET": api_key = request.headers.get("x-api-key") filename = os.path.join(DATA_FOLDER, api_key, file_id) if os.path.isfile(filename): return send_file(filename) else: return BARUtils.error_exit("File not found"), 404
def post(self): """Returns a list of files stored in the user's folder""" if request.method == "POST": api_key = request.headers.get("x-api-key") files = [] if os.path.exists(os.path.join(DATA_FOLDER, api_key)): for file in os.walk(os.path.join(DATA_FOLDER, api_key)): files.append(file[2]) return BARUtils.success_exit(files)
def get(self, species="", database="", gene_id=""): """This end point returns RNA-Seq gene expression data""" # Variables species = escape(species) database = escape(database) gene_id = escape(gene_id) results = RNASeqUtils.get_data(species, database, gene_id) if results["success"]: # Return results if there are data if len(results["data"]) > 0: return BARUtils.success_exit(results["data"]) else: return BARUtils.error_exit( "There are no data found for the given gene") else: return BARUtils.error_exit(results["error"]), results["error_code"]
def post(self): """Validates a reCaptcha value using our secret token """ if request.method == 'POST': json = request.get_json() value = json['response'] key = os.environ.get('CAPTCHA_KEY') if key: ret = requests.post( 'https://www.google.com/recaptcha/api/siteverify', data={ 'secret': key, 'response': value }) return BARUtils.success_exit(ret.text) else: return BARUtils.error_exit( 'Forbidden: CAPTCHA key is not found'), 403
def post(self): """Validates a reCaptcha value using our secret token""" if request.method == "POST": json = request.get_json() value = json["response"] key = os.environ.get("CAPTCHA_KEY") if key: ret = requests.post( "https://www.google.com/recaptcha/api/siteverify", data={ "secret": key, "response": value }, ) return BARUtils.success_exit(ret.text) else: return BARUtils.error_exit( "Forbidden: CAPTCHA key is not found"), 403
def get(self, species='', database='', gene_id=''): """This end point returns RNA-Seq gene expression data""" # Variables species = escape(species) database = escape(database) gene_id = escape(gene_id) results = RNASeqUtils.get_data(species, database, gene_id) if results['success']: # Return results if there are data if len(results['data']) > 0: return BARUtils.success_exit(results['data']) else: return BARUtils.error_exit( 'There are no data found for the given gene') else: return BARUtils.error_exit(results['error']), results['error_code']
def post(self): """Verify if an API key provided by the user exists in the database""" if request.method == "POST": tbl = Users() json = request.get_json() key = json["key"] try: row = tbl.query.filter_by(api_key=key).first() except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500 if row is None: return BARUtils.error_exit("API key not found"), 404 else: if row.uses_left > 0: return BARUtils.success_exit(True) else: return BARUtils.error_exit("API key expired"), 401