bluenevus commited on
Commit
23a3b49
·
verified ·
1 Parent(s): 12ce912

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -124
app.py CHANGED
@@ -3,145 +3,61 @@ import pandas as pd
3
  import matplotlib.pyplot as plt
4
  import io
5
  import google.generativeai as genai
6
- from PIL import Image
7
  import ast
8
  import re
9
  import traceback
10
 
11
  def process_file(api_key, file, instructions):
12
- # Configure Gemini API with error handling
13
- try:
14
- genai.configure(api_key=api_key)
15
- model = genai.GenerativeModel('gemini-2.5-pro-preview-03-25')
16
- except Exception as e:
17
- return [generate_error_image(f"API Config Error: {str(e)}")] * 3
18
-
19
- # Load data with validation
20
- try:
21
- if file.name.endswith('.csv'):
22
- df = pd.read_csv(file.name)
23
- else:
24
- df = pd.read_excel(file.name)
25
-
26
- if df.empty:
27
- raise ValueError("Empty dataset uploaded")
28
- if len(df.columns) < 2:
29
- raise ValueError("Dataset needs at least 2 columns")
30
- except Exception as e:
31
- return [generate_error_image(f"Data Error: {str(e)}")] * 3
32
-
33
- # Enhanced prompt with strict formatting
34
- prompt = f"""Generate 3 Python matplotlib codes with these rules:
35
- 1. Perfect Python 3.10 syntax with 4-space indentation
36
- 2. Complete code blocks with proper indentation
37
- 3. Use ONLY these variables: df, plt
38
- 4. Each visualization must:
39
- - Start with: plt.figure(figsize=(16,9), dpi=120)
40
- - Use plt.style.use('ggplot')
41
- - Include title, axis labels, and data visualization
42
- - End with plt.tight_layout()
43
-
44
- Dataset Columns: {list(df.columns)}
45
- Data Sample: {df.head(3).to_dict()}
46
- User Instructions: {instructions or 'Show general trends'}
47
-
48
- Format EXACTLY as:
49
- # Visualization 1
50
- [properly indented code]
51
-
52
- # Visualization 2
53
- [properly indented code]
54
-
55
- # Visualization 3
56
- [properly indented code]
57
- """
58
-
59
- # Get and process Gemini response
60
- try:
61
- response = model.generate_content(prompt)
62
- code_blocks = re.split(r'# Visualization \d+\s*', response.text)[1:4]
63
- except Exception as e:
64
- return [generate_error_image("API Response Error")] * 3
65
-
66
- visualizations = []
67
- for i, block in enumerate(code_blocks, 1):
68
- try:
69
- # Clean and validate code
70
- cleaned_code = sanitize_code(block, df.columns)
71
- img = execute_plot_code(cleaned_code, df)
72
- visualizations.append(img)
73
- except Exception as e:
74
- print(f"Visualization {i} Error:\n{traceback.format_exc()}")
75
- visualizations.append(generate_error_image(f"Error in Viz {i}"))
76
-
77
- # Ensure exactly 3 outputs
78
- return visualizations + [generate_error_image("Not Generated")]*(3-len(visualizations))
79
 
80
  def sanitize_code(code_block, columns):
81
- """Fix indentation and syntax issues in generated code"""
82
- lines = []
83
- indent_level = 0
84
- indent_size = 4
85
- stack = []
86
 
87
- for line in code_block.split('\n'):
88
- line = line.rstrip()
89
- if not line:
90
- continue
91
 
92
- # Remove markdown artifacts
93
- line = re.sub(r'^```python|```$', '', line)
 
 
 
94
 
95
- # Handle indentation triggers
96
- if re.match(r'^\s*(for|if|while|with|def|class|try|except|else|elif)\b', line):
97
- stack.append(indent_level)
98
- indent_level += 1
99
- elif re.match(r'^\s*(return|pass|break|continue|raise)', line):
100
- indent_level = max(0, indent_level - 1)
101
 
102
- # Apply current indentation
103
- current_indent = ' ' * (indent_level * indent_size)
104
- cleaned_line = current_indent + line.lstrip()
 
