sroy0211 commited on
Commit
bbb205b
·
verified ·
1 Parent(s): 41eec22

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +219 -0
app.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import base64
4
+ import pandas as pd
5
+ import io
6
+ import time
7
+ import os
8
+ from io import BytesIO
9
+ from fpdf import FPDF
10
+ import tempfile
11
+ from typing import Tuple, List, Optional, Dict, Any
12
+ from PIL import Image
13
+
14
+ API_URL = "https://sroy46--insightsphere-wrapper.modal.run"
15
+
16
+ LANGUAGES = [
17
+ ("en", "English"),
18
+ ("zh", "Chinese"),
19
+ #("ja", "Japanese"),
20
+ ("ko", "Korean"),
21
+ ]
22
+
23
+ def language_name_to_code(name: str) -> str:
24
+ for code, lang_name in LANGUAGES:
25
+ if lang_name == name:
26
+ return code
27
+ return "en"
28
+
29
+ def make_api_request(endpoint: str, payload: Dict[str, Any]) -> requests.Response:
30
+ response = requests.post(
31
+ f"{API_URL}{endpoint}",
32
+ json=payload,
33
+ timeout=None
34
+ )
35
+ response.raise_for_status()
36
+ return response
37
+
38
+ def run_insightsphere(query: str, chart_types: List[str], tone: str, language_name: str) -> Tuple[str, List[Any], str, Optional[pd.DataFrame], Optional[Dict]]:
39
+ try:
40
+ language_code = language_name_to_code(language_name)
41
+ response = make_api_request("/interpret", {"query": query})
42
+ sql_query = response.json()["sql"]
43
+
44
+ response = make_api_request("/collect", {"sql": sql_query})
45
+ raw_data = pd.read_csv(io.StringIO(base64.b64decode(response.json()["data"]).decode()))
46
+
47
+ response = make_api_request("/clean", {
48
+ "data": base64.b64encode(raw_data.to_csv(index=False).encode()).decode()
49
+ })
50
+ clean_data = pd.read_csv(io.StringIO(base64.b64decode(response.json()["data"]).decode()))
51
+
52
+ response = make_api_request("/analyze", {
53
+ "data": base64.b64encode(clean_data.to_csv(index=False).encode()).decode()
54
+ })
55
+ insights = response.json()["insights"]
56
+
57
+ charts = []
58
+ clean_data_encoded = base64.b64encode(clean_data.to_csv(index=False).encode()).decode()
59
+ for chart_type in chart_types:
60
+ response = make_api_request("/visualize", {
61
+ "data": clean_data_encoded,
62
+ "insights": insights,
63
+ "chart_type": chart_type,
64
+ "tone": tone
65
+ })
66
+ img_bytes = base64.b64decode(response.json()["image"])
67
+ img = Image.open(BytesIO(img_bytes))
68
+ charts.append(img)
69
+
70
+ response = make_api_request("/summarize", {
71
+ "insights": insights,
72
+ "tone": tone,
73
+ "language_code": language_code
74
+ })
75
+ summary = response.json()["summary"]
76
+
77
+ response = make_api_request("/recommend", {
78
+ "insights": insights,
79
+ "tone": tone,
80
+ "language_code": language_code
81
+ })
82
+ recommendations = response.json()["recommendations"]
83
+
84
+ return summary, charts, recommendations, clean_data, insights
85
+
86
+ except Exception as e:
87
+ error_msg = f"Error: {str(e)}"
88
+ return error_msg, [], error_msg, None, None
89
+
90
+ def save_pdf(summary: str, charts: List[Any], recommendations: str) -> str:
91
+ pdf = FPDF()
92
+ pdf.add_page()
93
+ pdf.set_font("helvetica", size=12)
94
+
95
+ def add_unicode_text(text):
96
+ text = text.encode('latin-1', 'replace').decode('latin-1')
97
+ pdf.multi_cell(0, 10, text)
98
+
99
+ pdf.multi_cell(0, 10, "Summary:")
100
+ add_unicode_text(summary)
101
+ pdf.ln(10)
102
+
103
+ for i, img in enumerate(charts):
104
+ with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp:
105
+ img.save(tmp.name, format="PNG")
106
+ pdf.image(tmp.name, x=10, w=180)
107
+ pdf.ln(10)
108
+ try:
109
+ os.unlink(tmp.name)
110
+ except:
111
+ pass
112
+
113
+ pdf.multi_cell(0, 10, "Recommendations:")
114
+ add_unicode_text(recommendations)
115
+
116
+ tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".pdf")
117
+ pdf.output(tmp_file.name)
118
+ return tmp_file.name
119
+
120
+ def save_excel(data: pd.DataFrame, insights: Dict) -> str:
121
+ try:
122
+ tmp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".xlsx")
123
+ with pd.ExcelWriter(tmp_file.name, engine='xlsxwriter') as writer:
124
+ data.to_excel(writer, sheet_name='Clean Data', index=False)
125
+ if isinstance(insights, dict):
126
+ pd.DataFrame([insights]).to_excel(writer, sheet_name='Insights', index=False)
127
+ return tmp_file.name
128
+ except Exception as e:
129
+ raise
130
+
131
+ with gr.Blocks(title="InsightSphere", css=".gradio-container {max-width: 900px !important}") as demo:
132
+ gr.Markdown("# Your AI Agent for Multilingual Query-to-Insight Data Workflows")
133
+
134
+ with gr.Row():
135
+ with gr.Column():
136
+ query_input = gr.Textbox(
137
+ label="Enter a query to explore your data with AI:",
138
+ lines=2,
139
+ value="Show the most popular baby names in the US from 1910 to 2013, ranked by total occurrences.",
140
+ placeholder="Enter a natural language query"
141
+ )
142
+
143
+ gr.Examples(
144
+ examples=[
145
+ "List the top 10 most popular male baby names by total count from 1910 to 2013 in California.",
146
+ "Compare average income by education level across all states.",
147
+ "Summarize total agricultural yield by crop type over the past decade.",
148
+ "What are the top 5 counties with highest unemployment rates in 2019?"
149
+ ],
150
+ inputs=query_input
151
+ )
152
+
153
+ with gr.Row():
154
+ tone_input = gr.Dropdown(
155
+ label="Narrative Style for Reports",
156
+ choices=["formal", "casual", "executive"],
157
+ value="formal"
158
+ )
159
+ language_input = gr.Dropdown(
160
+ label="Select Your Preferred Language",
161
+ choices=[name for _, name in LANGUAGES],
162
+ value="English"
163
+ )
164
+
165
+ chart_type_input = gr.CheckboxGroup(
166
+ label="Select Graph Types to Visualize Insights",
167
+ choices=["histogram", "scatter", "boxplot", "bar", "line"],
168
+ value=["histogram"]
169
+ )
170
+
171
+ generate_btn = gr.Button("Generate Insights", variant="primary")
172
+
173
+ with gr.Column():
174
+ summary_output = gr.Markdown(label="### Analysis Summary")
175
+ rec_output = gr.Markdown(label="### Recommendations")
176
+ chart_gallery = gr.Gallery(
177
+ label="Generated Visualizations",
178
+ columns=2,
179
+ height="auto"
180
+ )
181
+ download_excel_btn = gr.Button("Download Data as Excel File")
182
+
183
+ state = gr.State()
184
+
185
+ def run_and_store(query: str, chart_types: List[str], tone: str, language: str):
186
+ result = run_insightsphere(query, chart_types, tone, language)
187
+ state.value = {
188
+ "summary": result[0],
189
+ "charts": result[1],
190
+ "recommendations": result[2],
191
+ "clean_data": result[3],
192
+ "insights": result[4],
193
+ }
194
+ chart_names = {
195
+ "histogram": "Distribution",
196
+ "scatter": "Scatter Plot",
197
+ "boxplot": "Box Plot",
198
+ "bar": "Bar Chart",
199
+ "line": "Line Chart"
200
+ }
201
+ display_images = []
202
+ for i, img in enumerate(result[1]):
203
+ chart_type = chart_types[i] if i < len(chart_types) else "chart"
204
+ display_images.append((img, f"{chart_names.get(chart_type, 'Chart')} {i+1}"))
205
+ return result[0], display_images, result[2]
206
+
207
+ generate_btn.click(
208
+ run_and_store,
209
+ inputs=[query_input, chart_type_input, tone_input, language_input],
210
+ outputs=[summary_output, chart_gallery, rec_output]
211
+ )
212
+
213
+ download_excel_btn.click(
214
+ lambda: save_excel(state.value["clean_data"], state.value["insights"]) if state.value else None,
215
+ outputs=gr.File(label="Download Excel Report")
216
+ )
217
+
218
+ if __name__ == "__main__":
219
+ demo.launch(server_name="0.0.0.0", server_port=7860, share=False)