Spaces:
Sleeping
Sleeping
File size: 2,924 Bytes
e784f1e a5ece8b aa97025 519d64c e784f1e 887b999 2959765 2abeceb e784f1e ca3ae8d aa97025 e784f1e 60fddfe ca3ae8d 2959765 e784f1e 2959765 e784f1e 2959765 e784f1e 2959765 e784f1e 2abeceb e784f1e 2abeceb ca3ae8d e784f1e 8cc354c 2959765 e784f1e 2959765 2abeceb ca3ae8d 67fc297 ca3ae8d 67fc297 79c9d08 2abeceb 79c9d08 2abeceb ca3ae8d 2959765 2abeceb 2959765 ca3ae8d 2abeceb ca3ae8d 79c9d08 2abeceb e784f1e 2959765 e784f1e 2959765 e784f1e 79c9d08 e784f1e |
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 |
import os
import gradio as gr
import pandas as pd
import duckdb
import openai
# 1) Load your OpenAI key from the Space’s Secrets
OPENAI_KEY = os.getenv("OPENAI_API_KEY")
if not OPENAI_KEY:
raise RuntimeError("Missing OPENAI_API_KEY secret in your Space settings")
openai.api_key = OPENAI_KEY
# 2) Load your synthetic data into DuckDB
df = pd.read_csv('synthetic_profit.csv')
conn = duckdb.connect(':memory:')
conn.register('sap', df)
# 3) Build a one-line schema description for prompts
schema = ", ".join(df.columns)
# 4) Function to generate SQL via OpenAI
def generate_sql(question: str) -> str:
system_prompt = (
f"You are an expert SQL generator for a DuckDB table named `sap` "
f"with columns: {schema}. "
"Translate the user's question into a valid SQL query and return ONLY the SQL."
)
try:
resp = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": question},
],
temperature=0.0,
max_tokens=150,
)
except Exception as e:
# Catch network/auth errors
raise RuntimeError(f"OpenAI API error: {e}")
sql = resp.choices[0].message.content.strip()
# strip triple-backticks if present
if sql.startswith("```") and sql.endswith("```"):
sql = "\n".join(sql.splitlines()[1:-1])
return sql
# 5) Core Q&A function: NL → SQL → execute → format
def answer_profitability(question: str) -> str:
# a) turn the question into SQL
try:
sql = generate_sql(question)
except Exception as e:
return f"❌ **OpenAI Error**\n{e}"
# b) try to run it
try:
result_df = conn.execute(sql).df()
except Exception as e:
return (
f"❌ **SQL Execution Error**\n{e}\n\n"
f"**Generated SQL**\n```sql\n{sql}\n```"
)
# c) format the result
if result_df.empty:
return f"No rows returned.\n\n```sql\n{sql}\n```"
# single-cell → scalar
if result_df.shape == (1,1):
return str(result_df.iat[0,0])
# multi-cell → markdown table
return result_df.to_markdown(index=False)
# 6) Gradio interface with explicit inputs & outputs
iface = gr.Interface(
fn=answer_profitability,
inputs=gr.Textbox(lines=2, placeholder="Ask a question about profitability…", label="Question"),
outputs=gr.Textbox(lines=8, placeholder="Answer will appear here", label="Answer"),
title="SAP Profitability Q&A (OpenAI → SQL → DuckDB)",
description=(
"Uses OpenAI’s GPT-3.5-Turbo to translate your question into SQL, "
"executes it against the `sap` table in DuckDB, and returns the result."
),
allow_flagging="never",
)
if __name__ == "__main__":
iface.launch(server_name="0.0.0.0", server_port=7860)
|