Proof-first analytics copilot with a rollback sandbox + BYODB
AskDB lets you query a SQL database in plain English and returns: (1) the business answer, (2) the generated SQL, and (3) a preview table — so every result is fast, explainable, and auditable.
Most NL→SQL demos stop at “the model generated a query.” AskDB is built like a real system:
- Proof-first output: answer + SQL + preview rows in one place (no guesswork)
- Safety model:
- Public mode =
SELECT-only (joins, CTEs, aggregations allowed) - Sandbox mode =
INSERT/UPDATE/DELETEallowed, but every write rolls back
- Public mode =
- BYODB (Bring Your Own Database): connect your own Postgres/MySQL/SQLite URL (schema CSV optional; AskDB can auto-detect)
- Reliability loop: optional SQL self-repair on execution errors (configurable retries)
- Scalable primitives: Redis-backed caching, async jobs (RQ), and Prometheus metrics (optional)
- Frontend: https://ask-db.vercel.app
- Backend API: https://askdb-jwz4.onrender.com
Render free instances may sleep. If the UI shows “Connecting…”, open the backend once to wake it up.
Top 3 customers by total payments
Total sales by product line
Switch mode = sandbox
Delete customer 112
Expect: rolled_back: true
Switch back to mode = public
Show customer 112
Customer is still present → rollback verified
flowchart LR
U[User] --> FE[Frontend - React Vite]
FE --> API[Flask API]
API --> SCHEMA[Schema - CSV or introspection]
API --> LLM[Gemini - LangChain]
API --> DB[(SQL database)]
API --> R[(Redis - optional)]
API --> M[Metrics - Prometheus]
API --> FE
Execution path
- UI sends a question + session_id + mode.
- Backend loads the active connection context (demo DB or BYODB connection).
- LLM produces SQL using schema context + few-shot examples.
- Guardrails enforce:
- public =
SELECTonly (single statement, LIMIT applied) - sandbox = DML allowed but rolled back
- DDL blocked always
- public =
- Backend returns answer + SQL + preview rows (+ metadata).
SELECT/WITH ... SELECTonly- single statement only
- enforced LIMIT + query timeout (dialect-aware best effort)
- Allows
INSERT / UPDATE / DELETE - Runs inside a transaction and always rolls back
- Multi-statement allowed only for FK-safe delete batches (child → parent)
- Connect a DB URL from the UI
- Schema CSV is optional:
- If CSV is missing/invalid → AskDB auto-detects schema from the DB
- Disconnect anytime to return to the demo DB
- Can be gated behind a demo key in production
- Structured JSON logs
/metricsendpoint (Prometheus format)- Request IDs for correlation
- Redis caching layer:
- LLM output caching (question → SQL)
- SQL result caching (sql hash + db_id → preview rows)
- Async execution path:
- queue via RQ + polling endpoints for long queries
Base URL (local): http://127.0.0.1:5000
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | status + feature flags |
/health |
GET | health check |
/about |
GET | app metadata |
/examples |
GET | curated example prompts |
/schema?session_id=... |
GET | active schema (demo or BYODB) |
/connection?session_id=... |
GET | active connection status |
/connect |
POST | connect BYODB for a session |
/disconnect |
POST | disconnect BYODB for a session |
/api |
POST | ask a question (sync or async depending on config) |
/jobs/<job_id> |
GET | poll async job result |
/metrics |
GET | Prometheus metrics (optional) |
{
"question": "Top 10 customers by total payments",
"session_id": "demo",
"mode": "public",
"include_sql": true
}Frontend
- React + Vite + TailwindCSS (Node.js toolchain)
- Deployed on Vercel
Backend
- Flask + SQLAlchemy + LangChain + Gemini
- Rate limiting + structured logging
- Optional: Redis + RQ + Prometheus
Database
- Postgres (Supabase demo DB) + BYODB support for Postgres/MySQL/SQLite
git clone https://github.com/charan047/AskDB.git
cd AskDB
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS/Linux:
source .venv/bin/activate
pip install -r requirements.txt
pip install -r requirements-dev.txtCreate .env in the repo root (do not commit it):
# --- LLM ---
GOOGLE_API_KEY=YOUR_GOOGLE_API_KEY
GEMINI_MODEL=gemini-2.5-flash
# --- Demo DB (default) ---
DATABASE_URL=postgresql+psycopg2://user:pass@host:5432/postgres?sslmode=require
# --- App ---
PORT=5000
CORS_ORIGINS=http://localhost:5173,http://127.0.0.1:5173
TABLE_DESCRIPTIONS_PATH=./database_table_descriptions.csv
# --- Optional: feature flags ---
BYODB_ENABLED=1
SANDBOX_ENABLED=1
# Gate BYODB/sandbox behind a demo key (recommended for public deployments)
DEMO_KEY=
# --- Optional: Redis (caching + sessions + async jobs) ---
REDIS_URL=rediss://default:<password>@<host>:<port>
ASYNC_ENABLED=1
ASYNC_DEFAULT=0
RQ_QUEUE_NAME=askdbpython code1.pycd frontend
npm install
npm run devUI: http://localhost:5173
API: http://127.0.0.1:5000
pytest -q- Never commit secrets (
.envshould be ignored). - Public mode is read-only (
SELECTonly). - Sandbox mode always rolls back DML (no permanent writes).
- DDL (CREATE/ALTER/DROP/TRUNCATE) is blocked.
- For public deployments, keep DEMO_KEY enabled to prevent arbitrary DB connections.
If you find a security issue, please follow the process in SECURITY.md.
V1 focuses on “proof-first” analytics with safe guardrails. V2 aims for production-scale workflows:
- Huge schema support (schema RAG + join-path hints)
- Cost-aware query rewrites + indexing suggestions
- Saved dashboards + scheduled insights
- Auth/RBAC + multi-tenant isolation
- Stronger observability (p95 latency + LLM vs DB breakdown)
We welcome issues + PRs. See CONTRIBUTING.md for guidelines.
MIT — see LICENSE.