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
34 changes: 23 additions & 11 deletions api/models/interactions_vincent_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,34 @@ class TagLookupTable(db.Model):
__tablename__ = "tag_lookup_table"

tag_name: db.Mapped[str] = db.mapped_column(db.String(20), nullable=False, primary_key=True)
tag_group: db.Mapped[str] = db.mapped_column(Enum("Gene", "Experiment", "Condition", "Misc"), nullable=False, primary_key=False)
tag_group: db.Mapped[str] = db.mapped_column(
Enum("Gene", "Experiment", "Condition", "Misc"), nullable=False, primary_key=False
)


class ExternalSource(db.Model):
__bind_key__ = "interactions_vincent_v2"
__tablename__ = "external_source"

source_id: db.Mapped[int] = db.mapped_column(db.Integer, nullable=False, comment="surrogate key", primary_key=True)
source_name: db.Mapped[str] = db.mapped_column(db.String(500), nullable=False, comment="name of the source, can be a pubmed identifier like “PMIDXXXXXXX” or “Asher’s sql dump”", primary_key=False)
comments: db.Mapped[str] = db.mapped_column(TEXT(), nullable=False, comment="Comments regarding the source", primary_key=False)
date_uploaded: db.Mapped[datetime] = db.mapped_column(db.Date(), nullable=False, comment="When it was uploaded to database", primary_key=False)
url: db.Mapped[str] = db.mapped_column(db.String(350), nullable=True, comment="URL if available to paper/source (does not have to be a DOI, can be a link to a databases’ source)", primary_key=False)
source_name: db.Mapped[str] = db.mapped_column(
db.String(500),
nullable=False,
comment="name of the source, can be a pubmed identifier like “PMIDXXXXXXX” or “Asher’s sql dump”",
primary_key=False,
)
comments: db.Mapped[str] = db.mapped_column(
TEXT(), nullable=False, comment="Comments regarding the source", primary_key=False
)
date_uploaded: db.Mapped[datetime] = db.mapped_column(
db.Date(), nullable=False, comment="When it was uploaded to database", primary_key=False
)
url: db.Mapped[str] = db.mapped_column(
db.String(350),
nullable=True,
comment="URL if available to paper/source (does not have to be a DOI, can be a link to a databases’ source)",
primary_key=False,
)
image_url: db.Mapped[str] = db.mapped_column(db.String(300), nullable=True, primary_key=False)
grn_title: db.Mapped[str] = db.mapped_column(db.String(200), nullable=True, primary_key=False)
cyjs_layout: db.Mapped[str] = db.mapped_column(db.String(1000), nullable=True, primary_key=False)
Expand All @@ -59,12 +75,8 @@ class SourceTagJoinTable(db.Model):
__tablename__ = "source_tag_join_table"

source_id: db.Mapped[int] = db.mapped_column(
db.Integer(),
db.ForeignKey("external_source.source_id"),
primary_key=True
db.Integer(), db.ForeignKey("external_source.source_id"), primary_key=True
)
tag_name: db.Mapped[str] = db.mapped_column(
db.String(20),
db.ForeignKey("tag_lookup_table.tag_name"),
primary_key=True
db.String(20), db.ForeignKey("tag_lookup_table.tag_name"), primary_key=True
)
2 changes: 1 addition & 1 deletion api/resources/efp_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def get(self, species=""):

# This will only work on the BAR
if os.environ.get("BAR"):
if species in ["arabidopsis", "arachis", "cannabis", "maize", "rice", "sorghum", "soybean"]:
if species in ["arabidopsis", "arachis", "cannabis", "grape", "maize", "rice", "sorghum", "soybean"]:
efp_base_path = "/var/www/html/efp_" + species + "/data"
else:
return BARUtils.error_exit("Invalid species.")
Expand Down
63 changes: 21 additions & 42 deletions api/resources/interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,13 +314,12 @@ def get(self, paper_id=""):
try:
interactions_database = PostInteractions
itnsjoin_database = PostInteractionsSourceMiJoin
query = db.select(
interactions_database,
itnsjoin_database
).select_from(interactions_database).join(
itnsjoin_database,
interactions_database.interaction_id == itnsjoin_database.interaction_id
).where(itnsjoin_database.source_id == paper_id)
query = (
db.select(interactions_database, itnsjoin_database)
.select_from(interactions_database)
.join(itnsjoin_database, interactions_database.interaction_id == itnsjoin_database.interaction_id)
.where(itnsjoin_database.source_id == paper_id)
)
rows = db.session.execute(query).all()
for i, m in rows:
result.append(
Expand Down Expand Up @@ -382,9 +381,7 @@ def get(self, tag=""):
# Step 1: Get source_ids that contain the searched tag

matching_source_ids = []
query_source = db.select(src_tag_join_database.source_id).where(
src_tag_join_database.tag_name == tag
)
query_source = db.select(src_tag_join_database.source_id).where(src_tag_join_database.tag_name == tag)
rows_source = db.session.execute(query_source).all()
matching_source_ids = [row[0] for row in rows_source]

Expand All @@ -393,11 +390,7 @@ def get(self, tag=""):

# Step 2: Get all tags for those sources
query = (
db.select(
ext_src_database,
src_tag_join_database.tag_name,
tag_lkup_database.tag_group
)
db.select(ext_src_database, src_tag_join_database.tag_name, tag_lkup_database.tag_group)
.join(src_tag_join_database, ext_src_database.source_id == src_tag_join_database.source_id)
.join(tag_lkup_database, src_tag_join_database.tag_name == tag_lkup_database.tag_name)
.where(ext_src_database.source_id.in_(matching_source_ids)) # Keep all tags for matched sources
Expand Down Expand Up @@ -425,7 +418,7 @@ def get(self, tag=""):
"image_url": ex.image_url,
"grn_title": ex.grn_title,
"cyjs_layout": ex.cyjs_layout,
"tag": "|".join(src_tag_match[ex.source_id])
"tag": "|".join(src_tag_match[ex.source_id]),
}
result.append(one_source[source_id])

Expand Down Expand Up @@ -494,7 +487,7 @@ def get(self, number=""):
"url": row.url,
"image_url": row.image_url,
"grn_title": row.grn_title,
"cyjs_layout": row.cyjs_layout
"cyjs_layout": row.cyjs_layout,
}
)

