Melika Kheirieh
fix(sqlite): unify adapter path resolution and load from env for stable pipeline execution
4c2cf14
from fastapi import APIRouter, HTTPException
from pydantic import BaseModel
from nl2sql.safety import Safety
from nl2sql.verifier import Verifier
# pick adapter for verifier (SQLite default)
from adapters.db.sqlite_adapter import SQLiteAdapter
from dataclasses import is_dataclass, asdict
from typing import Any
import yaml
from pathlib import Path
import os
CONFIG_PATH = os.getenv("PIPELINE_CONFIG", "configs/sqlite_pipeline.yaml")
def _is_dataclass_instance(x: Any) -> bool:
# True only for dataclass *instances* (not classes)
return is_dataclass(x) and not isinstance(x, type)
def _to_dict(obj: Any) -> dict:
# Pydantic v2
if hasattr(obj, "model_dump"):
return obj.model_dump() # type: ignore[no-any-return]
# Pydantic v1
if hasattr(obj, "dict"):
return obj.dict() # type: ignore[no-any-return]
# Dataclass instance
if _is_dataclass_instance(obj):
return asdict(obj) # type: ignore[arg-type]
# Plain object
if hasattr(obj, "__dict__"):
return {k: v for k, v in obj.__dict__.items() if not k.startswith("_")}
return {"value": str(obj)}
router = APIRouter(prefix="/_dev", tags=["dev"])
class SQLBody(BaseModel):
sql: str
@router.post("/safety")
def dev_safety_check(body: SQLBody):
"""
Run the Safety stage directly on a raw SQL string.
Used for metrics validation (Prometheus counters).
"""
s = Safety()
res = s.check(body.sql)
return _to_dict(res)
@router.post("/verifier")
def dev_verifier_check(body: SQLBody):
"""
Run the Verifier stage directly on a raw SQL string
with a real adapter connection loaded from YAML config.
"""
config_path = Path(CONFIG_PATH)
if not config_path.exists():
raise HTTPException(status_code=500, detail="Config file not found")
try:
with config_path.open("r") as f:
config = yaml.safe_load(f)
dsn = config.get("adapter", {}).get("dsn")
if not dsn:
raise ValueError("Missing adapter.dsn in config file")
adapter = SQLiteAdapter(dsn)
except Exception as e:
raise HTTPException(status_code=500, detail=f"Adapter init failed: {e}")
v = Verifier()
res = v.verify(body.sql, adapter=adapter)
return _to_dict(res)