Updated BIGSdb API to be more tolerant towards failures
This commit is contained in:
parent
d4f890a150
commit
463e320386
@ -9,5 +9,5 @@ class Allele:
|
|||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class MLSTProfile:
|
class MLSTProfile:
|
||||||
alleles: Mapping[str, Sequence[Allele]]
|
alleles: Mapping[str, Sequence[Allele]]
|
||||||
sequence_type: int
|
sequence_type: str
|
||||||
clonal_complex: str
|
clonal_complex: str
|
16
src/automlst/engine/exceptions/database.py
Normal file
16
src/automlst/engine/exceptions/database.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from typing import Union
|
||||||
|
|
||||||
|
class BIGSDbDatabaseAPIException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class NoBIGSdbExactMatchesException(BIGSDbDatabaseAPIException):
|
||||||
|
def __init__(self, database_name: str, database_schema_id: int, *args):
|
||||||
|
super().__init__(f"No exact match found with schema with ID {database_schema_id} in the database \"{database_name}\".", *args)
|
||||||
|
|
||||||
|
class NoSuchBIGSdbDatabaseException(BIGSDbDatabaseAPIException):
|
||||||
|
def __init__(self, database_name: str, *args):
|
||||||
|
super().__init__(f"No database \"{database_name}\" found.", *args)
|
||||||
|
|
||||||
|
class NoSuchBigSdbSchemaException(BIGSDbDatabaseAPIException):
|
||||||
|
def __init__(self, database_name: str, database_schema_id: int, *args):
|
||||||
|
super().__init__(f"No schema with ID {database_schema_id} in \"{database_name}\" found.", *args)
|
@ -6,6 +6,7 @@ from aiohttp import ClientSession, ClientTimeout
|
|||||||
|
|
||||||
from automlst.engine.data.genomics import NamedString
|
from automlst.engine.data.genomics import NamedString
|
||||||
from automlst.engine.data.mlst import Allele, MLSTProfile
|
from automlst.engine.data.mlst import Allele, MLSTProfile
|
||||||
|
from automlst.engine.exceptions.database import NoBIGSdbExactMatchesException, NoSuchBIGSdbDatabaseException
|
||||||
|
|
||||||
class BIGSdbMLSTProfiler(AbstractAsyncContextManager):
|
class BIGSdbMLSTProfiler(AbstractAsyncContextManager):
|
||||||
|
|
||||||
@ -25,12 +26,10 @@ class BIGSdbMLSTProfiler(AbstractAsyncContextManager):
|
|||||||
"sequence": sequence_string
|
"sequence": sequence_string
|
||||||
})
|
})
|
||||||
sequence_response: dict = await response.json()
|
sequence_response: dict = await response.json()
|
||||||
if "exact_matches" not in sequence_response:
|
|
||||||
# TODO throw exception for not finding matches.
|
|
||||||
pass
|
|
||||||
|
|
||||||
if "exact_matches" not in sequence_response:
|
if "exact_matches" not in sequence_response:
|
||||||
raise ValueError(f"Unable to find exact matches in \"{self._database_name}\" under schema ID \"{self._schema_id}\".")
|
raise NoBIGSdbExactMatchesException(self._database_name, self._schema_id)
|
||||||
|
|
||||||
exact_matches: dict[str, Sequence[dict[str, str]]] = sequence_response["exact_matches"]
|
exact_matches: dict[str, Sequence[dict[str, str]]] = sequence_response["exact_matches"]
|
||||||
for allele_loci, alleles in exact_matches.items():
|
for allele_loci, alleles in exact_matches.items():
|
||||||
for allele in alleles:
|
for allele in alleles:
|
||||||
@ -48,11 +47,16 @@ class BIGSdbMLSTProfiler(AbstractAsyncContextManager):
|
|||||||
}
|
}
|
||||||
async with self._http_client.post(uri_path, json=request_json) as response:
|
async with self._http_client.post(uri_path, json=request_json) as response:
|
||||||
response_json = await response.json()
|
response_json = await response.json()
|
||||||
if "fields" not in response_json:
|
if "exact_matches" not in response_json:
|
||||||
# TODO raise exception about invalid parameters or no exact parameterization found
|
raise NoBIGSdbExactMatchesException(self._database_name, self._schema_id)
|
||||||
pass
|
|
||||||
schema_fields_returned = response_json["fields"]
|
|
||||||
schema_exact_matches: dict = response_json["exact_matches"]
|
schema_exact_matches: dict = response_json["exact_matches"]
|
||||||
|
if "fields" not in response_json:
|
||||||
|
schema_fields_returned = {
|
||||||
|
"ST": "Unknown",
|
||||||
|
"Clonal Complex": "Unknown"
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
schema_fields_returned: Mapping[str, str] = response_json["fields"]
|
||||||
allele_map: dict[str, list[Allele]] = defaultdict(list)
|
allele_map: dict[str, list[Allele]] = defaultdict(list)
|
||||||
for exact_match_loci, exact_match_alleles in schema_exact_matches.items():
|
for exact_match_loci, exact_match_alleles in schema_exact_matches.items():
|
||||||
for exact_match_allele in exact_match_alleles:
|
for exact_match_allele in exact_match_alleles:
|
||||||
@ -64,10 +68,14 @@ class BIGSdbMLSTProfiler(AbstractAsyncContextManager):
|
|||||||
return await self.fetch_mlst_st(alleles)
|
return await self.fetch_mlst_st(alleles)
|
||||||
|
|
||||||
|
|
||||||
async def profile_multiple_strings(self, namedStrings: AsyncIterable[NamedString]) -> AsyncGenerator[tuple[str, MLSTProfile], Any]:
|
async def profile_multiple_strings(self, namedStrings: AsyncIterable[NamedString], stop_on_fail: bool = False) -> AsyncGenerator[Union[tuple[str, MLSTProfile], tuple[str, None]], Any]:
|
||||||
async for named_string in namedStrings:
|
async for named_string in namedStrings:
|
||||||
|
try:
|
||||||
yield (named_string.name, await self.profile_string(named_string.sequence))
|
yield (named_string.name, await self.profile_string(named_string.sequence))
|
||||||
|
except NoBIGSdbExactMatchesException as e:
|
||||||
|
if stop_on_fail:
|
||||||
|
raise e
|
||||||
|
yield (named_string.name, None)
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
await self._http_client.close()
|
await self._http_client.close()
|
||||||
@ -107,7 +115,7 @@ class BIGSdbIndex(AbstractAsyncContextManager):
|
|||||||
async def get_bigsdb_api_from_seqdefdb(self, seqdef_db_name: str) -> str:
|
async def get_bigsdb_api_from_seqdefdb(self, seqdef_db_name: str) -> str:
|
||||||
known_databases = await self.get_known_seqdef_dbs()
|
known_databases = await self.get_known_seqdef_dbs()
|
||||||
if seqdef_db_name not in known_databases:
|
if seqdef_db_name not in known_databases:
|
||||||
raise ValueError(f"The database \"{seqdef_db_name}\" could not be found.")
|
raise NoSuchBIGSdbDatabaseException(seqdef_db_name)
|
||||||
return known_databases[seqdef_db_name]
|
return known_databases[seqdef_db_name]
|
||||||
|
|
||||||
async def get_schemas_for_seqdefdb(self, seqdef_db_name: str, force: bool = False) -> Mapping[str, int]:
|
async def get_schemas_for_seqdefdb(self, seqdef_db_name: str, force: bool = False) -> Mapping[str, int]:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user