from __future__ import annotations import time from fastapi import APIRouter, Depends, HTTPException, Request from app.engine import DuckDBEngine from app.models import QueryRequest, QueryResponse router = APIRouter(tags=["Generic Queries"]) def get_engine(request: Request) -> DuckDBEngine: return request.app.state.engine @router.post("/query", response_model=QueryResponse) async def execute_query( req: QueryRequest, engine: DuckDBEngine = Depends(get_engine), ) -> QueryResponse: t0 = time.perf_counter() try: rows = engine.query(req.query, req.params) duration_ms = round((time.perf_counter() - t0) * 1000, 2) cols = list(rows[0].keys()) if rows else [] return QueryResponse( columns=cols, rows=rows, count=len(rows), execution_time_ms=duration_ms, ) except ValueError as ve: raise HTTPException(status_code=400, detail=str(ve)) except Exception as e: raise HTTPException(status_code=500, detail=str(e))