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.
50 lines
1.8 KiB
Python
50 lines
1.8 KiB
Python
import uuid
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from sqlalchemy import select
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.db import get_session
|
|
from app.models import Job, Sample
|
|
from app.schemas import JobOut, SampleCreate, SampleOut
|
|
from app.services.events import publish_vcf_uploaded
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("", response_model=list[SampleOut])
|
|
async def list_samples(session: AsyncSession = Depends(get_session)):
|
|
result = await session.scalars(select(Sample).order_by(Sample.created_at.desc()))
|
|
return result.all()
|
|
|
|
|
|
@router.post("", response_model=SampleOut, status_code=status.HTTP_201_CREATED)
|
|
async def create_sample(payload: SampleCreate, session: AsyncSession = Depends(get_session)):
|
|
sample = Sample(**payload.model_dump())
|
|
session.add(sample)
|
|
await session.commit()
|
|
await session.refresh(sample)
|
|
return sample
|
|
|
|
|
|
@router.get("/{sample_id}/jobs", response_model=list[JobOut])
|
|
async def list_jobs(sample_id: uuid.UUID, session: AsyncSession = Depends(get_session)):
|
|
result = await session.scalars(
|
|
select(Job).where(Job.sample_id == sample_id).order_by(Job.created_at.desc())
|
|
)
|
|
return result.all()
|
|
|
|
|
|
@router.post("/{sample_id}/annotate", response_model=JobOut, status_code=status.HTTP_202_ACCEPTED)
|
|
async def annotate(sample_id: uuid.UUID, session: AsyncSession = Depends(get_session)):
|
|
sample = await session.get(Sample, sample_id)
|
|
if sample is None:
|
|
raise HTTPException(404, "sample not found")
|
|
job = Job(sample_id=sample.id)
|
|
session.add(job)
|
|
await session.commit()
|
|
await session.refresh(job)
|
|
# Emits to Pub/Sub in GCP; runs the Nextflow pipeline inline for local dev.
|
|
await publish_vcf_uploaded(job_id=job.id, vcf_uri=sample.vcf_uri)
|
|
return job
|