Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def create_app():
tomato_seq_db.init_app(bar_app)
single_cell_db.init_app(bar_app)
summarization_db.init_app(bar_app)
rice_interactions_db.init_app(bar_app)

# Initialize the cache
cache.init_app(bar_app)
Expand All @@ -104,6 +105,8 @@ def create_app():
from api.resources.snps import snps
from api.resources.sequence import sequence
from api.resources.gene_annotation import gene_annotation
from api.resources.interactions import itrns
from api.resources.gene_localizations import loc

bar_api.add_namespace(gene_information)
bar_api.add_namespace(rnaseq_gene_expression)
Expand All @@ -114,6 +117,8 @@ def create_app():
bar_api.add_namespace(snps)
bar_api.add_namespace(sequence)
bar_api.add_namespace(gene_annotation)
bar_api.add_namespace(itrns)
bar_api.add_namespace(loc)
bar_api.init_app(bar_app)
return bar_app

Expand All @@ -130,6 +135,7 @@ def create_app():
tomato_seq_db = SQLAlchemy(metadata=MetaData())
single_cell_db = SQLAlchemy(metadata=MetaData())
summarization_db = SQLAlchemy(metadata=MetaData())
rice_interactions_db = SQLAlchemy(metadata=MetaData())

# Initialize Redis
cache = Cache(
Expand Down
52 changes: 52 additions & 0 deletions api/models/rice_interactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from api import rice_interactions_db as db


class Interactions(db.Model):
__bind_key__ = "rice_interactions"
__tablename__ = "interactions"
Protein1 = db.Column(db.String(14), primary_key=True)
Protein2 = db.Column(db.String(14), primary_key=True)
S_cerevisiae = db.Column(db.SmallInteger(), primary_key=False)
S_pombe = db.Column(db.SmallInteger(), primary_key=False)
Worm = db.Column(db.SmallInteger(), primary_key=False)
Fly = db.Column(db.SmallInteger(), primary_key=False)
Human = db.Column(db.SmallInteger(), primary_key=False)
Mouse = db.Column(db.SmallInteger(), primary_key=False)
Total_hits = db.Column(db.SmallInteger(), primary_key=False)
Num_species = db.Column(db.SmallInteger(), primary_key=False)
Quality = db.Column(db.SmallInteger(), primary_key=False)
Index = db.Column(db.SmallInteger(), primary_key=False)
Pcc = db.Column(db.Float, primary_key=False)
Bind_id = db.Column(db.SmallInteger(), primary_key=False)


class Rice_mPLoc(db.Model):
__bind_key__ = "rice_interactions"
__tablename__ = "Rice_mPLoc"
gene_id = db.Column(db.String(20), primary_key=True)
alias = db.Column(db.String(), primary_key=False)
lab_description = db.Column(db.String(), primary_key=False)
gfp = db.Column(db.String(), primary_key=False)
mass_spec = db.Column(db.String(), primary_key=False)
swissprot = db.Column(db.String(), primary_key=False)
amigo = db.Column(db.String(), primary_key=False)
annotation = db.Column(db.String(), primary_key=False)
pred_ipsort = db.Column(db.String(), primary_key=False)
pred_mitopred = db.Column(db.String(), primary_key=False)
pred_mitopred2 = db.Column(db.String(), primary_key=False)
pred_predator = db.Column(db.String(), primary_key=False)
pred_peroxp = db.Column(db.String(), primary_key=False)
pred_subloc = db.Column(db.String(), primary_key=False)
pred_targetp = db.Column(db.String(), primary_key=False)
pred_wolfpsort = db.Column(db.String(), primary_key=False)
pred_multiloc = db.Column(db.String(), primary_key=False)
pred_loctree = db.Column(db.String(), primary_key=False)
pred_mPLoc = db.Column(db.String(), primary_key=False)


class RGI_annotation(db.Model):
__bind_key__ = "rice_interactions"
__tablename__ = "RGI_annotation"
loc = db.Column(db.String(14), primary_key=True)
annotation = db.Column(db.String(), primary_key=True)
date = db.Column(db.Date(), primary_key=True)
118 changes: 118 additions & 0 deletions api/resources/gene_localizations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"""
Date: Nov 2021
Author: Vincent Lau
Localizations (for various species and their respective genes) endpoint
"""

from flask_restx import Namespace, Resource, fields
from flask import request
from api.models.rice_interactions import Rice_mPLoc as rice_loc_db
from markupsafe import escape
from sqlalchemy.exc import OperationalError
from api.utils.bar_utils import BARUtils
from marshmallow import Schema, ValidationError, fields as marshmallow_fields

loc = Namespace("Localizations", description="Sub-cellular gene localzation endpoint", path="/loc")


# Validation is done in a different way to keep things simple
class GeneLocationsSchema(Schema):
species = marshmallow_fields.String(required=True)
genes = marshmallow_fields.List(cls_or_instance=marshmallow_fields.String)


@loc.route("/<species>/<query_gene>")
class Localizations(Resource):
@loc.param("species", _in="path", default="rice")
@loc.param("query_gene", _in="path", default="LOC_Os01g52560.1")
def get(self, species="", query_gene=""):
"""
Returns the protein-protein interactions for a particular query gene
Supported species: 'rice'
"""

species = escape(species.lower())
query_gene = escape(query_gene)
if species == "rice" and BARUtils.is_rice_gene_valid(query_gene, True):
try:
rows = rice_loc_db.query.filter_by(gene_id=query_gene).all()
if len(rows) == 0:
return (
BARUtils.error_exit(
"There are no data found for the given gene"
),
400,
)
else:
print(rows)
return {
"status": "success",
"result": {
"gene": rows[0].gene_id,
"predicted_location": rows[0].pred_mPLoc,
}
}
except OperationalError:
return BARUtils.error_exit("An internal error has occurred"), 500
else:
return BARUtils.error_exit("Invalid species or gene ID"), 400


loc_post_ex = loc.model(
"GeneIsoforms",
{
"species": fields.String(required=True, example="rice"),
"genes": fields.List(
required=True,
example=["LOC_Os01g01080.1", "LOC_Os01g52560.1"],
cls_or_instance=fields.String,
),
},
)


@loc.route("/")
class LocalizationsPost(Resource):
@loc.expect(loc_post_ex)
def post(self):
"""
Returns the protein-protein interactions for a particular multiple genes
Supported species: 'rice'
"""

json_data = request.get_json()
data = {}

# Validate json
try:
json_data = GeneLocationsSchema().load(json_data)
except ValidationError as err:
return BARUtils.error_exit(err.messages), 400

genes = json_data["genes"]
species = json_data["species"].lower()

if species == "rice":
for gene in genes:
if not BARUtils.is_rice_gene_valid(gene, True):
return BARUtils.error_exit("Invalid gene id"), 400

try:
rows = rice_loc_db.query.filter(rice_loc_db.gene_id.in_(genes)).all()
except OperationalError:
return BARUtils.error_exit("An internal error has occurred."), 500
else:
return BARUtils.error_exit("Invalid species"), 400

if len(rows) > 0:
for row in rows:
if row.gene_id in data:
data[row.gene_id].append(row.pred_mPLoc)
else:
data[row.gene_id] = []
data[row.gene_id].append(row.pred_mPLoc)

return BARUtils.success_exit(data)

else:
return BARUtils.error_exit("No data for the given species/genes"), 400
60 changes: 60 additions & 0 deletions api/resources/interactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Date: Nov 2021
Author: Vincent Lau
Interactions (Protein-Protein, Protein-DNA, etc.) endpoint
"""

from flask_restx import Namespace, Resource
from api.models.rice_interactions import Interactions as rice_interactions
from markupsafe import escape
from sqlalchemy.exc import OperationalError
from sqlalchemy import or_
from api.utils.bar_utils import BARUtils

itrns = Namespace("Interactions", description="Interactions (protein-protein, protein-DNA, etc) endpoint", path="/interactions")


@itrns.route("/<species>/<query_gene>")
class Interactions(Resource):
@itrns.param("species", _in="path", default="rice")
@itrns.param("query_gene", _in="path", default="LOC_Os01g52560")
def get(self, species="", query_gene=""):
"""
Returns the protein-protein interactions for a particular query gene
Supported species: 'rice'
"""

species = escape(species.lower())
query_gene = escape(query_gene)
if species == "rice" and BARUtils.is_rice_gene_valid(query_gene):
try:
rows = rice_interactions.query.filter(or_(rice_interactions.Protein1 == query_gene, rice_interactions.Protein2 == query_gene)).all()
if len(rows) == 0:
return (
BARUtils.error_exit(
"There are no data found for the given gene"
),
400,
)
else:
print(rows)
# res = []
res = [
{
"protein_1": i.Protein1,
"protein_2": i.Protein2,
"total_hits": i.Total_hits,
"Num_species": i.Num_species,
"Quality": i.Quality,
"pcc": i.Pcc,
}
for i in rows
]
return {
"status": "success",
"result": res
}
except OperationalError:
return BARUtils.error_exit("An internal error has occurred"), 500
else:
return BARUtils.error_exit("Invalid species or gene ID"), 400
14 changes: 14 additions & 0 deletions api/utils/bar_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ def is_poplar_gene_valid(gene):
else:
return False

@staticmethod
def is_rice_gene_valid(gene, isoform_id=False):
"""This function verifies if rice gene is valid
:param gene:
:param isoform_id: True if you want to verifiy isoform ID
:return: True if valid
"""
if isoform_id and re.search(r"^LOC_Os\d{2}g\d{5}\.\d{1,2}$", gene, re.I):
return True
elif isoform_id is False and re.search(r"^LOC_Os\d{2}g\d{5}$", gene, re.I):
return True
else:
return False

@staticmethod
def is_tomato_gene_valid(gene, isoform_id=False):
"""This function verifies if ITAG Solyc gene is valid
Expand Down
3 changes: 2 additions & 1 deletion config/BAR_API.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ SQLALCHEMY_BINDS = {
'tomato_nssnp' : 'mysql://root:root@localhost/tomato_nssnp',
'eplant_poplar' : 'mysql://root:root@localhost/eplant_poplar',
'eplant_tomato' : 'mysql://root:root@localhost/eplant_tomato',
'tomato_sequence' : 'mysql://root:root@localhost/tomato_sequence'
'tomato_sequence' : 'mysql://root:root@localhost/tomato_sequence',
'rice_interactions': 'mysql://root:root@localhost/rice_interactions'
}

## API Manager variables
Expand Down
Loading