Spaces:
Sleeping
Sleeping
| 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 | |
| def home(): | |
| return {"message": "🎬 Movie Recommendation API is running!"} | |
| def health(): | |
| return {"status": "ok", "movies_loaded": movies is not None} | |
| 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") | |
| def startup_event(): | |
| load_artifacts() | |