rmishuk commited on
Commit
82a06d3
·
verified ·
1 Parent(s): 79ee8c8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -20
app.py CHANGED
@@ -1,19 +1,25 @@
1
  import os
2
  import gradio as gr
3
  import pandas as pd
 
 
 
 
4
  from google import genai
5
 
6
  # 1. Initialize the Gemini client securely from the environment
7
  api_key = os.environ.get('GEMINI_API_KEY')
8
  client = genai.Client(api_key=api_key)
9
 
10
- # 2. Define the core data analysis logic
11
- def analyze_data(uploaded_file, user_question):
12
- # Check if a file was actually uploaded
13
  if uploaded_file is None:
14
- return "⚠️ Please upload a CSV file first before asking a question."
15
 
16
  try:
 
 
 
17
  # Read the uploaded CSV file using Pandas
18
  df = pd.read_csv(uploaded_file.name)
19
 
@@ -24,7 +30,7 @@ def analyze_data(uploaded_file, user_question):
24
  data_preview = df.head(3).to_string()
25
  data_types = df.dtypes.to_string()
26
 
27
- # Build a robust prompt telling Gemini about the data structure
28
  system_context = (
29
  f"You are an expert Python Data Analyst. The user has uploaded a dataset.\n"
30
  f"Dataset Statistics:\n"
@@ -32,43 +38,68 @@ def analyze_data(uploaded_file, user_question):
32
  f"- Total Columns: {col_count}\n"
33
  f"- Column Names: {column_names}\n\n"
34
  f"Data Types:\n{data_types}\n\n"
35
- f"Preview of first 3 rows:\n{data_preview}\n\n"
36
- f"Please answer the user's question by performing statistical logic or providing "
37
- f"Python code snippets if requested. Always base your calculations on this data framework."
 
 
 
 
38
  )
39
 
40
- # Send the metadata context and the user query to Gemini
41
  response = client.models.generate_content(
42
  model='gemini-2.5-flash',
43
  contents=[system_context, f"User Question: {user_question}"]
44
  )
45
- return response.text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  except Exception as e:
48
- return f"❌ An error occurred processing the file: {str(e)}"
49
 
50
- # 3. Design a beautiful, custom web dashboard using Gradio Blocks
51
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
52
- gr.Markdown("# 📊 Cloud AI Data Analyst")
53
- gr.Markdown("Upload a spreadsheet dataset and ask the AI to clean it, summarize it, or uncover hidden insights.")
54
 
55
  with gr.Row():
56
  with gr.Column(scale=1):
57
  file_input = gr.File(label="Step 1: Upload CSV Dataset", file_types=[".csv"])
58
  question_input = gr.Textbox(
59
- label="Step 2: What would you like to know about this data?",
60
- placeholder="e.g., Summarize the main trends, find missing values, or calculate averages..."
61
  )
62
- submit_btn = gr.Button("Analyze Data", variant="primary")
63
 
64
  with gr.Column(scale=1):
65
- output_text = gr.Markdown(label="AI Analysis Result")
 
66
 
67
  # Connect the inputs to the function when clicking the button
68
  submit_btn.click(
69
- fn=analyze_data,
70
  inputs=[file_input, question_input],
71
- outputs=output_text
72
  )
73
 
74
  # 4. Launch the public cloud server
 
1
  import os
2
  import gradio as gr
3
  import pandas as pd
4
+ import matplotlib
5
+ # Use a non-interactive backend for Matplotlib to prevent cloud server crashes
6
+ matplotlib.use('Agg')
7
+ import matplotlib.pyplot as plt
8
  from google import genai
9
 
10
  # 1. Initialize the Gemini client securely from the environment
11
  api_key = os.environ.get('GEMINI_API_KEY')
12
  client = genai.Client(api_key=api_key)
13
 
14
+ # 2. Define the core data and plotting logic
15
+ def analyze_and_plot(uploaded_file, user_question):
 
