Spaces:
Runtime error
Runtime error
File size: 5,088 Bytes
df78000 f13132c df78000 f4ca9de df78000 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | from flask import Flask, render_template, request, session, jsonify, Response
from sqlalchemy import create_engine, text
from dotenv import load_dotenv
from init_db import init_database
import time
import os
from schemaconnector import extract
from nl_to_sql import generate_sql, explain_results
load_dotenv()
init_database()
app = Flask(__name__)
# Flask sessions require a secret key to sign the session cookie.
# Always set a secure fallback or load it from your environment (.env).
app.secret_key = os.getenv("FLASK_SECRET_KEY")
# ------------------------------------------------------------------
# Database setup
# ------------------------------------------------------------------
DATABASE_URL = os.getenv("DB_URL")
engine = create_engine(DATABASE_URL)
with engine.connect() as startup_conn:
startup_conn.execute(text("SELECT 1;"))
registry = extract(engine)
schema_context = registry.to_prompt_context()
# ------------------------------------------------------------------
# Logs
# ------------------------------------------------------------------
@app.route("/stream-logs")
def stream_logs():
def generate_log_stream():
# Change this path if you log to a dedicated text file,
# otherwise we can simulate a live application heartbeat feed
log_file_path = "app.log"
# Ensure the log file exists
if not os.path.exists(log_file_path):
with open(log_file_path, "w") as f:
f.write("[SYSTEM] Live Log Monitoring Engine Initialized.\n")
# Open the file and keep checking for new additions (like tail -f)
with open(log_file_path, "r") as f:
# Go to the end of the file first
f.seek(0, os.SEEK_END)
while True:
line = f.readline()
if not line:
time.sleep(0.5) # Pause briefly if no new log line exists
continue
yield f"data: {line}\n\n"
return Response(generate_log_stream(), mimetype="text/event-stream")
# ------------------------------------------------------------------
# Routes
# ------------------------------------------------------------------
@app.route("/", methods=["GET", "POST"])
def index():
sql = None
explanation = None
headers = []
rows = []
error = None
question = ""
metrics = None # Initialize empty metrics dictionary container
if "history" not in session:
session["history"] = []
if request.method == "POST":
question = request.form.get("question", "").strip()
if question:
try:
# 1. Generate SQL and unpack metrics payload
sql_res = generate_sql(question, schema_context, registry.tables, session["history"])
sql = sql_res["sql"]
# Execute SQL
with engine.connect() as conn:
result = conn.execute(text(sql))
headers = list(result.keys())
rows = [list(row) for row in result.fetchall()]
# 2. Generate summary explanation and unpack metrics payload
exp_res = explain_results(question, sql, rows)
explanation = exp_res["explanation"]
# Aggregate the combined performance totals
metrics = {
"sql_prompt_tokens": sql_res["prompt_tokens"],
"sql_gen_tokens": sql_res["completion_tokens"],
"exp_prompt_tokens": exp_res["prompt_tokens"],
"exp_gen_tokens": exp_res["completion_tokens"],
"total_tokens": sql_res["total_tokens"] + exp_res["total_tokens"]
}
# Manage session history updates
local_history = session["history"]
local_history.append({"role": "user", "content": question})
local_history.append({"role": "assistant", "content": sql})
if len(local_history) > 8:
del local_history[:-8]
session["history"] = local_history
except Exception as ex:
error = str(ex)
return render_template(
"index.html",
question=question,
sql=sql,
explanation=explanation,
headers=headers,
rows=rows,
error=error,
table_count=len(registry.tables),
tables=", ".join(t.name for t in registry.tables),
metrics=metrics # <-- Pass statistics to UI
)
# ------------------------------------------------------------------
# Health Check
# ------------------------------------------------------------------
@app.route("/health")
def health():
return {
"status": "ok",
"database": DATABASE_URL
}
# ------------------------------------------------------------------
# Start
# ------------------------------------------------------------------
if __name__ == "__main__":
app.run(
host="0.0.0.0",
port=int(os.getenv("PORT", 7860)),
debug=True
) |