Skip to content

Latest commit

Β 

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

PredicateLogicSQL β€” Banking Chatbot

Python 3.14+ FastAPI Streamlit LangChain LangGraph License MIT

A natural language interface for banking databases that translates user queries into validated predicate logic objects, ensuring safe database execution without ever generating or executing raw SQL strings.


Important

The Zero Raw SQL Security Guarantee: The LLM never generates or executes raw SQL code. Instead, natural language inputs are parsed into a strictly validated Pydantic PredicateExpression structure. The application layer translates these validated structures into parameterized database queries. This architecture completely eliminates the risk of SQL injection attacks.


Architecture

The diagram below outlines the end-to-end request lifecycle, from natural language input to safe execution against the Entity-Attribute-Value (EAV) database and response generation:

graph TD
    User([User / Client])
    UI[Streamlit Demo UI / Terminal CLI]
    API[FastAPI Router: /api/v1/chat]
    NLP[NLP Parser: LangChain Structured Output]
    Exec[Query Executor: Repository Dispatch]
    DB[(SQLite EAV Datastore)]
    Resp[Response Generator: Natural Language Answer]
    
    User -->|Asks Question| UI
    User -->|HTTP API / SSE| API
    UI -->|API Calls / SSE Stream| API
    API -->|LangGraph Workflow| NLP
    
    subgraph Fallback [LLM Provider Fallback Chain]
        Groq[Groq: llama-3.3-70b-versatile]
        Gemini[Gemini: gemini-2.0-flash]
        Ollama[Ollama: Local llama3.2]
        Groq -.->|if unavailable| Gemini
        Gemini -.->|if unavailable| Ollama
    end
    
    NLP -->|Queries| Fallback
    Fallback -->|Returns PredicateExpression| NLP
    NLP -->|Passes PredicateExpression| Exec
    Exec -->|Safe Parameterized Filter| DB
    DB -->|Returns QueryResult Rows| Exec
    Exec -->|Passes QueryResult| Resp
    Resp -->|Natural Language Answer| User
Loading

Entity-Attribute-Value (EAV) Database Schema

All domain data (customers, accounts, loans, bank info, interest rates, schema metadata) is stored flexibly using an EAV pattern across three primary tables:

  • entities: Unique entity instances (customer_id, account_id, loan_id, etc.).
  • attributes: Attribute definitions (balance, interest_rate, swift_code, kyc_status).
  • entity_values: Typed value mappings associating an entity with an attribute value.

Key Features

  • πŸ›‘οΈ SQL Injection Protection: Translates natural language strictly into validated Pydantic predicate structures instead of raw SQL code.
  • πŸ”„ Multi-Provider LLM Fallback: Automatic Chain-of-Responsibility fallback across Groq, Google Gemini, and local Ollama instances.
  • ⚑ Real-Time SSE Streaming: Async FastAPI streaming endpoint (/api/v1/chat/stream) sending live token updates and predicate metadata to clients.
  • πŸ“Š EAV Schema Introspection: Built-in REST route (/api/v1/schema) for full dynamic database schema discovery with PII sensitivity flagging.
  • 🎨 Modern Streamlit Demo UI: Dark glassmorphism interface with chat session switching, live execution timing, predicate inspector, and database browser.
  • πŸ› οΈ Developer Tooling & Automation: Fully managed Makefile automation for installation, seeding, testing, and dev environment launching.

Tech Stack

Layer Technology Purpose
Language Python >= 3.14 Core execution runtime
API Framework FastAPI + Uvicorn High-performance REST APIs + SSE streaming
Web Interface Streamlit Dark-themed interactive web UI
Database SQLite + aiosqlite Asynchronous local relational datastore
ORM SQLAlchemy 2.x (async) Async database session and schema modeling
Workflow Engine LangGraph Stateful conversational graph orchestration
LLM Framework LangChain Structured output parsing & provider integrations
Validation Pydantic v2 Strict schema validation and settings
Logging Structlog Structured JSON developer logging
Package Manager uv Lightning-fast Python dependency management

