Spaces:
Sleeping
Sleeping
| import json | |
| import os | |
| import uvicorn | |
| import urllib.request | |
| import urllib.error | |
| from fastapi import FastAPI, Request | |
| from fastapi.responses import HTMLResponse, JSONResponse | |
| app = FastAPI() | |
| def call_gemini(prompt: str) -> str: | |
| api_key = os.environ.get("GEMINI_API_KEY", "") | |
| if not api_key: | |
| raise ValueError("GEMINI_API_KEY is not set in environment variables") | |
| url = ( | |
| "https://generativelanguage.googleapis.com/v1beta/models/" | |
| "gemini-1.5-flash:generateContent?key=" + api_key | |
| ) | |
| payload = json.dumps({ | |
| "contents": [{"parts": [{"text": prompt}]}], | |
| "generationConfig": { | |
| "temperature": 0.7, | |
| "maxOutputTokens": 1000 | |
| } | |
| }).encode("utf-8") | |
| req = urllib.request.Request( | |
| url, | |
| data=payload, | |
| headers={"Content-Type": "application/json"}, | |
| method="POST" | |
| ) | |
| try: | |
| with urllib.request.urlopen(req, timeout=30) as resp: | |
| data = json.loads(resp.read().decode("utf-8")) | |
| except urllib.error.HTTPError as e: | |
| error_body = e.read().decode("utf-8") | |
| raise ValueError("Gemini HTTP error " + str(e.code) + ": " + error_body) | |
| return data["candidates"][0]["content"]["parts"][0]["text"] | |
| async def analyze(request: Request): | |
| try: | |
| body = await request.json() | |
| user_data = body["user_data"] | |
| answers = body["answers"] | |
| scores = body["scores"] | |
| answers_text = "" | |
| for a in answers: | |
| answers_text += "- [" + a["category"] + "] " + a["question"][:60] + "... Answer: " + a["answer"][:50] + "\n" | |
| prompt = ( | |
| "You are an expert psychologist and intelligence analyst.\n" | |
| "Analyze these test results and return a JSON report.\n\n" | |
| "User: " + user_data["name"] + ", Age " + str(user_data["age"]) + ", " + user_data["edu"] + ", likes " + user_data["interest"] + "\n\n" | |
| "Scores: Logical=" + str(scores["logical"]) + " Creative=" + str(scores["creative"]) + | |
| " Spatial=" + str(scores["spatial"]) + " Verbal=" + str(scores["verbal"]) + " Emotional=" + str(scores["emotional"]) + "\n\n" | |
| "Answers:\n" + answers_text + "\n" | |
| "Return ONLY valid JSON, no markdown, no backticks, no extra text:\n" | |
| '{"intel_type":"3-4 sentences about dominant intelligence","scientist_name":"matching historical scientist","scientist_title":"their field","scientist_icon":"emoji","scientist_reason":"2-3 sentences why similar","jobs":["job1","job2","job3","job4"],"jobs_reason":"2 sentences why suitable","advice":"2-3 sentences personal advice"}' | |
| ) | |
| text = call_gemini(prompt) | |
| text = text.replace("```json", "").replace("```", "").strip() | |
| # Find JSON in response | |
| start = text.find("{") | |
| end = text.rfind("}") + 1 | |
| if start == -1 or end == 0: | |
| raise ValueError("No JSON found in response: " + text[:200]) | |
| result = json.loads(text[start:end]) | |
| return JSONResponse(content=result) | |
| except Exception as e: | |
| return JSONResponse(content={"error": str(e)}, status_code=500) | |
| async def root(): | |
| try: | |
| with open("index.html", "r", encoding="utf-8") as f: | |
| return f.read() | |
| except FileNotFoundError: | |
| return HTMLResponse("<h1>index.html not found</h1>", status_code=404) | |
| async def health(): | |
| key = os.environ.get("GEMINI_API_KEY", "") | |
| return { | |
| "status": "ok", | |
| "gemini_key_set": bool(key), | |
| "key_preview": key[:10] + "..." if key else "NOT SET" | |
| } | |
| if __name__ == "__main__": | |
| uvicorn.run(app, host="0.0.0.0", port=7860) |