Skip to content

Commit 622b605

Browse files
committed
fix: disable API fallback when local BLAST is enabled
1 parent 16a6b18 commit 622b605

File tree

3 files changed

+60
-41
lines changed

3 files changed

+60
-41
lines changed

graphgen/models/searcher/db/ncbi_searcher.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,18 @@ def _process_network_blast_result(blast_record, seq: str, threshold: float) -> O
393393
return None
394394

395395
# Try local BLAST first if enabled
396-
if self.use_local_blast and (accession := self._local_blast(seq, threshold)):
397-
logger.debug("Local BLAST found accession: %s", accession)
398-
return self.get_by_accession(accession)
396+
if self.use_local_blast:
397+
accession = self._local_blast(seq, threshold)
398+
if accession:
399+
logger.debug("Local BLAST found accession: %s", accession)
400+
return self.get_by_accession(accession)
401+
logger.info(
402+
"Local BLAST found no match for sequence. "
403+
"API fallback disabled when using local database."
404+
)
405+
return None
399406

400-
# Fall back to network BLAST
407+
# Fall back to network BLAST only if local BLAST is not enabled
401408
logger.debug("Falling back to NCBIWWW.qblast")
402409

403410
with NCBIWWW.qblast("blastn", "nr", seq, hitlist_size=1, expect=threshold) as result_handle:

graphgen/models/searcher/db/rnacentral_searcher.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,13 @@ def _extract_sequence(sequence: str) -> Optional[str]:
255255
if accession:
256256
logger.debug("Local BLAST found accession: %s", accession)
257257
return self.get_by_rna_id(accession)
258+
logger.info(
259+
"Local BLAST found no match for sequence. "
260+
"API fallback disabled when using local database."
261+
)
262+
return None
258263

259-
# Fall back to RNAcentral API if local BLAST didn't find result
264+
# Fall back to RNAcentral API only if local BLAST is not enabled
260265
logger.debug("Falling back to RNAcentral API.")
261266

262267
md5_hash = self._calculate_md5(seq)
@@ -272,11 +277,13 @@ def _extract_sequence(sequence: str) -> Optional[str]:
272277
if not results:
273278
logger.info("No exact match found in RNAcentral for sequence")
274279
return None
280+
275281
rna_id = results[0].get("rnacentral_id")
276-
if not rna_id:
277-
logger.error("No RNAcentral ID found in search results.")
278-
return None
279-
return self.get_by_rna_id(rna_id)
282+
if rna_id:
283+
return self.get_by_rna_id(rna_id)
284+
285+
logger.error("No RNAcentral ID found in search results.")
286+
return None
280287
except Exception as e:
281288
logger.error("Sequence search failed: %s", e)
282289
return None

graphgen/models/searcher/db/uniprot_searcher.py

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -124,47 +124,52 @@ def get_by_fasta(self, fasta_sequence: str, threshold: float) -> Optional[Dict]:
124124
logger.error("Empty FASTA sequence provided.")
125125
return None
126126

127-
accession = None
128127
if self.use_local_blast:
129128
accession = self._local_blast(seq, threshold)
130129
if accession:
131130
logger.debug("Local BLAST found accession: %s", accession)
131+
return self.get_by_accession(accession)
132+
logger.info(
133+
"Local BLAST found no match for sequence. "
134+
"API fallback disabled when using local database."
135+
)
136+
return None
132137

133-
if not accession:
134-
logger.debug("Falling back to NCBIWWW.qblast.")
138+
# Fall back to network BLAST only if local BLAST is not enabled
139+
logger.debug("Falling back to NCBIWWW.qblast.")
135140

136-
# UniProtKB/Swiss-Prot BLAST API
137-
try:
138-
logger.debug(
139-
"Performing BLAST searcher for the given sequence: %s", seq
140-
)
141-
result_handle = NCBIWWW.qblast(
142-
program="blastp",
143-
database="swissprot",
144-
sequence=seq,
145-
hitlist_size=1,
146-
expect=threshold,
147-
)
148-
blast_record = NCBIXML.read(result_handle)
149-
except RequestException:
150-
raise
151-
except Exception as e: # pylint: disable=broad-except
152-
logger.error("BLAST searcher failed: %s", e)
153-
return None
141+
# UniProtKB/Swiss-Prot BLAST API
142+
try:
143+
logger.debug(
144+
"Performing BLAST searcher for the given sequence: %s", seq
145+
)
146+
result_handle = NCBIWWW.qblast(
147+
program="blastp",
148+
database="swissprot",
149+
sequence=seq,
150+
hitlist_size=1,
151+
expect=threshold,
152+
)
153+
blast_record = NCBIXML.read(result_handle)
154+
except RequestException:
155+
raise
156+
except Exception as e: # pylint: disable=broad-except
157+
logger.error("BLAST searcher failed: %s", e)
158+
return None
154159

155-
if not blast_record.alignments:
156-
logger.info("No BLAST hits found for the given sequence.")
157-
return None
160+
if not blast_record.alignments:
161+
logger.info("No BLAST hits found for the given sequence.")
162+
return None
158163

159-
best_alignment = blast_record.alignments[0]
160-
best_hsp = best_alignment.hsps[0]
161-
if best_hsp.expect > threshold:
162-
logger.info("No BLAST hits below the threshold E-value.")
163-
return None
164-
hit_id = best_alignment.hit_id
164+
best_alignment = blast_record.alignments[0]
165+
best_hsp = best_alignment.hsps[0]
166+
if best_hsp.expect > threshold:
167+
logger.info("No BLAST hits below the threshold E-value.")
168+
return None
165169

166-
# like sp|P01308.1|INS_HUMAN
167-
accession = hit_id.split("|")[1].split(".")[0] if "|" in hit_id else hit_id
170+
# like sp|P01308.1|INS_HUMAN
171+
hit_id = best_alignment.hit_id
172+
accession = hit_id.split("|")[1].split(".")[0] if "|" in hit_id else hit_id
168173
return self.get_by_accession(accession)
169174

170175
def _local_blast(self, seq: str, threshold: float) -> Optional[str]:

0 commit comments

Comments
 (0)