diff --git a/client/src/components/Utilities/GetCoordinates/GetCoordinates.tsx b/client/src/components/Utilities/GetCoordinates/GetCoordinates.tsx index f9d441f4..8dd43949 100644 --- a/client/src/components/Utilities/GetCoordinates/GetCoordinates.tsx +++ b/client/src/components/Utilities/GetCoordinates/GetCoordinates.tsx @@ -151,8 +151,8 @@ const GetCoordinates: React.FC = () => { const handleResponse = (coordsResponse: CoordsUtilsResponse) => { if (coordsResponse.warnings) { - setResults(null); - clearWarnings(); + // setResults(null); + // clearWarnings(); coordsResponse.warnings.forEach((warning) => { if (warning.startsWith("Found more than one accession")) { setChromosomeText("Complete ID required"); diff --git a/requirements.txt b/requirements.txt index d19c649b..4e727d4d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ charset-normalizer==3.2.0 click==8.1.6 coloredlogs==15.0.1 configparser==6.0.0 -cool-seq-tool==0.1.14.dev0 +cool-seq-tool==0.3.0-dev1 cssselect==1.2.0 Cython==3.0.0 decorator==5.1.1 @@ -27,8 +27,8 @@ fake-useragent==1.1.3 fastapi==0.100.0 fusor==0.0.30.dev1 ga4gh.vrs==0.8.4 -ga4gh.vrsatile.pydantic==0.0.13 -gene-normalizer==0.1.39 +ga4gh.vrsatile.pydantic==0.2.0 +gene-normalizer==0.1.40-dev1 h11==0.14.0 hgvs==1.5.4 humanfriendly==10.0 @@ -55,7 +55,7 @@ prompt-toolkit==3.0.39 psycopg2==2.9.6 ptyprocess==0.7.0 pure-eval==0.2.2 -pydantic==1.10.12 +pydantic==2.4.2 pyee==8.2.2 Pygments==2.15.1 pyliftover==0.4 diff --git a/server/curfu/routers/demo.py b/server/curfu/routers/demo.py index 6feabb8b..f3d1888a 100644 --- a/server/curfu/routers/demo.py +++ b/server/curfu/routers/demo.py @@ -101,10 +101,10 @@ def clientify_structural_element( element_args["nomenclature"] = nm element_args["input_type"] = "exon_coords_tx" element_args["input_tx"] = element.transcript.split(":")[1] - element_args["input_exon_start"] = element.exon_start - element_args["input_exon_start_offset"] = element.exon_start_offset - element_args["input_exon_end"] = element.exon_end - element_args["input_exon_end_offset"] = element.exon_end_offset + element_args["input_exon_start"] = str(element.exon_start) + element_args["input_exon_start_offset"] = str(element.exon_start_offset) + element_args["input_exon_end"] = str(element.exon_end) + element_args["input_exon_end_offset"] = str(element.exon_end_offset) return ClientTranscriptSegmentElement(**element_args) else: raise ValueError("Unknown element type provided") diff --git a/server/curfu/routers/utilities.py b/server/curfu/routers/utilities.py index fc34454a..fdb44374 100644 --- a/server/curfu/routers/utilities.py +++ b/server/curfu/routers/utilities.py @@ -64,10 +64,9 @@ async def get_transcripts_for_gene(request: Request, gene: str) -> Dict: :param str gene: gene term provided by user :return: Dict containing transcripts if lookup succeeds, or warnings upon failure """ - cst = CoolSeqTool(db_url=UTA_DB_URL) - transcripts = await cst.uta_db.get_transcripts_from_gene(gene) - if not transcripts: - return {"warnings": [f"No matching transcripts: {gene}"]} + transcripts = await request.app.state.fusor.cool_seq_tool.uta_db.get_transcripts(gene) + if transcripts.is_empty(): + return {"warnings": [f"No matching transcripts: {gene}"], "transcripts": []} else: return {"transcripts": transcripts} @@ -187,7 +186,7 @@ async def get_exon_coords( logger.warning(warning) return CoordsUtilsResponse(warnings=warnings, coordinates_data=None) - response = await request.app.state.fusor.cool_seq_tool.genomic_to_transcript_exon_coordinates( # noqa: E501 + response = await request.app.state.fusor.cool_seq_tool.ex_g_coords_mapper.genomic_to_transcript_exon_coordinates( # noqa: E501 chromosome, start=start, end=end, diff --git a/server/curfu/schemas.py b/server/curfu/schemas.py index 13878f86..4acc7c52 100644 --- a/server/curfu/schemas.py +++ b/server/curfu/schemas.py @@ -1,5 +1,6 @@ """Provide schemas for FastAPI responses.""" from typing import Dict, List, Literal, Optional, Tuple, Union +import polars as pl from cool_seq_tool.schemas import GenomicData from fusor.models import ( @@ -45,16 +46,16 @@ class ClientTranscriptSegmentElement(TranscriptSegmentElement, ClientStructuralE Literal["genomic_coords_tx"], Literal["exon_coords_tx"], ] - input_tx: Optional[str] - input_strand: Optional[Strand] - input_gene: Optional[str] - input_chr: Optional[str] - input_genomic_start: Optional[str] - input_genomic_end: Optional[str] - input_exon_start: Optional[str] - input_exon_start_offset: Optional[str] - input_exon_end: Optional[str] - input_exon_end_offset: Optional[str] + input_tx: Optional[str] = "" + input_strand: Optional[Strand] = None + input_gene: Optional[str] = "" + input_chr: Optional[str] = "" + input_genomic_start: Optional[str] = "" + input_genomic_end: Optional[str] = "" + input_exon_start: Optional[str] = "" + input_exon_start_offset: Optional[str] = "" + input_exon_end: Optional[str] = "" + input_exon_end_offset: Optional[str] = "" class ClientLinkerElement(LinkerElement, ClientStructuralElement): @@ -66,9 +67,9 @@ class ClientLinkerElement(LinkerElement, ClientStructuralElement): class ClientTemplatedSequenceElement(TemplatedSequenceElement, ClientStructuralElement): """Templated sequence element used client-side.""" - input_chromosome: Optional[str] - input_start: Optional[str] - input_end: Optional[str] + input_chromosome: Optional[str] = "" + input_start: Optional[str] = "" + input_end: Optional[str] = "" class ClientGeneElement(GeneElement, ClientStructuralElement): @@ -112,7 +113,7 @@ class ClientRegulatoryElement(RegulatoryElement): class Response(BaseModel): """Abstract Response class for defining API response structures.""" - warnings: ResponseWarnings + warnings: ResponseWarnings = None class Config: """Configure class""" @@ -123,28 +124,28 @@ class Config: class GeneElementResponse(Response): """Response model for gene element construction endoint.""" - element: Optional[GeneElement] + element: Optional[GeneElement] = None class TxSegmentElementResponse(Response): """Response model for transcript segment element construction endpoint.""" - element: Optional[TranscriptSegmentElement] + element: Optional[TranscriptSegmentElement] = None class TemplatedSequenceElementResponse(Response): """Response model for transcript segment element construction endpoint.""" - element: Optional[TemplatedSequenceElement] + element: Optional[TemplatedSequenceElement] = None class NormalizeGeneResponse(Response): """Response model for gene normalization endpoint.""" term: StrictStr - concept_id: Optional[CURIE] - symbol: Optional[StrictStr] - cased: Optional[StrictStr] + concept_id: Optional[CURIE] = None + symbol: Optional[StrictStr] = "" + cased: Optional[StrictStr] = "" class SuggestGeneResponse(Response): @@ -153,10 +154,10 @@ class SuggestGeneResponse(Response): term: StrictStr matches_count: int # complete term, normalized symbol, normalized concept ID, chromosome ID, strand - concept_id: Optional[List[Tuple[str, str, str, str, str]]] - symbol: Optional[List[Tuple[str, str, str, str, str]]] - prev_symbols: Optional[List[Tuple[str, str, str, str, str]]] - aliases: Optional[List[Tuple[str, str, str, str, str]]] + concept_id: Optional[List[Tuple[str, str, str, str, str]]] = [] + symbol: Optional[List[Tuple[str, str, str, str, str]]] = [] + prev_symbols: Optional[List[Tuple[str, str, str, str, str]]] = [] + aliases: Optional[List[Tuple[str, str, str, str, str]]] = [] class DomainParams(BaseModel): @@ -172,20 +173,20 @@ class DomainParams(BaseModel): class GetDomainResponse(Response): """Response model for functional domain constructor endpoint.""" - domain: Optional[FunctionalDomain] + domain: Optional[FunctionalDomain] = None class AssociatedDomainResponse(Response): """Response model for domain ID autocomplete suggestion endpoint.""" gene_id: StrictStr - suggestions: Optional[List[DomainParams]] + suggestions: Optional[List[DomainParams]] = [] class ValidateFusionResponse(Response): """Response model for Fusion validation endpoint.""" - fusion: Optional[Fusion] + fusion: Optional[Fusion] = None class ExonCoordsRequest(BaseModel): @@ -223,9 +224,9 @@ class SequenceIDResponse(Response): """Response model for sequence ID retrieval endpoint.""" sequence: StrictStr - refseq_id: Optional[StrictStr] - ga4gh_id: Optional[StrictStr] - aliases: Optional[List[StrictStr]] + refseq_id: Optional[StrictStr] = "" + ga4gh_id: Optional[StrictStr] = "" + aliases: Optional[List[StrictStr]] = [] class ManeGeneTranscript(BaseModel): @@ -242,8 +243,8 @@ class ManeGeneTranscript(BaseModel): Ensembl_prot: str MANE_status: str GRCh38_chr: str - chr_start: str - chr_end: str + chr_start: StrictInt + chr_end: StrictInt chr_strand: str @@ -255,7 +256,7 @@ class GetTranscriptsResponse(Response): class GetGeneTranscriptsResponse(Response): """Response model for MANE transcript retrieval endpoint.""" - transcripts: Optional[List[str]] + transcripts: Optional[pl.DataFrame] class ServiceInfoResponse(Response): @@ -309,7 +310,7 @@ class ClientAssayedFusion(AssayedFusion): class NomenclatureResponse(Response): """Response model for regulatory element nomenclature endpoint.""" - nomenclature: Optional[str] + nomenclature: Optional[str] = "" class RegulatoryElementResponse(Response): diff --git a/server/setup.cfg b/server/setup.cfg index cb825e63..42a3ef53 100644 --- a/server/setup.cfg +++ b/server/setup.cfg @@ -36,7 +36,9 @@ dev = ruff black pre-commit - gene-normalizer ~= 0.1.39 + gene-normalizer ~=0.1.40-dev1 + cool-seq-tool ~=0.3.0-dev1 + pydantic == 2.* pydantic-to-typescript