16
  if uploaded_file is None:
17
+ return "⚠️ Please upload a CSV file first.", None
18
 
19
  try:
20
+ # Clear any previous figures to avoid overlapping graphs
21
+ plt.close('all')
22
+
23
  # Read the uploaded CSV file using Pandas
24
  df = pd.read_csv(uploaded_file.name)
25
 
 
30
  data_preview = df.head(3).to_string()
31
  data_types = df.dtypes.to_string()
32
 
33
+ # System instructions forcing Gemini to return structured code if a chart is needed
34
  system_context = (
35
  f"You are an expert Python Data Analyst. The user has uploaded a dataset.\n"
36
  f"Dataset Statistics:\n"
 
38
  f"- Total Columns: {col_count}\n"
39
  f"- Column Names: {column_names}\n\n"
40
  f"Data Types:\n{data_types}\n\n"
41
+ f"Preview:\n{data_preview}\n\n"
42
+ f"INSTRUCTIONS:\n"
43
+ f"1. Answer the user's question clearly.\n"
44
+ f"2. If the user asks for a chart, graph, or plot, you MUST include a clean Python code block "
45
+ f"that uses 'matplotlib.pyplot' to build it. Assume the dataframe is already loaded as a variable named 'df'.\n"
46
+ f"3. Crucial: The LAST line of your chart code block must save the image exactly as: plt.savefig('output_chart.png')\n"
47
+ f"4. Do not include plt.show(). Only save it to 'output_chart.png'."
48
  )
49
 
50
+ # Send the metadata context and user query to Gemini
51
  response = client.models.generate_content(
52
  model='gemini-2.5-flash',
53
  contents=[system_context, f"User Question: {user_question}"]
54
  )
55
+
56
+ text_response = response.text
57
+ chart_path = None
58
+
59
+ # Extract and execute the python code if Gemini generated a graph script
60
+ if "```python" in text_response:
61
+ try:
62
+ # Isolate the code inside the markdown blocks
63
+ code_block = text_response.split("```python")[1].split("```")[0]
64
+
65
+ # Create a safe execution environment containing the user's data
66
+ local_vars = {'df': df, 'plt': plt}
67
+ exec(code_block, {}, local_vars)
68
+
69
+ # Check if the file was successfully written by the executed code
70
+ if os.path.exists("output_chart.png"):
71
+ chart_path = "output_chart.png"
72
+ except Exception as e:
73
+ text_response += f"\n\n*(Note: There was a background error rendering the chart: {str(e)})*"
74
+
75
+ return text_response, chart_path
76
 
77
  except Exception as e:
78
+ return f"❌ An error occurred processing the file: {str(e)}", None
79
 
80
+ # 3. Design the custom layout using Gradio Blocks
81
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
82
+ gr.Markdown("# 📊 Visual Cloud AI Data Analyst")
83
+ gr.Markdown("Upload a CSV file, ask a question, or tell the AI exactly what kind of chart to build.")
84
 
85
  with gr.Row():
86
  with gr.Column(scale=1):
87
  file_input = gr.File(label="Step 1: Upload CSV Dataset", file_types=[".csv"])
88
  question_input = gr.Textbox(
89
+ label="Step 2: Ask a question or request a graph",
90
+ placeholder="e.g., 'Make a bar chart of sales by region' or 'Plot a histogram of ages'..."
91
  )
92
+ submit_btn = gr.Button("Analyze & Generate Chart", variant="primary")
93
 
94
  with gr.Column(scale=1):
95
+ output_text = gr.Markdown(label="AI Written Insights")
96
+ output_image = gr.Image(label="Generated Data Visualization", type="filepath")
97
 
98
  # Connect the inputs to the function when clicking the button
99
  submit_btn.click(
100
+ fn=analyze_and_plot,
101
  inputs=[file_input, question_input],
102
+ outputs=[output_text, output_image]
103
  )
104
 
105
  # 4. Launch the public cloud server