diff --git a/bedhost/_version.py b/bedhost/_version.py index def467e0..76da4a98 100644 --- a/bedhost/_version.py +++ b/bedhost/_version.py @@ -1 +1 @@ -__version__ = "0.12.1" +__version__ = "0.12.2" diff --git a/bedhost/data_models.py b/bedhost/data_models.py index b81ed2bc..e5b45cca 100644 --- a/bedhost/data_models.py +++ b/bedhost/data_models.py @@ -1,4 +1,5 @@ from enum import Enum +from typing import Dict from fastapi import Path from pydantic import BaseModel @@ -81,3 +82,7 @@ class BaseListResponse(BaseModel): class CreateBEDsetRequest(BaseModel): registry_path: str + + +class ChromLengthUploadModel(BaseModel): + bed_file: Dict[str, int] diff --git a/bedhost/main.py b/bedhost/main.py index fb544724..d979e4c6 100644 --- a/bedhost/main.py +++ b/bedhost/main.py @@ -10,6 +10,8 @@ MissingObjectError, MissingThumbnailError, ) +from bedboss.refgenome_validator.main import ReferenceValidator + from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import HTMLResponse, RedirectResponse @@ -142,6 +144,11 @@ def main(): global bbagent bbagent = configure(bbconf_file_path) + + _LOGGER.info("Initializing reference genome validator...") + global ref_validator + ref_validator = ReferenceValidator() + attach_routers(app) uvicorn.run( app, @@ -158,12 +165,15 @@ def main(): _LOGGER.info(f"Running {PKG_NAME} app...") bbconf_file_path = os.environ.get("BEDBASE_CONFIG") or None global bbagent - global usage_data - usage_data = init_model_usage() + global ref_validator + bbagent = configure( bbconf_file_path ) # configure before attaching routers to avoid circular imports + usage_data = init_model_usage() + + ref_validator = ReferenceValidator() scheduler = BackgroundScheduler() diff --git a/bedhost/routers/bed_api.py b/bedhost/routers/bed_api.py index 1e745321..b90b20e7 100644 --- a/bedhost/routers/bed_api.py +++ b/bedhost/routers/bed_api.py @@ -29,6 +29,7 @@ TokenizedPathResponse, QdrantSearchResult, RefGenValidReturnModel, + RefGenValidModel, ) from fastapi import APIRouter, File, HTTPException, Query, UploadFile, Request from fastapi.responses import PlainTextResponse @@ -36,8 +37,13 @@ from .. import _LOGGER from ..const import EXAMPLE_BED, MAX_FILE_SIZE, MAX_REGION_NUMBER, MIN_REGION_WIDTH -from ..data_models import CROM_NUMBERS, BaseListResponse, BedDigest -from ..main import bbagent, usage_data +from ..data_models import ( + CROM_NUMBERS, + BaseListResponse, + BedDigest, + ChromLengthUploadModel, +) +from ..main import bbagent, usage_data, ref_validator from ..helpers import count_requests, test_query_parameter router = APIRouter(prefix="/v1/bed", tags=["bed"]) @@ -291,6 +297,54 @@ async def embed_bed_file( return embedding.tolist()[0] +@router.post( + "/analyze-genome", + summary="Analyze reference genome for bed file", + response_model=RefGenValidReturnModel, +) +async def analyze_reference_genome( + chrom_lengths: ChromLengthUploadModel, +): + """ + Provide length of the chromosomes for a reference genome, and + return reference genome validation results for a bed file + """ + + try: + genome_aliases = bbagent.get_reference_genomes() + result = ref_validator.determine_compatibility( + chrom_lengths.bed_file, concise=True + ) + + compared_genomes: List[RefGenValidModel] = [] + for genome, value in result.items(): + if value.tier_ranking < 4: + compared_genomes.append( + RefGenValidModel( + provided_genome="Not Provided", + compared_genome=genome_aliases.get(genome, "Unknown genome"), + genome_digest=genome, + xs=value.xs, + oobr=value.oobr, + sequence_fit=value.sequence_fit, + assigned_points=value.assigned_points, + tier_ranking=value.tier_ranking, + ) + ) + return RefGenValidReturnModel( + id="No ID", + provided_genome="Not Provided", + compared_genome=compared_genomes, + ) + + except BedBaseConfError as e: + _LOGGER.error(e) + raise HTTPException( + status_code=400, + detail=f"Unable to process request. Check loggs", + ) + + @router.get( "/missing_plots", summary="Get missing plots for a bed file.", diff --git a/requirements/requirements-all.txt b/requirements/requirements-all.txt index eaa44f47..7fe617d4 100644 --- a/requirements/requirements-all.txt +++ b/requirements/requirements-all.txt @@ -1,5 +1,5 @@ # bbconf @ git+https://github.com/databio/bbconf.git@dev#egg=bbconf -bbconf>=0.14.1 +bbconf>=0.14.2 fastapi>=0.103.0 logmuse>=0.2.7 markdown @@ -12,4 +12,4 @@ psycopg[binary,pool] python-multipart>=0.0.9 APScheduler>=3.11.0 cachetools>=4.2.4 - +bedboss>=0.8.5 diff --git a/test.Dockerfile b/test.Dockerfile index 725c1369..4f08d822 100644 --- a/test.Dockerfile +++ b/test.Dockerfile @@ -1,7 +1,7 @@ FROM bedhost -COPY config.yaml /bedbase.yaml -ENV BEDBASE_CONFIG=/bedbase.yaml +COPY config.yaml /config.yaml +ENV BEDBASE_CONFIG=/config.yaml RUN mkdir -p /data/outputs/bedstat_output RUN mkdir -p /data/outputs/bedbuncher_output diff --git a/ui/package.json b/ui/package.json index e406eb55..b32c1c53 100644 --- a/ui/package.json +++ b/ui/package.json @@ -12,7 +12,7 @@ "generate-types-local": "npx openapi-typescript http://localhost:8000/openapi.json -o bedbase-types.d.ts" }, "dependencies": { - "@databio/gtars": "^0.5.2", + "@databio/gtars": "^0.5.3", "@tanstack/react-query": "^5.28.0", "@tanstack/react-query-devtools": "^5.28.0", "@tanstack/react-table": "^8.15.3", diff --git a/ui/public/api_icon.svg b/ui/public/api_icon.svg index da662f02..f92313a0 100644 --- a/ui/public/api_icon.svg +++ b/ui/public/api_icon.svg @@ -8,7 +8,7 @@ version="1.1" id="svg1" inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)" - sodipodi:docname="API.svg" + sodipodi:docname="api_icon.svg" xml:space="preserve" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -24,7 +24,7 @@ inkscape:deskcolor="#d1d1d1" inkscape:document-units="mm" inkscape:zoom="9.142616" - inkscape:cx="13.015968" + inkscape:cx="12.961279" inkscape:cy="28.219494" inkscape:window-width="1920" inkscape:window-height="1082" @@ -531,135 +531,137 @@ r="5.275753" id="circle2" style="stroke-width:0.732744" />