92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
from fastapi import FastAPI, HTTPException, Request, Response
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from contextlib import asynccontextmanager
|
|
from connection import prisma
|
|
from schemas import ComparisonResponse, RecommendationRequest
|
|
import ml_core
|
|
import services
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI):
|
|
print("⏳ Menghubungkan ke Database Neon...")
|
|
await prisma.connect()
|
|
|
|
print("🤖 Memuat Asset Machine Learning (XGBoost)...")
|
|
ml_core.load_ml_assets()
|
|
|
|
yield
|
|
|
|
print("🔌 Memutuskan koneksi database...")
|
|
await prisma.disconnect()
|
|
|
|
app = FastAPI(
|
|
title="Tokopedia Laptop Recommendation API",
|
|
description="Backend analisis sentimen ulasan laptop menggunakan XGBoost - Syafrizal Wd Mahendra",
|
|
lifespan=lifespan
|
|
)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=["*"],
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
@app.post("/recommend", response_model=ComparisonResponse)
|
|
async def recommend_laptop(request: Request, data: RecommendationRequest):
|
|
if not ml_core.model_optimized:
|
|
raise HTTPException(
|
|
status_code=500,
|
|
detail="Model Machine Learning belum siap atau gagal dimuat."
|
|
)
|
|
|
|
results = []
|
|
|
|
for index, candidate in enumerate(data.candidates):
|
|
if await request.is_disconnected():
|
|
print("🛑 Sinyal Cancel diterima! Menghentikan proses AI.")
|
|
return Response(status_code=204)
|
|
|
|
print(f"🔄 Memproses ulasan untuk: {candidate.name}...")
|
|
|
|
try:
|
|
result = await services.process_product_reviews(
|
|
candidate=candidate,
|
|
user_email=data.user_email,
|
|
metric_id=data.metric_id,
|
|
brand_id=data.brand_id,
|
|
request=request
|
|
)
|
|
|
|
if result:
|
|
results.append(result)
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ Gagal memproses {candidate.name}: {str(e)}")
|
|
continue
|
|
|
|
if not results:
|
|
raise HTTPException(
|
|
status_code=400,
|
|
detail="Tidak ada ulasan valid yang berhasil dianalisis dari produk yang diberikan."
|
|
)
|
|
|
|
try:
|
|
sorted_results = sorted(
|
|
results,
|
|
key=lambda x: x.general_score if hasattr(x, 'general_score') else x["general_score"],
|
|
reverse=True
|
|
)
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"Gagal mengurutkan hasil analisis: {str(e)}")
|
|
|
|
winner = sorted_results[0]
|
|
|
|
return {
|
|
"user_email": data.user_email,
|
|
"brand_id": data.brand_id,
|
|
"winning_product": winner.name if hasattr(winner, 'name') else winner["name"],
|
|
"details": sorted_results,
|
|
"metric_id": data.metric_id
|
|
} |