Expand Down Expand Up @@ -530,7 +523,7 @@ def get(self, stringAGI=""):
es.comments,
es.cyjs_layout,
stjt.tag_name,
tlt.tag_group
tlt.tag_group,
)
.join(i_s_mi_join_table, i_s_mi_join_table.source_id == es.source_id)
.join(i, i.interaction_id == i_s_mi_join_table.interaction_id)
Expand All @@ -557,20 +550,14 @@ def get(self, stringAGI=""):
"source_name": row.source_name,
"comments": row.comments,
"cyjs_layout": row.cyjs_layout,
"tags": []
"tags": [],
}

tag_entry = f"{row.tag_name}:{row.tag_group}"
if tag_entry not in result_dict[source_id]["tags"]: # DISTINCT
result_dict[source_id]["tags"].append(tag_entry)

result = [
{
**data,
"tags": "|".join(data["tags"]) # overwrites tags
}
for data in result_dict.values()
]
result = [{**data, "tags": "|".join(data["tags"])} for data in result_dict.values()] # overwrites tags

if len(result) == 0:
return BARUtils.error_exit("Invalid AGI"), 400
Expand Down Expand Up @@ -603,7 +590,7 @@ def get(self, AGI_1="", AGI_2=""):
es.comments,
es.cyjs_layout,
stjt.tag_name,
tlt.tag_group
tlt.tag_group,
)
.join(i_s_mi_join_table, i_s_mi_join_table.source_id == es.source_id)
.join(i, i.interaction_id == i_s_mi_join_table.interaction_id)
Expand All @@ -630,18 +617,14 @@ def get(self, AGI_1="", AGI_2=""):
"source_name": row.source_name,
"comments": row.comments,
"cyjs_layout": row.cyjs_layout,
"tags": set()
"tags": set(),
}

result_dict[source_id]["tags"].add(f"{row.tag_name}:{row.tag_group}") # ensures uniqueness automatically with `set`
result_dict[source_id]["tags"].add(
f"{row.tag_name}:{row.tag_group}"
) # ensures uniqueness automatically with `set`

result = [
{
**data,
"tags": "|".join(sorted(data["tags"]))
}
for data in result_dict.values()
]
result = [{**data, "tags": "|".join(sorted(data["tags"]))} for data in result_dict.values()]

if len(result) == 0:
return BARUtils.error_exit("Both AGI invalid"), 400
Expand All @@ -664,11 +647,7 @@ def get(self):
stjt = SourceTagJoinTable
tlt = TagLookupTable
query = (
db.select(
es,
stjt.tag_name,
tlt.tag_group
)
db.select(es, stjt.tag_name, tlt.tag_group)
.join(stjt, es.source_id == stjt.source_id)
.join(tlt, stjt.tag_name == tlt.tag_name)
)
Expand All @@ -695,7 +674,7 @@ def get(self):
"image_url": ex.image_url,
"grn_title": ex.grn_title,
"cyjs_layout": ex.cyjs_layout,
"tag": "|".join(src_tag_match[ex.source_id])
"tag": "|".join(src_tag_match[ex.source_id]),
}
result.append(one_source[source_id])

Expand Down
4 changes: 3 additions & 1 deletion api/utils/mfinder_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,9 @@ def get_gene_id_hash_map(input):
if item[1] not in hash_of_ids.values():
hash_of_ids[iter] = item[1]
iter += 1
return_str += f"{MfinderUtils.find_key(hash_of_ids, item[0])} {MfinderUtils.find_key(hash_of_ids, item[1])} 1\n"
return_str += (
f"{MfinderUtils.find_key(hash_of_ids, item[0])} {MfinderUtils.find_key(hash_of_ids, item[1])} 1\n"
)