Project Structure

predicate-sql-chat/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ main.py                     ← FastAPI app entrypoint & lifespan management
β”‚   β”œβ”€β”€ api/
β”‚   β”‚   └── v1/routes/
β”‚   β”‚       β”œβ”€β”€ chat.py             ← API routes for chat execution (standard + SSE streaming)
β”‚   β”‚       β”œβ”€β”€ chats.py            ← API routes for chat sessions and message history
β”‚   β”‚       └── schema.py           ← API route for dynamic EAV schema introspection
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ config.py               ← App settings loaded from .env via Pydantic
β”‚   β”‚   β”œβ”€β”€ exceptions.py           ← Centralized custom error hierarchy
β”‚   β”‚   └── logging.py              ← Structlog logging setup
β”‚   β”œβ”€β”€ db/
β”‚   β”‚   β”œβ”€β”€ base.py                 ← Async SQLAlchemy engine and session factory
β”‚   β”‚   β”œβ”€β”€ seed.py                 ← EAV database seeder with sample banking data
β”‚   β”‚   └── models/
β”‚   β”‚       β”œβ”€β”€ eav.py              ← Entity, Attribute, and EntityValue ORM models
β”‚   β”‚       └── chat_history.py     ← ChatSession and ChatMessage persistence models
β”‚   β”œβ”€β”€ domain/
β”‚   β”‚   β”œβ”€β”€ predicates.py           ← Pure domain models: PredicateExpression, FilterCondition
β”‚   β”‚   └── specifications.py       ← Specification rules for table and field validation
β”‚   β”œβ”€β”€ infrastructure/
β”‚   β”‚   β”œβ”€β”€ llm/
β”‚   β”‚   β”‚   β”œβ”€β”€ base.py             ← LLMProvider Protocol interface definition
β”‚   β”‚   β”‚   β”œβ”€β”€ fallback_chain.py   ← Chain of Responsibility fallback implementation
β”‚   β”‚   β”‚   β”œβ”€β”€ groq_provider.py    ← Groq LLM integration
β”‚   β”‚   β”‚   β”œβ”€β”€ gemini_provider.py  ← Gemini LLM integration
β”‚   β”‚   β”‚   └── ollama_provider.py  ← Local Ollama LLM integration
β”‚   β”‚   └── repositories/
β”‚   β”‚       β”œβ”€β”€ base.py             ← Base repository helper methods
β”‚   β”‚       β”œβ”€β”€ chat_history_repository.py ← Conversation history persistence
β”‚   β”‚       β”œβ”€β”€ eav_repository.py   ← EAV dataset query execution & schema fetching
β”‚   β”‚       └── operator_dispatch.py← Dispatch map for execution comparison operators
β”‚   β”œβ”€β”€ schemas/
β”‚   β”‚   └── chat.py                 ← API request/response Pydantic models
β”‚   └── application/
β”‚       β”œβ”€β”€ query_executor.py       ← Validates and executes PredicateExpressions
β”‚       β”œβ”€β”€ use_cases.py            ← ChatUseCase coordinating execution & persistence
β”‚       └── workflow/
β”‚           β”œβ”€β”€ graph.py            ← LangGraph state machine configuration
β”‚           β”œβ”€β”€ nodes.py            ← Workflow node handlers (parse, query, reply)
β”‚           └── state.py            ← Conversational state dictionary schema
β”œβ”€β”€ streamlit_app/                  
β”‚   β”œβ”€β”€ styles/
β”‚   β”‚   └── theme.css               ← Dark glassmorphism stylesheet for Streamlit UI
β”‚   └── api_client.py               ← API connection client for Streamlit UI
β”œβ”€β”€ tests/
β”‚   β”œβ”€β”€ unit/                       ← Unit tests for domain, use cases, and repositories
β”‚   └── integration/                ← Integration tests for full API pipelines
β”œβ”€β”€ chat.py                         ← CLI terminal chat loop wrapper
β”œβ”€β”€ streamlit_ui.py                 ← Streamlit web interface entry point
β”œβ”€β”€ pyproject.toml                  ← Project dependencies and configuration
β”œβ”€β”€ Makefile                        ← Automation targets (install, dev, seed, test)
└── .env.example                    ← Template environment configuration file

