Spaces:
Sleeping
Sleeping
| import csv | |
| import os | |
| import tempfile | |
| from datetime import datetime | |
| import requests | |
| from flask import Flask, request, jsonify, send_from_directory, session | |
| from flask_cors import CORS | |
| import firebase_admin | |
| from firebase_admin import credentials, firestore, auth as firebase_auth | |
| # ================== APP SETUP ================== | |
| app = Flask(__name__, static_folder='.', template_folder='.') | |
| app.secret_key = os.environ.get("FLASK_SECRET_KEY", "dev-secret") | |
| app.config.update( | |
| SESSION_COOKIE_SAMESITE="None", | |
| SESSION_COOKIE_SECURE=True | |
| ) | |
| CORS(app, supports_credentials=True) | |
| # ================== FIREBASE INIT ================== | |
| db = None | |
| firebase_json = os.environ.get("FIREBASE_CREDENTIALS_JSON") | |
| if firebase_json: | |
| fd, path = tempfile.mkstemp(suffix=".json") | |
| with os.fdopen(fd, "w") as f: | |
| f.write(firebase_json) | |
| cred = credentials.Certificate(path) | |
| firebase_admin.initialize_app(cred) | |
| db = firestore.client() | |
| print("Firebase initialized") | |
| else: | |
| print("FIREBASE_CREDENTIALS_JSON not set") | |
| # ================== GEMINI CONFIG ================== | |
| GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY") | |
| GEMINI_URL = ( | |
| "https://generativelanguage.googleapis.com/v1/models/" | |
| "gemini-1.5-flash-latest:generateContent" | |
| ) | |
| # ================== HELPERS ================== | |
| def is_logged_in(): | |
| return "uid" in session | |
| # ================== AUTH ROUTES ================== | |
| def api_login(): | |
| try: | |
| token = request.json.get("token") | |
| decoded = firebase_auth.verify_id_token(token) | |
| session["uid"] = decoded["uid"] | |
| session["email"] = decoded.get("email") | |
| session["name"] = decoded.get("name") | |
| session["picture"] = decoded.get("picture") | |
| return jsonify({"ok": True}) | |
| except Exception as e: | |
| print("Login error:", e) | |
| return jsonify({"error": "Login failed"}), 401 | |
| def api_logout(): | |
| session.clear() | |
| return jsonify({"ok": True}) | |
| def api_me(): | |
| if not is_logged_in(): | |
| return jsonify({"authenticated": False}) | |
| return jsonify({ | |
| "authenticated": True, | |
| "email": session.get("email"), | |
| "name": session.get("name"), | |
| "picture": session.get("picture") | |
| }) | |
| # ================== ANALYSIS ================== | |
| def api_analyze(): | |
| if not is_logged_in(): | |
| return jsonify({"error": "Login required"}), 401 | |
| if not db: | |
| return jsonify({"error": "Database not ready"}), 500 | |
| data = request.json or {} | |
| name = data.get("name", "") | |
| pitch = data.get("pitch", "") | |
| description = data.get("description", "") | |
| industry = data.get("industry", "") | |
| mode = data.get("mode", "fast") | |
| if not (name or pitch or description): | |
| return jsonify({"error": "Missing input"}), 400 | |
| doc_ref = db.collection("analyses").document() | |
| doc_id = doc_ref.id | |
| doc_ref.set({ | |
| "name": name, | |
| "pitch": pitch, | |
| "description": description, | |
| "industry": industry, | |
| "mode": mode, | |
| "user_id": session.get("uid"), | |
| "status": "running", | |
| "created_at": datetime.utcnow() | |
| }) | |
| try: | |
| if not GEMINI_API_KEY: | |
| raise Exception("Gemini API key not set") | |
| prompt = f""" | |
| Analyze this startup idea: | |
| Name: {name} | |
| Pitch: {pitch} | |
| Description: {description} | |
| Industry: {industry} | |
| Mode: {mode} | |
| Give: | |
| 1. Market fit | |
| 2. Strengths | |
| 3. Risks | |
| 4. Suggestions | |
| 5. Score out of 10 | |
| """ | |
| payload = { | |
| "contents": [{ | |
| "parts": [{"text": prompt}] | |
| }] | |
| } | |
| r = requests.post( | |
| f"{GEMINI_URL}?key={GEMINI_API_KEY}", | |
| json=payload, | |
| timeout=30 | |
| ) | |
| gem = r.json() | |
| if "candidates" not in gem: | |
| raise Exception("Invalid Gemini response") | |
| result_text = gem["candidates"][0]["content"]["parts"][0]["text"] | |
| doc_ref.set({ | |
| "status": "done", | |
| "result": result_text, | |
| "completed_at": datetime.utcnow() | |
| }, merge=True) | |
| return jsonify({"ok": True, "id": doc_id}) | |
| except Exception as e: | |
| print("Gemini error:", e) | |
| doc_ref.set({ | |
| "status": "failed", | |
| "error": str(e), | |
| "completed_at": datetime.utcnow() | |
| }, merge=True) | |
| return jsonify({"error": "Gemini failed"}), 500 | |
| # ================== STATIC FILES ================== | |
| def home(): | |
| return send_from_directory(".", "index.html") | |
| def api_feedback(): | |
| if not is_logged_in(): | |
| return jsonify({"error": "Login required"}), 401 | |
| data = request.json or {} | |
| with open("feedback.csv", "a", newline="", encoding="utf-8") as f: | |
| writer = csv.writer(f) | |
| writer.writerow([ | |
| datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"), | |
| data.get("analysis_id"), | |
| data.get("rating"), | |
| data.get("helpful"), | |
| data.get("comment") | |
| ]) | |
| return jsonify({"message": "✅ Feedback saved successfully"}) | |
| def static_files(path): | |
| return send_from_directory(".", path) | |
| # ================== RUN ================== | |
| if __name__ == "__main__": | |
| app.run(host="0.0.0.0", port=7860) | |