Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 43 additions & 9 deletions Backend/app/routes/ai.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,53 @@
# Initialize router
router = APIRouter()

# Load environment variables for Supabase and Gemini
SUPABASE_URL = os.environ.get("SUPABASE_URL")
SUPABASE_KEY = os.environ.get("SUPABASE_KEY")
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY")
# Cache for the lazily-created Supabase client so it is built only once.
_supabase_client: Client | None = None

# Validate required environment variables
if not all([SUPABASE_URL, SUPABASE_KEY, GEMINI_API_KEY]):
raise ValueError("Missing required environment variables: SUPABASE_URL, SUPABASE_KEY, GEMINI_API_KEY")

supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
def get_supabase_client() -> Client:
"""
Lazily create and return the Supabase client.

Reading the environment variables and constructing the client is deferred
to request time so that importing this module never crashes the whole app
when the required variables are missing. If the configuration is absent we
raise an HTTPException so only the AI endpoints fail (with a clear 503),
not unrelated routes.
"""
global _supabase_client
if _supabase_client is not None:
return _supabase_client

supabase_url = os.environ.get("SUPABASE_URL")
supabase_key = os.environ.get("SUPABASE_KEY")
if not supabase_url or not supabase_key:
raise HTTPException(
status_code=503,
detail="AI service is not configured: missing SUPABASE_URL and/or SUPABASE_KEY.",
)

_supabase_client = create_client(supabase_url, supabase_key)
return _supabase_client


def get_gemini_api_key() -> str:
"""Return the Gemini API key, raising a clear 503 if it is not configured."""
gemini_api_key = os.environ.get("GEMINI_API_KEY")
if not gemini_api_key:
raise HTTPException(
status_code=503,
detail="AI service is not configured: missing GEMINI_API_KEY.",
)
return gemini_api_key


def fetch_from_gemini():
prompt = (
"List the top 6 trending content niches for creators and brands this week. For each, provide: name (the niche), insight (a short qualitative reason why it's trending), and global_activity (a number from 1 to 5, where 5 means very high global activity in this category, and 1 means low).Return as a JSON array of objects with keys: name, insight, global_activity."
)
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key={GEMINI_API_KEY}"
gemini_api_key = get_gemini_api_key()
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-lite:generateContent?key={gemini_api_key}"
# Set up retry strategy
retry_strategy = Retry(
total=3,
Expand Down Expand Up @@ -60,6 +91,7 @@ def trending_niches():
- Otherwise, fetch from Gemini, store in Supabase, and return the new data.
- If Gemini fails, fallback to the most recent data available.
"""
supabase = get_supabase_client()
today = str(date.today())
# Check if today's data exists in Supabase
result = supabase.table("trending_niches").select("*").eq("fetched_at", today).execute()
Expand All @@ -75,6 +107,8 @@ def trending_niches():
"fetched_at": today
}).execute()
result = supabase.table("trending_niches").select("*").eq("fetched_at", today).execute()
except HTTPException:
raise
except Exception as e:
print("Gemini fetch failed:", e)
# fallback: serve most recent data
Expand Down
Loading