Spaces:
Running
Running
| """ | |
| api/main.py β FastAPI backend for feelin' | |
| """ | |
| from __future__ import annotations | |
| from fastapi import FastAPI, BackgroundTasks, HTTPException | |
| from fastapi.staticfiles import StaticFiles | |
| from pydantic import BaseModel | |
| from pathlib import Path | |
| import sys | |
| sys.path.insert(0, str(Path(__file__).parent.parent)) | |
| from data.db import init_db, get_leaderboard, get_latest_podcast, get_stats ,SEG_DIR, POD_DIR | |
| from agents.graph import run_post_pipeline | |
| BASE_DIR = Path(__file__).parent.parent | |
| app = FastAPI(title="feelin' API", version="1.0") | |
| # Serve static podcast/segment files | |
| static_dir = BASE_DIR / "static" | |
| static_dir.mkdir(parents=True, exist_ok=True) | |
| app.mount("/static", StaticFiles(directory=str(static_dir)), name="static") | |
| # Init DB on startup | |
| def on_startup(): | |
| init_db() | |
| # ββ Models ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| class PostRequest(BaseModel): | |
| text: str | |
| class PodcastRequest(BaseModel): | |
| category: str | |
| # ββ Routes ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def health(): | |
| return {"status": "ok"} | |
| def submit_post(req: PostRequest): | |
| if not req.text or len(req.text.strip()) < 10: | |
| raise HTTPException(status_code=400, detail="Post too short.") | |
| result = run_post_pipeline(req.text.strip()) | |
| return result | |
| def leaderboard_category(category: str, limit: int = 10): | |
| valid = ["hilarious", "tragic", "unhinged", "awkward", "chaotic"] | |
| if category not in valid: | |
| raise HTTPException(status_code=400, detail="Invalid category.") | |
| posts = get_leaderboard(category, limit=limit) | |
| return {"category": category, "posts": posts} | |
| def leaderboard_all(): | |
| result = {} | |
| for cat in ["hilarious", "tragic", "unhinged", "awkward", "chaotic"]: | |
| result[cat] = get_leaderboard(cat, limit=5) | |
| return result | |
| def generate_podcast_endpoint(req: PodcastRequest, background_tasks: BackgroundTasks): | |
| valid = ["hilarious", "tragic", "unhinged", "awkward", "chaotic"] | |
| if req.category not in valid: | |
| raise HTTPException(status_code=400, detail="Invalid category.") | |
| def _safe_generate(cat: str): | |
| try: | |
| from podcast.builder import generate_podcast | |
| generate_podcast(cat) | |
| except Exception as e: | |
| print(f"[Podcast background error] {e}") | |
| background_tasks.add_task(_safe_generate, req.category) | |
| return {"status": "generating", "category": req.category} | |
| def get_podcast(category: str): | |
| valid = ["hilarious", "tragic", "unhinged", "awkward", "chaotic"] | |
| if category not in valid: | |
| raise HTTPException(status_code=400, detail="Invalid category.") | |
| pod = get_latest_podcast(category) | |
| if not pod: | |
| return {"status": "not_ready", "message": "No episode generated yet. Click β‘ to generate."} | |
| audio_path = pod.get("audio_path", "") | |
| audio_url = f"/{audio_path}" if audio_path else None | |
| return { | |
| "status": "ready", | |
| "category": category, | |
| "audio_url": audio_url, | |
| "script": pod.get("script", ""), | |
| "post_count": pod.get("post_count", 0), | |
| "created_at": pod.get("created_at", ""), | |
| } | |
| def stats(): | |
| return get_stats() | |