ci / api (push) Failing after 10s
ci / terraform (push) Failing after 11s
ci / web (push) Failing after 35s
ci / pipeline (push) Failing after 2m29s
ci / images (api) (push) Skipped
ci / images (ml) (push) Skipped
ci / images (pipeline) (push) Skipped
ci / images (web) (push) Skipped
End-to-end variant interpretation platform for rare genetic disease research: SvelteKit UI, FastAPI + PostgreSQL API, Nextflow/Ensembl VEP pipeline, LightGBM pathogenicity scoring with MLflow, K8s/ArgoCD/GCP infrastructure. Public test data only; no clinical claims.
44 lines
1.5 KiB
Python
44 lines
1.5 KiB
Python
import uuid
|
|
|
|
from fastapi import APIRouter, Depends, Query
|
|
from sqlalchemy import func, select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy.orm import selectinload
|
|
|
|
from app.db import get_session
|
|
from app.models import Prediction, Variant
|
|
from app.schemas import VariantPage
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("", response_model=VariantPage)
|
|
async def list_variants(
|
|
job_id: uuid.UUID,
|
|
gene: str | None = None,
|
|
impact: str | None = Query(None, pattern="^(HIGH|MODERATE|LOW|MODIFIER)$"),
|
|
max_af: float | None = Query(None, ge=0, le=1),
|
|
min_score: float | None = Query(None, ge=0, le=1),
|
|
limit: int = Query(50, le=500),
|
|
offset: int = 0,
|
|
session: AsyncSession = Depends(get_session),
|
|
):
|
|
stmt = select(Variant).where(Variant.job_id == job_id)
|
|
if gene:
|
|
stmt = stmt.where(Variant.gene == gene.upper())
|
|
if impact:
|
|
stmt = stmt.where(Variant.impact == impact)
|
|
if max_af is not None:
|
|
stmt = stmt.where((Variant.gnomad_af.is_(None)) | (Variant.gnomad_af <= max_af))
|
|
if min_score is not None:
|
|
stmt = stmt.join(Prediction, Prediction.variant_id == Variant.id).where(Prediction.score >= min_score)
|
|
|
|
total = await session.scalar(select(func.count()).select_from(stmt.subquery()))
|
|
rows = await session.scalars(
|
|
stmt.options(selectinload(Variant.prediction))
|
|
.order_by(Variant.chrom, Variant.pos)
|
|
.limit(limit)
|
|
.offset(offset)
|
|
)
|
|
return VariantPage(items=rows.all(), total=total or 0, limit=limit, offset=offset)
|