triflix commited on
Commit
0cbcf4a
Β·
verified Β·
1 Parent(s): 908f218

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -26
app.py CHANGED
@@ -1,18 +1,17 @@
1
- from fastapi import FastAPI, Request, File, UploadFile, Form
2
- from fastapi.responses import StreamingResponse, JSONResponse, HTMLResponse
3
- from fastapi.staticfiles import StaticFiles
4
- from fastapi.templating import Jinja2Templates
5
  import pandas as pd
6
  from google import genai
7
  from google.genai import types
8
  import os
9
  import json
10
  import asyncio
 
11
 
12
  # -------------------------------
13
  # πŸ”‘ Configuration
14
  # -------------------------------
15
- API_KEY = os.getenv("GEMINI_API_KEY", "AIzaSyB1jgGCuzg7ELPwNEEwaluQZoZhxhgLmAs")
16
  MODEL = "gemini-2.5-flash-lite"
17
  client = genai.Client(api_key=API_KEY)
18
 
@@ -20,33 +19,56 @@ client = genai.Client(api_key=API_KEY)
20
  # ⚑ FastAPI Setup
21
  # -------------------------------
22
  app = FastAPI()
23
- app.mount("/static", StaticFiles(directory="static"), name="static")
24
- templates = Jinja2Templates(directory="templates")
 
 
 
 
 
 
 
25
 
26
  # -------------------------------
27
  # πŸ› οΈ Helper Functions
28
  # -------------------------------
29
  def get_metadata(df: pd.DataFrame):
30
- return {
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  "columns": list(df.columns),
32
  "dtypes": df.dtypes.apply(lambda x: str(x)).to_dict(),
33
  "num_rows": df.shape[0],
34
  "num_cols": df.shape[1],
35
- "null_counts": df.isnull().sum().to_dict(),
36
- "unique_counts": df.nunique().to_dict(),
37
- "sample_rows": df.head(3).to_dict(orient="records"),
 
 
 
38
  }
 
39
 
40
  async def stream_insights(user_query, metadata):
41
- """Generator that yields insights step by step as text/json strings."""
42
-
43
- # Step 1: Start message
44
  yield json.dumps({"status": "started", "message": "File received. Extracting metadata..."}) + "\n"
45
- await asyncio.sleep(0.5)
46
 
47
  # Step 2: Metadata
48
  yield json.dumps({"status": "metadata", "metadata": metadata}) + "\n"
49
- await asyncio.sleep(0.5)
50
 
51
  # Step 3: Call Gemini for structured insights