return hash_of_ids, return_str

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jsonschema==4.25.1
jsonschema-specifications==2025.9.1
limits==5.5.0
markdown-it-py==4.0.0
MarkupSafe==3.0.2
MarkupSafe==3.0.3
marshmallow==4.0.1
mccabe==0.7.0
mdurl==0.1.2
Expand Down
58 changes: 14 additions & 44 deletions tests/resources/test_interactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,26 +210,20 @@ def test_single_itrn(self):
"pearson_correlation_coeff": None,
"entity_1": "AT4G25470",
"entity_2": "AT5G50720",
"interaction_type_id": 1
"interaction_type_id": 1,
}
]
],
}
self.assertEqual(response.json, expected)

# Input not a number
response = self.app_client.get("/interactions/single_interaction/g")
expected = {
"wasSuccessful": False,
"error": "ID given was not a number!"
}
expected = {"wasSuccessful": False, "error": "ID given was not a number!"}
self.assertEqual(response.json, expected)

# Not a valid interaction ID
response = self.app_client.get("/interactions/single_interaction/3")
expected = {
"wasSuccessful": False,
"error": "Invalid interaction ID"
}
expected = {"wasSuccessful": False, "error": "Invalid interaction ID"}
self.assertEqual(response.json, expected)

def test_itrn_by_ref(self):
Expand All @@ -245,18 +239,12 @@ def test_itrn_by_ref(self):

# Input not a number
response = self.app_client.get("/interactions/interactions_by_ref/k")
expected = {
"wasSuccessful": False,
"error": "ID given was not a number!"
}
expected = {"wasSuccessful": False, "error": "ID given was not a number!"}
self.assertEqual(response.json, expected)

# Not a valid paper ID
response = self.app_client.get("/interactions/interactions_by_ref/1")
expected = {
"wasSuccessful": False,
"error": "Invalid paper ID"
}
expected = {"wasSuccessful": False, "error": "Invalid paper ID"}
self.assertEqual(response.json, expected)

def test_all_tags(self):
Expand All @@ -283,10 +271,7 @@ def test_search_by_tag(self):

# Invalid tag name
response = self.app_client.get("/interactions/search_by_tag/p")
expected = {
"wasSuccessful": False,
"error": "Invalid tag name"
}
expected = {"wasSuccessful": False, "error": "Invalid tag name"}
self.assertEqual(response.json, expected)

def test_get_all_papers(self):
Expand Down Expand Up @@ -318,34 +303,25 @@ def test_get_paper(self):
"url": "www.ncbi.nlm.nih.gov/pubmed/25736223",
"image_url": "https://bar.utoronto.ca/GRN_Images/25736223%232.jpg",
"grn_title": "Park et al.(The Plant Journal, 2015) CBF Regulon Low Temperature Network",
"cyjs_layout": "{\"name\": \"breadthfirst\", \"animate\" : \"true\"}"
"cyjs_layout": '{"name": "breadthfirst", "animate" : "true"}',
}
]
],
}
self.assertEqual(response.json, expected)

# Input not an integer, a string
response = self.app_client.get("/interactions/get_paper/p")
expected = {
"wasSuccessful": False,
"error": "Input number is not an integer!"
}
expected = {"wasSuccessful": False, "error": "Input number is not an integer!"}
self.assertEqual(response.json, expected)

# Input not an integer, a float
response = self.app_client.get("/interactions/get_paper/2.2")
expected = {
"wasSuccessful": False,
"error": "Input number is not an integer!"
}
expected = {"wasSuccessful": False, "error": "Input number is not an integer!"}
self.assertEqual(response.json, expected)

# Invalid source ID
response = self.app_client.get("/interactions/get_paper/3")
expected = {
"wasSuccessful": False,
"error": "Invalid source ID"
}
expected = {"wasSuccessful": False, "error": "Invalid source ID"}
self.assertEqual(response.json, expected)

def test_get_paper_by_agi(self):
Expand All @@ -361,10 +337,7 @@ def test_get_paper_by_agi(self):

# Invalid AGI
response = self.app_client.get("/interactions/get_paper_by_agi/AT1G00000")
expected = {
"wasSuccessful": False,
"error": "Invalid AGI"
}
expected = {"wasSuccessful": False, "error": "Invalid AGI"}
self.assertEqual(response.json, expected)

def test_get_paper_by_agi_pair(self):
Expand All @@ -380,10 +353,7 @@ def test_get_paper_by_agi_pair(self):

# Both AGI invalid
response = self.app_client.get("/interactions/get_paper_by_agi_pair/AT1G00000/AT2G00000")
expected = {
"wasSuccessful": False,
"error": "Both AGI invalid"
}
expected = {"wasSuccessful": False, "error": "Both AGI invalid"}
self.assertEqual(response.json, expected)

def test_get_all_grns(self):
Expand Down
Loading