Spaces:
Sleeping
Sleeping
File size: 7,773 Bytes
c426d0d 684eb72 7e83507 aff0db3 684eb72 aff0db3 c426d0d aff0db3 7e83507 a7b6807 aff0db3 c426d0d aff0db3 743d09e 7e83507 743d09e aff0db3 684eb72 aff0db3 9bcbc93 c426d0d aff0db3 684eb72 9bcbc93 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 c426d0d 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 9e8adcf 684eb72 aff0db3 684eb72 5e79371 a7b6807 c426d0d aff0db3 684eb72 9bcbc93 7e83507 9bcbc93 7e83507 684eb72 7e83507 a7b6807 7e83507 5e79371 684eb72 5e79371 684eb72 7e83507 684eb72 7e83507 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | import time
import json
import requests
import traceback
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
app = FastAPI(title="Gemini AI Dashboard API")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
API_KEYS = [
"AIzaSyAIo-DJ1iTwoP-jaU0rhhHgojxMdXCDhB8",
"AIzaSyASgxIkI7xM2QwcNBOUWT7sDqpBRKAOvYs"
]
class AnalysisRequest(BaseModel):
text: str
task: str = "dashboard"
@app.get("/")
async def root():
return {"status": "running", "message": "API is online."}
@app.get("/health")
async def health_check():
return {"status": "healthy"}
def get_best_free_model_and_key():
for api_key in API_KEYS:
list_url = f"https://generativelanguage.googleapis.com/v1beta/models?key={api_key}"
try:
resp = requests.get(list_url, timeout=10)
if resp.status_code == 200:
data = resp.json()
available_models = data.get("models", [])
flash_models = []
other_models = []
for model in available_models:
if "generateContent" in model.get("supportedGenerationMethods", []):
name = model["name"].replace("models/", "")
if "flash" in name.lower():
flash_models.append(name)
else:
other_models.append(name)
if flash_models:
return flash_models[0], api_key
elif other_models:
return other_models[0], api_key
except Exception as e:
print(f"Error fetching models for key {api_key[-4:]}: {e}")
pass
return None, None
@app.post("/dashboard")
async def generate_dashboard(request: AnalysisRequest):
start_time = time.time()
input_data = request.text[:15000]
model_name, working_key = get_best_free_model_and_key()
if not model_name:
raise HTTPException(status_code=500, detail="No free models available for your API keys.")
print(f"Using model: {model_name} with key ending in ...{working_key[-4:]}")
prompt = f"""
You are a strict, mathematically precise Data Analyst AI.
Your job is to analyze the provided raw data and calculate exact metrics.
CRITICAL INSTRUCTIONS:
1. You MUST actually read the data, count the rows, and sum the numbers.
2. DO NOT hallucinate, guess, or use placeholder numbers.
3. If you cannot calculate a specific number, do not include it.
4. All "value" fields in charts and metrics MUST be real numbers calculated directly from the data provided.
The raw data to analyze is:
---
{input_data}
---
You MUST return ONLY a valid JSON object with this exact structure.
Replace all <placeholders> with actual calculated values from the data.
{{
"summary": "A factual summary of exactly what the data is and the most obvious mathematical trend.",
"metrics": [
{{"label": "<Exact Metric Name 1>", "value": "<Exact Calculated Value>", "change": "<Exact Change if available, else N/A>"}},
{{"label": "<Exact Metric Name 2>", "value": "<Exact Calculated Value>", "change": "<Exact Change if available, else N/A>"}},
{{"label": "<Exact Metric Name 3>", "value": "<Exact Calculated Value>", "change": "<Exact Change if available, else N/A>"}},
{{"label": "<Exact Metric Name 4>", "value": "<Exact Calculated Value>", "change": "<Exact Change if available, else N/A>"}}
],
"charts": [
{{
"type": "bar",
"title": "<Title based on data categories>",
"data": [{{"name": "<Category 1>", "value": <Exact Sum or Count>}}, {{"name": "<Category 2>", "value": <Exact Sum or Count>}}]
}},
{{
"type": "pie",
"title": "<Title based on data distribution>",
"data": [{{"name": "<Segment 1>", "value": <Exact Count>}}, {{"name": "<Segment 2>", "value": <Exact Count>}}]
}}
],
"insights": ["Factual finding 1 based on the numbers", "Factual finding 2 based on the numbers"],
"recommendations": ["Actionable recommendation based strictly on the data"],
"risks": ["Risk identified in the data"],
"opportunities": ["Opportunity identified in the data"],
"tables": [
{{
"title": "Data Sample Breakdown",
"headers": ["<Col 1>", "<Col 2>", "<Col 3>"],
"rows": [
["<Actual Row 1 Data>", "<Actual Row 1 Data>", "<Actual Row 1 Data>"],
["<Actual Row 2 Data>", "<Actual Row 2 Data>", "<Actual Row 2 Data>"]
]
}}
],
"confidence_score": 90,
"dataset_info": {{
"name": "<Inferred Dataset Name>",
"records": <Exact count of rows/records in the data>,
"columns": <Exact count of columns/fields in the data>,
"detected_type": "<Type of data>",
"upload_time": "0.1s",
"processing_time": "1.2s"
}}
}}
"""
payload = {
"contents": [{"parts": [{"text": prompt}]}],
"generationConfig": {
"temperature": 0.1,
"maxOutputTokens": 8000
}
}
url = f"https://generativelanguage.googleapis.com/v1beta/models/{model_name}:generateContent?key={working_key}"
try:
response = requests.post(url, json=payload, headers={"Content-Type": "application/json"}, timeout=45)
if response.status_code != 200:
error_msg = f"Gemini API Error {response.status_code}: {response.text}"
print(error_msg)
raise HTTPException(status_code=500, detail=error_msg)
gemini_result = response.json()
if 'candidates' in gemini_result and len(gemini_result['candidates']) > 0:
if 'content' in gemini_result['candidates'][0] and 'parts' in gemini_result['candidates'][0]['content']:
raw_text = gemini_result['candidates'][0]['content']['parts'][0]['text']
else:
error_msg = f"Gemini blocked the prompt. Full response: {json.dumps(gemini_result)}"
print(error_msg)
raise HTTPException(status_code=500, detail=error_msg)
else:
error_msg = f"Gemini returned no candidates. Full response: {json.dumps(gemini_result)}"
print(error_msg)
raise HTTPException(status_code=500, detail=error_msg)
if raw_text.startswith("```json"):
raw_text = raw_text[7:]
if raw_text.endswith("```"):
raw_text = raw_text[:-3]
# --- ADDED JSON PARSE ERROR HANDLING ---
try:
dashboard_data = json.loads(raw_text.strip())
except json.JSONDecodeError:
print(f"JSON Parse Error. Raw text from AI: {raw_text}")
raise HTTPException(status_code=500, detail="The AI returned an empty or invalid JSON response. Please try again.")
processing_time = f"{time.time() - start_time:.1f}s"
if 'dataset_info' in dashboard_data:
dashboard_data['dataset_info']['processing_time'] = processing_time
else:
dashboard_data['dataset_info'] = {"processing_time": processing_time}
return dashboard_data
except HTTPException:
raise
except Exception as e:
traceback.print_exc()
raise HTTPException(status_code=500, detail=f"Internal Server Error: {str(e)}") |