52
  system_prompt = """
@@ -89,16 +111,16 @@ async def stream_insights(user_query, metadata):
89
 
90
  # Step 4: Excel info
91
  yield json.dumps({"status": "excel_info", "excel_info": parsed.get("excel_info", {})}) + "\n"
92
- await asyncio.sleep(0.5)
93
 
94
  # Step 5: Data type context
95
  yield json.dumps({"status": "context", "data_type_context": parsed.get("data_type_context", "")}) + "\n"
96
- await asyncio.sleep(0.5)
97
 
98
- # Step 6: Stream each insight one by one
99
  for insight in parsed.get("auto_insights", {}).get("insights", []):
100
  yield json.dumps({"status": "insight", "insight": insight}) + "\n"
101
- await asyncio.sleep(0.5)
102
 
103
  # Step 7: Query insights
104
  yield json.dumps({"status": "query", "query_insights": parsed.get("query_insights", {})}) + "\n"
@@ -106,14 +128,9 @@ async def stream_insights(user_query, metadata):
106
  # Step 8: Completed
107
  yield json.dumps({"status": "completed", "message": "All insights generated"}) + "\n"
108
 
109
-
110
  # -------------------------------
111
- # 🌐 Routes
112
  # -------------------------------
113
- @app.get("/", response_class=HTMLResponse)
114
- async def home(request: Request):
115
- return templates.TemplateResponse("index.html", {"request": request})
116
-
117
  @app.post("/stream_insights")
118
  async def stream_insight_file(file: UploadFile = File(...), query: str = Form("Analyze the dataset")):
119
  """Stream structured JSON insights step by step."""
 
1
+ from fastapi import FastAPI, File, UploadFile, Form, JSONResponse, StreamingResponse
2
+ from fastapi.middleware.cors import CORSMiddleware
 
 
3
  import pandas as pd
4
  from google import genai
5
  from google.genai import types
6
  import os
7
  import json
8
  import asyncio
9
+ import numpy as np
10
 
11
  # -------------------------------
12
  # πŸ”‘ Configuration
13
  # -------------------------------
14
+ API_KEY = os.getenv("GEMINI_API_KEY", "YOUR_GEMINI_KEY")
15
  MODEL = "gemini-2.5-flash-lite"
16
  client = genai.Client(api_key=API_KEY)
17
 
 
19
  # ⚑ FastAPI Setup
20
  # -------------------------------
21
  app = FastAPI()
22
+
23
+ # Enable CORS for all origins
24
+ app.add_middleware(
25
+ CORSMiddleware,
26
+ allow_origins=["*"], # or specify your frontend URLs
27
+ allow_credentials=True,
28
+ allow_methods=["*"],
29
+ allow_headers=["*"],
30
+ )
31
 
32
  # -------------------------------
33
  # πŸ› οΈ Helper Functions
34
  # -------------------------------
35
  def get_metadata(df: pd.DataFrame):
36
+ """Extract JSON-serializable metadata."""
37
+ def serialize_value(x):
38
+ if isinstance(x, pd.Timestamp):
39
+ return x.isoformat()
40
+ elif isinstance(x, (np.integer, np.int64, np.int32)):
41
+ return int(x)
42
+ elif isinstance(x, (np.floating, np.float64, np.float32)):
43
+ return float(x)
44
+ elif pd.isna(x):
45
+ return None
46
+ else:
47
+ return x
48
+
49
+ metadata = {
50
  "columns": list(df.columns),
51
  "dtypes": df.dtypes.apply(lambda x: str(x)).to_dict(),
52
  "num_rows": df.shape[0],
53
  "num_cols": df.shape[1],
54
+ "null_counts": {k: int(v) for k, v in df.isnull().sum().to_dict().items()},
55
+ "unique_counts": {k: int(v) for k, v in df.nunique().to_dict().items()},
56
+ "sample_rows": [
57
+ {col: serialize_value(val) for col, val in row.items()}
58
+ for row in df.head(3).to_dict(orient="records")
59
+ ],
60
  }
61
+ return metadata
62
 
63
  async def stream_insights(user_query, metadata):
64
+ """Generator that yields insights step by step as JSON strings."""
65
+ # Step 1: Start
 
66
  yield json.dumps({"status": "started", "message": "File received. Extracting metadata..."}) + "\n"
67
+ await asyncio.sleep(0.2)
68
 
69
  # Step 2: Metadata
70
  yield json.dumps({"status": "metadata", "metadata": metadata}) + "\n"
71
+ await asyncio.sleep(0.2)
72
 
73
  # Step 3: Call Gemini for structured insights
74
  system_prompt = """
 
111
 
112
  # Step 4: Excel info
113
  yield json.dumps({"status": "excel_info", "excel_info": parsed.get("excel_info", {})}) + "\n"
114
+ await asyncio.sleep(0.2)
115
 
116
  # Step 5: Data type context
117
  yield json.dumps({"status": "context", "data_type_context": parsed.get("data_type_context", "")}) + "\n"
118
+ await asyncio.sleep(0.2)
119
 
120
+ # Step 6: Stream each insight
121
  for insight in parsed.get("auto_insights", {}).get("insights", []):
122
  yield json.dumps({"status": "insight", "insight": insight}) + "\n"
123
+ await asyncio.sleep(0.2)
124
 
125
  # Step 7: Query insights
126
  yield json.dumps({"status": "query", "query_insights": parsed.get("query_insights", {})}) + "\n"
 
128
  # Step 8: Completed
129
  yield json.dumps({"status": "completed", "message": "All insights generated"}) + "\n"
130
 
 
131
  # -------------------------------
132
+ # 🌐 API Routes
133
  # -------------------------------
 
 
 
 
134
  @app.post("/stream_insights")
135
  async def stream_insight_file(file: UploadFile = File(...), query: str = Form("Analyze the dataset")):
136
  """Stream structured JSON insights step by step."""