Quickstart Guide

Follow these steps to clone the repository and run the application locally:

1. Prerequisites

  • Python 3.14+
  • uv package manager (curl -LsSf https://astral.sh/uv/install.sh | sh)
  • (Optional) Ollama running locally if using local offline LLM fallback:
    ollama pull llama3.2

2. Clone & Install

Clone the repository and install dependencies using uv:

git clone https://github.com/KESHABWI/predicate-sql-chat.git
cd predicate-sql-chat
make install

3. Environment Configuration

Copy the example environment file to .env:

cp .env.example .env

Open .env and fill in your API keys:

APP_ENV=development
LOG_LEVEL=INFO
DATABASE_URL=sqlite+aiosqlite:///./banking.db

GROQ_API_KEY=your-groq-key-here
GROQ_MODEL=llama-3.3-70b-versatile

GEMINI_API_KEY=your-gemini-key-here
GEMINI_MODEL=gemini-2.0-flash

OLLAMA_URL=http://localhost:11434
OLLAMA_MODEL=llama3.2

LLM_FALLBACK_ORDER=groq,gemini,ollama
LLM_PROVIDER_TIMEOUT=30.0

4. Database Setup & Seeding

Initialize and seed the SQLite database with mock banking records (customers, accounts, loans, interest rates, branches):

make db-reset

5. Run the Application

Launch both the FastAPI backend and the Streamlit UI simultaneously:

make dev

Once running:

Alternatively, run individual components:

  • make run β€” Launch FastAPI backend server (http://localhost:8000)
  • make ui β€” Launch Streamlit UI (http://localhost:8501)
  • make chat β€” Launch interactive CLI terminal chat

API Reference

Endpoint Method Description
/api/v1/chat POST Process a natural language question and return a structured response with parsed predicates.
/api/v1/chat/stream POST Process a question and stream Server-Sent Events (SSE) token by token.
/api/v1/chats GET List all active conversation sessions.
/api/v1/chats/{session_id}/messages GET Retrieve the chat message history for a given session.
/api/v1/schema GET Retrieve database tables, column metadata, and PII sensitivity indicators.

Query Examples & Predicate Structure

Example 1: Account Balance Query

  • Natural Language Question: "Show all savings accounts"
  • Parsed Predicate Expression:
    PredicateExpression(
        table="accounts",
        conditions=[
            FilterCondition(field="account_type", operator="eq", value="savings")
        ],
        select_fields=["account_number", "current_balance", "account_status"],
        limit=10
    )
  • Generated Answer: "You have 10 savings accounts. Account ACC-0001001 has a balance of NPR 580,000.00..."

Example 2: Loan Filtering Query

  • Natural Language Question: "Do I have any active mortgage loans?"
  • Parsed Predicate Expression:
    PredicateExpression(
        table="loans",
        conditions=[
            FilterCondition(field="loan_type", operator="eq", value="mortgage"),
            FilterCondition(field="loan_status", operator="eq", value="active")
        ],
        select_fields=["loan_reference", "outstanding_balance", "loan_status"],
        limit=10
    )

Developer Automation (Makefile)

Every common developer task is accessible via short make targets:

make install          # Install dependencies via uv sync
make dev              # Run FastAPI backend + Streamlit UI concurrently
make run              # Start FastAPI backend server with hot reload
make ui               # Start Streamlit web UI
make chat             # Start terminal CLI chat interface
make seed             # Populate database with mock data
make db-reset         # Recreate database tables and re-seed
make test             # Run pytest test suite (24 tests)
make test-unit        # Run unit tests only
make test-integration # Run integration tests only
make clean            # Remove pycache, temp files, and caches
make help             # Display Makefile command summary

License

Distributed under the MIT License. See LICENSE for more information.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages