Architecture Overview¶
System Diagram β POC (Current)¶
The diagram below shows the current POC architecture backed by SQLite and local ChromaDB.
flowchart TD
Client(["π Client\n(curl / browser / app)"])
subgraph API["β‘ FastAPI Application (main.py)"]
Router_Chat["api/v1/chat.py\n(Chat Router)"]
Router_Train["api/v1/training.py\n(Training Router)"]
DI["core/dependencies.py\n(Dependency Injection)"]
Service["services/vanna_service.py\n(VannaService β Singleton)"]
end
ChromaDB[("π£ ChromaDB\nVector Store\nchroma.sqlite3")]
OpenAI["βοΈ OpenAI\ngpt-4o + ada-002"]
SQLite[("π¦ SQLite\ndbn-poc-database.db")]
Client -->|"POST /chat/ask\nPOST /chat/generate-sql\nPOST /chat/run-sql"| Router_Chat
Client -->|"GET/POST/DELETE /training/*"| Router_Train
Router_Chat --> DI
Router_Train --> DI
DI -->|"singleton"| Service
Service -->|"embed + similarity_search(question)"| ChromaDB
ChromaDB -->|"top-10 DDL + SQL context"| Service
Service -->|"generate_sql(prompt + context)"| OpenAI
OpenAI -->|"SQL string"| Service
Service -->|"run_sql(sql)"| SQLite
SQLite -->|"pandas DataFrame"| Service
Service -->|"AskResponse / TrainResponse"| Client
Production target: SQLite β Azure SQL Database (MS SQL Server), local ChromaDB β Azure-hosted ChromaDB or Azure AI Search. See DBN Production Setup.
Project Structure¶
dbn-analytics-poc/
β
βββ api/
β βββ v1/
β βββ chat.py # POST /chat/ask Β· /generate-sql Β· /run-sql
β βββ training.py # GET/POST/DELETE /training/*
β
βββ core/
β βββ config.py # Pydantic Settings β env var management
β βββ dependencies.py # FastAPI DI providers (get_vanna singleton)
β
βββ docs/ # MkDocs Material documentation site
β βββ api/ # API reference pages
β βββ architecture/ # Architecture & DBN production docs
β βββ assets/ # CSS, logo, images
β βββ deployment/ # Docker Β· Fly.io Β· Azure guides
β βββ getting-started/ # Installation Β· Config Β· Quickstart
β βββ training/ # RAG training lifecycle docs
β βββ index.md # Home page
β
βββ models/
β βββ schemas.py # All Pydantic v2 request/response models
β
βββ services/
β βββ vanna_service.py # Vanna singleton: inference + training methods
β
βββ scripts/ # Utility scripts (seed training, audit, retrain)
β
βββ dbn-poc-database.db # SQLite database (msmeloans table)
βββ chroma.sqlite3 # ChromaDB persistent vector index
β
βββ main.py # FastAPI app factory, CORS middleware, router mounts
βββ Dockerfile # Production container definition
βββ fly.toml # Fly.io deployment config
βββ mkdocs.yml # Documentation site config
βββ requirements.txt # Python package dependencies
βββ README.md # Repository entry-point
Design Principles¶
| Principle | Implementation | Benefit |
|---|---|---|
| Separation of Concerns | Routes, services, schemas in distinct modules | Independently testable and replaceable |
| Singleton Services | VannaService initialised once via DI |
Single DB + ChromaDB connection per process |
| Validation-First | Pydantic v2 on all inputs and outputs | Clear error messages, zero manual parsing |
| Fail-Safe Charting | Plotly generation errors caught silently | Data always returned even if chart fails |
| Pluggable Database | vn.run_sql is overridable |
Easy swap from SQLite β MS SQL Server |
| Immutable Config | Pydantic BaseSettings loaded at startup |
No runtime env mutations |
API Surface Summary¶
| Tag | Method | Path | Description |
|---|---|---|---|
| chat | POST | /api/v1/chat/ask |
Full RAG: NL β SQL β Data β Plotly |
| chat | POST | /api/v1/chat/generate-sql |
NL β SQL only (no execution) |
| chat | POST | /api/v1/chat/run-sql |
Execute raw SQL β Data |
| training | GET | /api/v1/training/data |
List all ChromaDB training records |
| training | POST | /api/v1/training/sql |
Add questionβSQL pair |
| training | POST | /api/v1/training/ddl |
Add DDL statement |
| training | POST | /api/v1/training/documentation |
Add business doc string |
| training | POST | /api/v1/training/from-database |
Auto-ingest schema DDL |
| training | DELETE | /api/v1/training/{id} |
Remove a training record |
| health | GET | /health |
Liveness probe |
Request Lifecycle β /chat/ask¶
sequenceDiagram
autonumber
participant C as Client
participant F as FastAPI Router
participant P as Pydantic (AskRequest)
participant V as VannaService
participant CH as ChromaDB
participant OA as OpenAI GPT-4o
participant DB as Database (SQLite / Azure SQL)
C->>F: POST /api/v1/chat/ask {"question": "..."}
F->>P: Validate request body
P-->>F: AskRequest(question="...")
F->>V: get_vanna() singleton
V->>CH: similarity_search(question, n=10)
CH-->>V: [DDL schema, SQL examples, docs]
V->>OA: generate_sql(system_prompt + context + question)
OA-->>V: "SELECT Sector, AVG(...) FROM msmeloans GROUP BY ..."
V->>DB: run_sql(sql) β pd.read_sql_query(...)
DB-->>V: pandas DataFrame (N rows Γ M cols)
V->>OA: generate_plotly_code(question, sql, df)
OA-->>V: "fig = px.bar(df, x='Sector', ...)"
V-->>F: AskResponse(sql, data, plotly_code)
F-->>C: 200 OK {"sql": "...", "data": [...], "plotly_code": "..."}