Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: AskSQLAI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
backend-lint-and-build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./backend

steps:
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install flake8

- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

frontend-lint-and-build:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./frontend

steps:
- uses: actions/checkout@v3

- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '18.x'
cache: 'npm'
cache-dependency-path: './frontend/package-lock.json'

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Lint
run: npm run lint
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# AskSQL AI

Convert natural language questions into PostgreSQL queries with a heavy-duty, premium AI-powered interface.

## 🚀 Features

- **Intuitive NL to SQL**: Powered by Gemini 2.5 Flash for high accuracy.
- **Midnight Sapphire UI**: Ultra-premium dark theme with advanced glassmorphism.
- **Live Database Connection**: Automatically reflects your current schema.
- **Dynamic Schema Creator**: Create tables with support for **TEXT, INTEGER, FLOAT, TIMESTAMP, and DATE**.
- **Execution Safety**: Strict read-only validation blocks destructive commands.

## 🛠️ Tech Stack

- **Frontend**: React 18, Vite, TypeScript, Custom CSS (Midnight theme).
- **Backend**: FastAPI, PostgreSQL, Google GenAI SDK.
- **Orchestration**: Docker & Docker Compose.

## 📦 Quick Start

1. **API Key**: Get a Gemini API key from [Google AI Studio](https://aistudio.google.com/).
2. **Environment**: Add your keys and DB config to `backend/.env`.
3. **Run**:
```bash
docker-compose up --build
```

Access the app at: `http://localhost:3000`

## 🔒 Security

All generated SQL queries are parsed for restricted keywords (`DROP`, `DELETE`, etc.) before execution to ensure a read-only experience for the AI.
21 changes: 21 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# AskSQL AI - Backend

FastAPI service handling NL to SQL conversion, schema exploration, and safe query execution.

## 🚀 Key Features
- **GenAI Integration**: Uses Gemini 1.5 Flash with optimized system instructions.
- **SQL Guardrails**: Custom validator blocks non-SELECT statements.
- **Schema Reflection**: Real-time introspection of the `public` schema.
- **Table Creator**: Support for common PostgreSQL types (`INT`, `TEXT`, `REAL`, etc).

## 🛠️ Technical Details
- **Framework**: FastAPI
- **DB Driver**: Psycopg2
- **Validation**: Pydantic v2
- **AI**: Google Generative AI

## 🔧 Local Development

1. **Install**: `pip install -r requirements.txt`
2. **Env**: Set `GEMINI_API_KEY` and DB credentials in `.env`.
3. **Run**: `uvicorn main:app --reload`
4 changes: 4 additions & 0 deletions backend/app/services/schema_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@

ALLOWED_TYPES = {
"text": "TEXT",
"string": "TEXT",
"int": "INTEGER",
"integer": "INTEGER",
"number": "REAL",
"float": "REAL",
"timestamp": "TIMESTAMP",
"date": "TIMESTAMP",
}


Expand Down
50 changes: 32 additions & 18 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,38 @@
version: '3.8'

services:
# backend:
# build:
# context: ./backend
# dockerfile: Dockerfile
# container_name: asksql_backend
# ports:
# - "8000:8000"
# volumes:
# - ./backend:/app
# env_file:
# - ./backend/.env
# environment:
# - DB_HOST=db
# - DB_PORT=5432
# depends_on:
# - db
# networks:
# - asksql_network
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: asksql_backend
ports:
- "8000:8000"
volumes:
- ./backend:/app
env_file:
- ./backend/.env
environment:
- DB_HOST=db
- DB_PORT=5432
depends_on:
- db
networks:
- asksql_network

frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: asksql_frontend
ports:
- "3000:80"
environment:
- VITE_API_BASE_URL=http://localhost:8000/api
depends_on:
- backend
networks:
- asksql_network

db:
image: postgres:15-alpine
Expand Down
1 change: 1 addition & 0 deletions frontend/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_API_BASE_URL=http://localhost:8000/api
24 changes: 24 additions & 0 deletions frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
28 changes: 28 additions & 0 deletions frontend/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM node:18-alpine as build

WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci

# Copy source code
COPY . .

# Build the application
RUN npm run build

# Production stage with nginx
FROM nginx:alpine

# Copy built assets from build stage
COPY --from=build /app/dist /usr/share/nginx/html

# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]
19 changes: 19 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# AskSQL AI - Frontend

A high-performance React frontend featuring a premium "Midnight Sapphire" glassmorphism aesthetic.

## 🎨 Design System
- **Midnight Deep**: Dark mode by default for high visual comfort.
- **Glassmorphism**: 25px blur with subtle white borders.
- **Electric Accents**: Vibrant blues and cyans for interactive elements.
- **Typeface**: 'Outfit' for titles, 'JetBrains Mono' for code.

## 🚀 Highlights
- **Schema Explorer**: Visual modal to browse existing tables and columns.
- **Table Architect**: GUI for creating new tables (supports `int`, `text`, `float`, etc).
- **Result Playground**: High-contrast tables and syntax-highlighted SQL view.
- **Centralized API**: Typed service layer for all backend communications.

## 🛠️ Build & Run
1. `npm install`
2. `npm run dev`
23 changes: 23 additions & 0 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
14 changes: 14 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Convert natural language questions to SQL queries using AI" />
<title>AskSQL AI - Natural Language to SQL</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
28 changes: 28 additions & 0 deletions frontend/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;

# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/json application/javascript;

# SPA routing - serve index.html for all routes
location / {
try_files $uri $uri/ /index.html;
}

# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}

# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}
Loading