from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware import psycopg2 from psycopg2.extras import RealDictCursor import os import google.generativeai as genai app = FastAPI() # Enable CORS app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Get secrets from Hugging Face Repository Secrets (not .env file) DATABASE_URL = os.getenv("DATABASE_URL") GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") # Configure Gemini if key exists if GEMINI_API_KEY: genai.configure(api_key=GEMINI_API_KEY) print("✅ Gemini configured on cloud") else: print("⚠️ No Gemini API key found") def get_db(): conn = psycopg2.connect(DATABASE_URL, cursor_factory=RealDictCursor) return conn def create_table(): conn = get_db() cursor = conn.cursor() cursor.execute(""" CREATE TABLE IF NOT EXISTS tasks ( id SERIAL PRIMARY KEY, title TEXT NOT NULL ) """) conn.commit() conn.close() create_table() @app.get("/") def hello(): return {"message": "Hello, Agentic AI! (Cloud with Gemini)"} @app.post("/tasks") def create_task(title: str): conn = get_db() cursor = conn.cursor() cursor.execute("INSERT INTO tasks (title) VALUES (%s) RETURNING id", (title,)) task_id = cursor.fetchone()["id"] conn.commit() conn.close() return {"id": task_id, "title": title} @app.get("/tasks") def get_tasks(): conn = get_db() cursor = conn.cursor() cursor.execute("SELECT * FROM tasks ORDER BY id DESC") tasks = cursor.fetchall() conn.close() return [{"id": t["id"], "title": t["title"]} for t in tasks] @app.delete("/tasks/{task_id}") def delete_task(task_id: int): conn = get_db() cursor = conn.cursor() cursor.execute("DELETE FROM tasks WHERE id = %s", (task_id,)) deleted = cursor.rowcount > 0 conn.commit() conn.close() if not deleted: raise HTTPException(status_code=404, detail="Task not found") return {"message": "Task deleted"} # AI endpoint with Gemini @app.get("/ai-tag") def ai_tag_paper(title: str, authors: str = ""): if not GEMINI_API_KEY: return {"tags": keyword_tag(title), "title": title, "authors": authors} try: # This points to a stable, newer model that is currently supported model = genai.GenerativeModel('gemini-2.5-flash-lite') prompt = f"""Paper title: "{title}". Authors: "{authors}". Generate 2-3 relevant tags with emojis. Return ONLY comma-separated tags. Example: "🤖 LLM/AI, 🧠 Deep Learning" Tags:""" response = model.generate_content(prompt) tags = response.text.strip() tags = tags.replace("```", "").replace("tags:", "").strip() if not tags: tags = keyword_tag(title) return {"tags": tags, "title": title, "authors": authors} except Exception as e: print(f"Gemini error: {e}") return {"tags": keyword_tag(title), "title": title, "authors": authors} def keyword_tag(title): """Fallback keyword-based tagging""" title_lower = title.lower() if any(word in title_lower for word in ['attention', 'transformer', 'llm', 'gpt', 'bert']): return "🤖 LLM/AI, 🧠 Deep Learning" elif any(word in title_lower for word in ['big data', 'data processing', 'heterogeneous']): return "📊 Big Data, 🤖 AI-Driven Processing" elif any(word in title_lower for word in ['solar', 'wind', 'battery', 'energy']): return "🔋 Energy, ☀️ Renewable" elif any(word in title_lower for word in ['quantum', 'qubit']): return "⚛️ Quantum Computing, 🔬 Physics" else: return "📄 General Research" @app.get("/health") def health(): return { "status": "ok", "gemini": "configured" if GEMINI_API_KEY else "missing", "database": "connected" }