PD03 commited on
Commit
08892e7
·
verified ·
1 Parent(s): 2abeceb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -50
app.py CHANGED
@@ -5,84 +5,68 @@ import duckdb
5
  import openai
6
 
7
  # 1) Load your OpenAI key from the Space’s Secrets
8
- OPENAI_KEY = os.getenv("OPENAI_API_KEY")
9
- if not OPENAI_KEY:
10
  raise RuntimeError("Missing OPENAI_API_KEY secret in your Space settings")
11
- openai.api_key = OPENAI_KEY
12
 
13
- # 2) Load your synthetic data into DuckDB
14
- df = pd.read_csv('synthetic_profit.csv')
15
- conn = duckdb.connect(':memory:')
16
- conn.register('sap', df)
17
 
18
- # 3) Build a one-line schema description for prompts
19
  schema = ", ".join(df.columns)
20
 
21
- # 4) Function to generate SQL via OpenAI
22
  def generate_sql(question: str) -> str:
23
- system_prompt = (
24
- f"You are an expert SQL generator for a DuckDB table named `sap` "
25
- f"with columns: {schema}. "
26
- "Translate the user's question into a valid SQL query and return ONLY the SQL."
 
 
 
 
 
 
 
 
 
27
  )
28
- try:
29
- resp = openai.ChatCompletion.create(
30
- model="gpt-3.5-turbo",
31
- messages=[
32
- {"role": "system", "content": system_prompt},
33
- {"role": "user", "content": question},
34
- ],
35
- temperature=0.0,
36
- max_tokens=150,
37
- )
38
- except Exception as e:
39
- # Catch network/auth errors
40
- raise RuntimeError(f"OpenAI API error: {e}")
41
-
42
  sql = resp.choices[0].message.content.strip()
43
- # strip triple-backticks if present
44
  if sql.startswith("```") and sql.endswith("```"):
45
  sql = "\n".join(sql.splitlines()[1:-1])
46
  return sql
47
 
48
- # 5) Core Q&A function: NL SQL → execute → format
49
  def answer_profitability(question: str) -> str:
50
- # a) turn the question into SQL
51
  try:
52
  sql = generate_sql(question)
53
  except Exception as e:
54
- return f"❌ **OpenAI Error**\n{e}"
55
 
56
- # b) try to run it
57
  try:
58
  result_df = conn.execute(sql).df()
59
  except Exception as e:
60
- return (
61
- f"❌ **SQL Execution Error**\n{e}\n\n"
62
- f"**Generated SQL**\n```sql\n{sql}\n```"
63
- )
64
 
65
- # c) format the result
66
  if result_df.empty:
67
- return f"No rows returned.\n\n```sql\n{sql}\n```"
68
-
69
- # single-cell → scalar
70
  if result_df.shape == (1,1):
71
  return str(result_df.iat[0,0])
72
-
73
- # multi-cell → markdown table
74
  return result_df.to_markdown(index=False)
75
 
76
- # 6) Gradio interface with explicit inputs & outputs
77
  iface = gr.Interface(
78
  fn=answer_profitability,
79
- inputs=gr.Textbox(lines=2, placeholder="Ask a question about profitability…", label="Question"),
80
- outputs=gr.Textbox(lines=8, placeholder="Answer will appear here", label="Answer"),
81
- title="SAP Profitability Q&A (OpenAI SQL DuckDB)",
82
- description=(
83
- "Uses OpenAI’s GPT-3.5-Turbo to translate your question into SQL, "
84
- "executes it against the `sap` table in DuckDB, and returns the result."
85
- ),
86
  allow_flagging="never",
87
  )
88
 
 
5
  import openai
6
 
7
  # 1) Load your OpenAI key from the Space’s Secrets
8
+ openai.api_key = os.getenv("OPENAI_API_KEY")
9
+ if not openai.api_key:
10
  raise RuntimeError("Missing OPENAI_API_KEY secret in your Space settings")
 
11
 
12
+ # 2) Load your CSV into DuckDB
13
+ df = pd.read_csv("synthetic_profit.csv")
14
+ conn = duckdb.connect(":memory:")
15
+ conn.register("sap", df)
16
 
17
+ # 3) Build a one-line schema string for prompting
18
  schema = ", ".join(df.columns)
19
 
20
+ # 4) Function to call OpenAI and get back a SQL string
21
  def generate_sql(question: str) -> str:
22
+ system = (
23
+ f"You are an expert SQL generator for DuckDB table `sap` with columns: {schema}. "
24
+ "Translate the user’s question into a valid SQL query. "
25
+ "Return ONLY the SQL, no explanation."
26
+ )
27
+ resp = openai.ChatCompletion.create(
28
+ model="gpt-3.5-turbo",
29
+ messages=[
30
+ {"role": "system", "content": system},
31
+ {"role": "user", "content": question}
32
+ ],
33
+ temperature=0.0,
34
+ max_tokens=150,
35
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  sql = resp.choices[0].message.content.strip()
37
+ # Strip ``` if present
38
  if sql.startswith("```") and sql.endswith("```"):
39
  sql = "\n".join(sql.splitlines()[1:-1])
40
  return sql
41
 
42
+ # 5) The function Gradio will call
43
  def answer_profitability(question: str) -> str:
44
+ # a) Generate the SQL
45
  try:
46
  sql = generate_sql(question)
47
  except Exception as e:
48
+ return f"❌ OpenAI error:\n{e}"
49
 
50
+ # b) Execute it in DuckDB
51
  try:
52
  result_df = conn.execute(sql).df()
53
  except Exception as e:
54
+ return f"❌ SQL error:\n{e}\n\nGenerated SQL:\n```sql\n{sql}\n```"
 
 
 
55
 
56
+ # c) Format the output
57
  if result_df.empty:
58
+ return f"No results.\n\nSQL was:\n```sql\n{sql}\n```"
 
 
59
  if result_df.shape == (1,1):
60
  return str(result_df.iat[0,0])
 
 
61
  return result_df.to_markdown(index=False)
62
 
63
+ # 6) Gradio interface—**note the explicit outputs=…**
64
  iface = gr.Interface(
65
  fn=answer_profitability,
66
+ inputs=gr.Textbox(lines=2, placeholder="Ask a question…", label="Question"),
67
+ outputs=gr.Textbox(lines=8, placeholder="Answer appears here", label="Answer"),
68
+ title="SAP Profitability Q&A (OpenAI→SQL→DuckDB)",
69
+ description="Enter a natural-language question and get back the numeric result or table.",
 
 
 
70
  allow_flagging="never",
71
  )
72