PD03 commited on
Commit
2959765
·
verified ·
1 Parent(s): ca3ae8d

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +18 -19
app.py CHANGED
@@ -4,7 +4,7 @@ import pandas as pd
4
  import duckdb
5
  import openai
6
 
7
- # 1) Read your OpenAI key from the Space’s Secrets
8
  openai.api_key = os.getenv("OPENAI_API_KEY")
9
 
10
  # 2) Load your synthetic data into DuckDB
@@ -13,17 +13,17 @@ conn = duckdb.connect(':memory:')
13
  conn.register('sap', df)
14
 
15
  # 3) Build a one-line schema description for prompts
16
- schema = ", ".join(df.columns) # e.g. "Region,Product,FiscalYear,FiscalQuarter,Revenue,Profit,ProfitMargin"
17
 
18
- # 4) SQL-generation via OpenAI
19
  def generate_sql(question: str) -> str:
20
- system = (
21
  f"You are an expert SQL generator for a DuckDB table named `sap` "
22
  f"with columns: {schema}. "
23
- "Translate the users question into a valid SQL query and return _only_ the SQL."
24
  )
25
  messages = [
26
- {"role": "system", "content": system},
27
  {"role": "user", "content": question},
28
  ]
29
  resp = openai.ChatCompletion.create(
@@ -33,42 +33,41 @@ def generate_sql(question: str) -> str:
33
  max_tokens=150,
34
  )
35
  sql = resp.choices[0].message.content.strip()
36
- # strip triple-backticks if present
37
  if sql.startswith("```") and sql.endswith("```"):
38
  sql = "\n".join(sql.splitlines()[1:-1])
39
  return sql
40
 
41
- # 5) Core QA function: NL → SQL → execute → format
42
  def answer_profitability(question: str) -> str:
43
- # a) generate SQL
44
  sql = generate_sql(question)
45
  # b) try to run it
46
  try:
47
  result_df = conn.execute(sql).df()
48
  except Exception as e:
49
  return (
50
- f"❌ **Error executing SQL**\n\n"
51
- f"```\n{e}\n```\n\n"
52
- f"**Generated SQL**\n```sql\n{sql}\n```"
53
  )
54
  # c) format the result
55
  if result_df.empty:
56
- return f"No rows returned.\n\n**Generated SQL**\n```sql\n{sql}\n```"
57
- # single-cell → just the value
58
  if result_df.shape == (1,1):
59
  return str(result_df.iat[0,0])
60
- # otherwise, markdown table
61
  return result_df.to_markdown(index=False)
62
 
63
- # 6) Gradio UI
64
  iface = gr.Interface(
65
  fn=answer_profitability,
66
- inputs=gr.Textbox(lines=2, placeholder="Ask a question about profitability…"),
67
- outputs=gr.Markdown(), # renders errors, code, and tables nicely
68
  title="SAP Profitability Q&A (OpenAI → SQL → DuckDB)",
69
  description=(
70
  "Uses OpenAI’s GPT-3.5-Turbo to translate your question into SQL, "
71
- "executes it on the `sap` table in DuckDB, and returns the result."
72
  ),
73
  allow_flagging="never",
74
  )
 
4
  import duckdb
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
 
10
  # 2) Load your synthetic data into DuckDB
 
13
  conn.register('sap', df)
14
 
15
  # 3) Build a one-line schema description for prompts
16
+ schema = ", ".join(df.columns)
17
 
18
+ # 4) Function to generate SQL via OpenAI
19
  def generate_sql(question: str) -> str:
20
+ system_prompt = (
21
  f"You are an expert SQL generator for a DuckDB table named `sap` "
22
  f"with columns: {schema}. "
23
+ "Translate the user's question into a valid SQL query and return ONLY the SQL."
24
  )
25
  messages = [
26
+ {"role": "system", "content": system_prompt},
27
  {"role": "user", "content": question},
28
  ]
29
  resp = openai.ChatCompletion.create(
 
33
  max_tokens=150,
34
  )
35
  sql = resp.choices[0].message.content.strip()
36
+ # strip ``` if user or model wrapped it
37
  if sql.startswith("```") and sql.endswith("```"):
38
  sql = "\n".join(sql.splitlines()[1:-1])
39
  return sql
40
 
41
+ # 5) Core Q&A function: NL → SQL → execute → format
42
  def answer_profitability(question: str) -> str:
43
+ # a) turn the question into SQL
44
  sql = generate_sql(question)
45
  # b) try to run it
46
  try:
47
  result_df = conn.execute(sql).df()
48
  except Exception as e:
49
  return (
50
+ f"❌ Error executing SQL:\n{e}\n\n"
51
+ f"Generated SQL was:\n```sql\n{sql}\n```"
 
52
  )
53
  # c) format the result
54
  if result_df.empty:
55
+ return f"No rows returned.\n\n```sql\n{sql}\n```"
56
+ # single-cell → scalar
57
  if result_df.shape == (1,1):
58
  return str(result_df.iat[0,0])
59
+ # multi-cell pretty table
60
  return result_df.to_markdown(index=False)
61
 
62
+ # 6) Gradio interface with explicit outputs
63
  iface = gr.Interface(
64
  fn=answer_profitability,
65
+ inputs=gr.Textbox(lines=2, placeholder="Ask a question about profitability…", label="Question"),
66
+ outputs=gr.Textbox(lines=8, placeholder="Answer will appear here", label="Answer"),
67
  title="SAP Profitability Q&A (OpenAI → SQL → DuckDB)",
68
  description=(
69
  "Uses OpenAI’s GPT-3.5-Turbo to translate your question into SQL, "
70
+ "executes it against the `sap` table in DuckDB, and returns the result."
71
  ),
72
  allow_flagging="never",
73
  )