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 get(self, table_id, sample, gene): """Returns the value for a given gene and sample. If no sample is given returns all values for that gene""" if not BARUtils.is_arabidopsis_gene_valid(gene): return BARUtils.success_exit("Invalid gene ID"), 400 else: 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) if sample == "": values = {} try: rows = con.execute( tbl.select(tbl.c.Value).where(tbl.c.Gene == gene)) except SQLAlchemyError: return BARUtils.error_exit( "Internal server error"), 500 for row in rows: values.update({str(row.Sample): float(row.Value)}) else: values = [] try: rows = con.execute( tbl.select(tbl.c.Value).where( tbl.c.Sample == sample).where( tbl.c.Gene == gene)) except SQLAlchemyError: return BARUtils.error_exit( "Internal server error"), 500 [values.append(row.Value) for row in rows] return BARUtils.success_exit(values) else: return BARUtils.error_exit("Invalid API key")
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 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): """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 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 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): """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): """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 get(self, species='', gene_id=''): """This end point provides gene alias given a gene ID.""" aliases = [] # Escape input species = escape(species) gene_id = escape(gene_id) if species == 'arabidopsis': if BARUtils.is_arabidopsis_gene_valid(gene_id): try: rows = AgiAlias.query.filter_by(agi=gene_id).all() except OperationalError: return BARUtils.error_exit( 'An internal error has occurred'), 500 [aliases.append(row.alias) for row in rows] else: return BARUtils.error_exit('Invalid gene id'), 400 else: return BARUtils.error_exit('No data for the given species') # Return results if there are data if len(aliases) > 0: return BARUtils.success_exit(aliases) else: return BARUtils.error_exit( 'There are no data found for the given gene')
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): """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 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='', gene_id=''): """This end point provides gene isoforms given a gene ID. Only genes/isoforms with pdb structures are returned""" gene_isoforms = [] # Escape input species = escape(species) gene_id = escape(gene_id) if species == 'arabidopsis': if BARUtils.is_arabidopsis_gene_valid(gene_id): try: rows = isoforms.query.filter_by(gene=gene_id).all() except OperationalError: return BARUtils.error_exit( 'An internal error has occurred'), 500 [gene_isoforms.append(row.isoform) for row in rows] # Found isoforms if len(gene_isoforms) > 0: return BARUtils.success_exit(gene_isoforms) else: return BARUtils.error_exit('Invalid gene id'), 400 elif species == 'poplar': if BARUtils.is_poplar_gene_valid(gene_id): # Path is the location of poplar pdb file if os.environ.get('BAR'): path = '/DATA/ePlants_Data/eplant_poplar/protein_structures/' else: path = os.getcwd( ) + '/data/gene_information/gene_isoforms/' path += gene_id + '.pdb' if os.path.exists(path) and os.path.isfile(path): return BARUtils.success_exit(gene_id) else: return BARUtils.error_exit('Invalid gene id'), 400 else: return BARUtils.error_exit('No data for the given species') return BARUtils.error_exit( 'There are no data found for the given gene')
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 # Todo: I guess this is work in progress. if row is None: return BARUtils.success_exit('Do data found') else: if row.uses_left > 0: 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 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 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) if ApiManagerUtils.send_email(): return BARUtils.success_exit("Data added, email sent") else: return BARUtils.success_exit( "Data added, email failed") else: return BARUtils.error_exit("E-mail already in use"), 409 except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500
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, species="", gene_id=""): """This end point provides gene isoforms given a gene ID. Only genes/isoforms with pdb structures are returned""" gene_isoforms = [] # Escape input species = escape(species) gene_id = escape(gene_id) # Set the database and check if genes are valid if species == "arabidopsis": database = eplant2_isoforms() if not BARUtils.is_arabidopsis_gene_valid(gene_id): return BARUtils.error_exit("Invalid gene id"), 400 elif species == "poplar": database = eplant_poplar_isoforms if not BARUtils.is_poplar_gene_valid(gene_id): return BARUtils.error_exit("Invalid gene id"), 400 # Format the gene first gene_id = BARUtils.format_poplar(gene_id) elif species == "tomato": database = eplant_tomato_isoforms if not BARUtils.is_tomato_gene_valid(gene_id, False): return BARUtils.error_exit("Invalid gene id"), 400 else: return BARUtils.error_exit("No data for the given species") # Now get the data try: rows = database.query.filter_by(gene=gene_id).all() except OperationalError: return BARUtils.error_exit("An internal error has occurred"), 500 [gene_isoforms.append(row.isoform) for row in rows] # Found isoforms if len(gene_isoforms) > 0: return BARUtils.success_exit(gene_isoforms) else: return BARUtils.error_exit( "There are no data found for the given gene")
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): """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
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): """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") species = json["species"] email = json["email"] aliases = json["aliases"] gtf = GTF_DICT[species] if SummarizationGeneExpressionUtils.decrement_uses(key): inputs = { "geneSummarization.summarizeGenesScript": "./summarize_genes.R", "geneSummarization.downloadFilesScript": "./downloadDriveFiles.py", "geneSummarization.chrsScript": "./chrs.py", "geneSummarization.folderId": json["folderId"], "geneSummarization.credentials": "./data/credentials.json", "geneSummarization.token": "./data/token.pickle", "geneSummarization.species": species, "geneSummarization.gtf": gtf, "geneSummarization.aliases": str(aliases), "geneSummarization.id": key, "geneSummarization.pairedEndScript": "./paired.sh", "geneSummarization.insertDataScript": "./insertData.py", "geneSummarization.barEmailScript": "./bar_email.py", "geneSummarization.errorEmailScript": "./error_email.py", "geneSummarization.email": email, } # Send request to Cromwell path = os.path.join(SUMMARIZATION_FILES_PATH, "rpkm.wdl") file = tempfile.TemporaryFile(mode="w+") file.write(jsonlib.dumps(inputs)) file.seek(0) files = { "workflowSource": ("rpkm.wdl", open(path, "rb")), "workflowInputs": ("rpkm_inputs.json", file.read()), } requests.post(CROMWELL_URL + "/api/workflows/v1", files=files) file.close() # Return ID for future accessing return BARUtils.success_exit(key), 200 else: return BARUtils.error_exit("Invalid API key")
def post(self): """Delete a request from the database""" if request.method == "POST": response_json = request.get_json() password = response_json["password"] if ApiManagerUtils.check_admin_pass(password): response_json = request.get_json() table = Requests() try: el = table.query.filter_by( email=response_json["email"]).one() except SQLAlchemyError: return BARUtils.error_exit("Internal server error"), 500 db.session.delete(el) db.session.commit() # table.query.filter_by(email=response_json['email']).delete() return BARUtils.success_exit(True) else: return BARUtils.error_exit("Forbidden"), 403
def post(self): """This function adds a CSV's data to the database. This is only called by the Cromwell server after receiving the user's file.""" if request.remote_addr != "127.0.0.1": return BARUtils.error_exit("Forbidden"), 403 if request.method == "POST": key = request.headers.get("X-Api-Key") if SummarizationGeneExpressionUtils.decrement_uses(key): csv = request.get_json()["csv"] db_id = request.get_json()["uid"] df = pandas.read_csv(csv) db_id = db_id.split(".")[0] df = df.melt(id_vars=["Gene"], var_name="Sample", value_name="Value") db_id = db_id.split("/")[len(db_id.split("/")) - 1] con = db.get_engine(bind="summarization") df.to_sql(db_id, con, if_exists="append", index=True) return BARUtils.success_exit("Success") else: return BARUtils.error_exit("Invalid API key")