105
 
106
- # Check for dedent patterns
107
- if re.match(r'^\s*(\}|\)|]|else:|elif |except)', line):
108
- if stack:
109
- indent_level = stack.pop()
110
 
111
- lines.append(cleaned_line)
 
 
 
 
 
 
 
112
 
113
- cleaned_code = '\n'.join(lines)
 
 
114
 
115
- # Validate syntax
116
- try:
117
- ast.parse(cleaned_code)
118
- except SyntaxError as e:
119
- raise ValueError(f"Syntax Error: {str(e)}")
120
 
121
- return cleaned_code
 
122
 
123
- def execute_plot_code(code, df):
124
- """Safely execute plotting code with resource management"""
125
- buf = io.BytesIO()
126
- plt.figure(figsize=(16, 9), dpi=120)
127
- plt.style.use('ggplot')
128
-
129
- try:
130
- exec(code, {'df': df, 'plt': plt})
131
- plt.tight_layout()
132
- plt.savefig(buf, format='png', bbox_inches='tight')
133
- buf.seek(0)
134
- return Image.open(buf)
135
- except Exception as e:
136
- raise RuntimeError(f"Execution Error: {str(e)}")
137
- finally:
138
- plt.close()
139
 
140
- def generate_error_image(message):
141
- """Create error indication image with message"""
142
- from PIL import ImageDraw, ImageFont
143
-
144
- img = Image.new('RGB', (1920, 1080), color=(255, 255, 255))
145
- try:
146
- draw = ImageDraw.Draw(img)
147
- font = ImageFont
 
3
  import matplotlib.pyplot as plt
4
  import io
5
  import google.generativeai as genai
6
+ from PIL import Image, ImageDraw, ImageFont
7
  import ast
8
  import re
9
  import traceback
10
 
11
  def process_file(api_key, file, instructions):
12
+ # ... [keep the existing process_file function exactly as before] ...
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
  def sanitize_code(code_block, columns):
15
+ # ... [keep the existing sanitize_code function exactly as before] ...
 
 
 
 
16
 
17
+ def execute_plot_code(code, df):
18
+ # ... [keep the existing execute_plot_code function exactly as before] ...
 
 
19
 
20
+ def generate_error_image(message):
21
+ """Create error indication image with message"""
22
+ try:
23
+ img = Image.new('RGB', (1920, 1080), color=(255, 255, 255))
24
+ draw = ImageDraw.Draw(img)
25
 
26
+ # Use default font
27
+ font = ImageFont.load_default()
 
 
 
 
28
 
29
+ # Calculate text position
30
+ text_width, text_height = draw.textsize(message, font=font)
31
+ x = (1920 - text_width) / 2
32
+ y = (1080 - text_height) / 2
33
 
34
+ # Draw message
35
+ draw.text((x, y), message, font=font, fill=(255, 0, 0))
 
 
36
 
37
+ return img
38
+ except Exception as e:
39
+ # Fallback if text rendering fails
40
+ return Image.new('RGB', (1920, 1080), color=(255, 255, 255))
41
+
42
+ # Gradio interface
43
+ with gr.Blocks(theme=gr.themes.Default(spacing_size="lg")) as demo:
44
+ gr.Markdown("# Professional Data Visualizer")
45
 
46
+ with gr.Row():
47
+ api_key = gr.Textbox(label="Gemini API Key", type="password")
48
+ file = gr.File(label="Upload Data File", file_types=[".csv", ".xlsx"])
49
 
50
+ instructions = gr.Textbox(label="Visualization Instructions")
51
+ submit = gr.Button("Generate Insights", variant="primary")
 
 
 
52
 
53
+ with gr.Row():
54
+ outputs = [gr.Image(label=f"Visualization {i+1}", width=600) for i in range(3)]
55
 
56
+ submit.click(
57
+ process_file,
58
+ inputs=[api_key, file, instructions],
59
+ outputs=outputs
60
+ )
 
 
 
 
 
 
 
 
 
 
 
61
 
62
+ if __name__ == "__main__":
63
+ demo.launch()