import os import pickle from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.staticfiles import StaticFiles from pydantic import BaseModel import numpy as np # Filenames (local, already in repo) MOVIES_PKL = "movies.pkl" SIM_PKL = "similarity.pkl" movies = None similarity = None def load_artifacts(): global movies, similarity if not os.path.exists(MOVIES_PKL) or not os.path.exists(SIM_PKL): raise FileNotFoundError("Pickle files not found in project directory.") with open(MOVIES_PKL, "rb") as f: movies = pickle.load(f) with open(SIM_PKL, "rb") as f: similarity = pickle.load(f) print("✅ Artifacts loaded successfully") # FastAPI app app = FastAPI() # CORS for frontend / external calls app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) class RecommendRequest(BaseModel): title: str top_n: int = 5 # Root route @app.get("/") def home(): return {"message": "🎬 Movie Recommendation API is running!"} @app.get("/health") def health(): return {"status": "ok", "movies_loaded": movies is not None} @app.post("/recommend") def recommend(request: RecommendRequest): if movies is None or similarity is None: raise HTTPException(status_code=500, detail="Model not loaded.") if request.title not in movies["title"].values: raise HTTPException( status_code=404, detail=f"Movie '{request.title}' not found in dataset", ) idx = movies[movies["title"] == request.title].index[0] sim_scores = sorted( enumerate(similarity[idx]), key=lambda x: x[1], reverse=True )[1 : request.top_n + 1] recommendations = [ {"title": movies.iloc[i].title, "score": float(score)} for i, score in sim_scores ] return {"input": request.title, "recommendations": recommendations} # Optional: mount frontend if you add HTML files FRONTEND_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "frontend") if os.path.exists(FRONTEND_DIR): app.mount("/", StaticFiles(directory=FRONTEND_DIR, html=True), name="frontend") @app.on_event("startup") def startup_event(): load_artifacts()