# app.py from fastapi import FastAPI, File, UploadFile, HTTPException from fastapi.responses import JSONResponse from model.model_logic import Predictor # Import class Predictor dari file sebelah import logging # Konfigurasi logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # Inisialisasi aplikasi FastAPI app = FastAPI( title="Food Nutrition API", description="API untuk memprediksi nama, nutrisi, dan komposisi makanan Indonesia dari gambar.", version="1.0.0" ) # Muat model HANYA SEKALI saat aplikasi dimulai # Ini sangat penting untuk performa try: logger.info("Memuat model dan aset...") predictor = Predictor( model_path="assets/best_model_finetuned_convnext.pth", metadata_path="assets/FoodID_metadata.csv" ) logger.info("Model dan aset berhasil dimuat.") except Exception as e: logger.error(f"Gagal memuat model: {e}") predictor = None @app.get("/", tags=["General"]) def read_root(): """Endpoint utama untuk memeriksa apakah API sedang berjalan.""" return {"status": "ok", "message": "Selamat datang di Food Nutrition API!"} @app.post("/predict", tags=["Prediction"]) async def predict_image(file: UploadFile = File(...)): """ Endpoint untuk melakukan prediksi. - **Upload** sebuah file gambar. - **Menerima** hasil prediksi dalam format JSON. """ if not predictor: raise HTTPException(status_code=503, detail="Model tidak tersedia. Silakan cek log server.") # Pastikan file yang diupload adalah gambar if not file.content_type.startswith("image/"): raise HTTPException(status_code=400, detail="File yang diunggah harus berupa gambar.") try: # Baca file gambar image_bytes = await file.read() # Lakukan prediksi logger.info(f"Menerima request prediksi untuk file: {file.filename}") prediction_result = predictor.predict(image_bytes) logger.info(f"Hasil prediksi: {prediction_result['food_name']}") return JSONResponse(content=prediction_result) except Exception as e: logger.error(f"Terjadi error saat prediksi: {e}") raise HTTPException(status_code=500, detail=f"Terjadi kesalahan internal: {e}")