creative-user's picture
Upload 5 files
93c8ebd verified
Raw
History Blame Contribute Delete
5.41 kB
# -*- coding: utf-8 -*-
"""FastAPI.ipynb
Automatically generated by Colab.
Original file is located at
https://colab.research.google.com/drive/1aRYWOGz0S2N2oVN33c0uv3PzGsoWc02F
"""
import io
import cv2
import json
import numpy as np
import tensorflow as tf
from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.responses import JSONResponse
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI(title="NusantaraLens API", description="API Klasifikasi Gambar Budaya Indonesia")
# 1. SETUP CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 2. BATASAN UKURAN FILE
MAX_FILE_SIZE = 5 * 1024 * 1024
# Load Model
MODEL_PATH = "model_nusantara_lens.keras"
try:
model = tf.keras.models.load_model(MODEL_PATH)
print("Model berhasil dimuat!")
except Exception as e:
print(f"Gagal memuat model: {e}")
model = None
LABEL_MAP = {0: "Kuliner", 1: "Lagu_Daerah", 2: "Pahlawan", 3: "Tarian"}
# 3. LOAD DATA JSON
try:
with open("/content/Data deksripsi budaya.json", "r", encoding="utf-8") as f:
DATA_BUDAYA = json.load(f)
print("File Data deksripsi budaya.json berhasil dimuat!")
except Exception as e:
print("File Data deksripsi budaya.json tidak ditemukan. Pastikan sudah dibuat di Colab!")
DATA_BUDAYA = []
def preprocess_image_consistent(img):
h, w, _ = img.shape
min_dim = min(h, w)
start_x = w // 2 - min_dim // 2
start_y = h // 2 - min_dim // 2
cropped_img = img[start_y:start_y+min_dim, start_x:start_x+min_dim]
img_resized = cv2.resize(cropped_img, (224, 224), interpolation=cv2.INTER_AREA)
img_array = img_resized.astype("float32") / 255.0
return np.expand_dims(img_array, axis=0)
@app.get("/")
def read_root():
return {"message": "Server NusantaraLens API aktif dan berjalan."}
@app.post("/predict")
async def predict_image(file: UploadFile = File(...)):
if model is None:
raise HTTPException(status_code=500, detail="Model AI belum siap di server.")
# Proteksi 1: Cek Format File
if not file.content_type.startswith("image/"):
raise HTTPException(status_code=400, detail="File harus berupa gambar (JPEG/PNG).")
# Proteksi 2: Baca isi gambar sekaligus cek ukuran file-nya
contents = await file.read()
if len(contents) > MAX_FILE_SIZE:
raise HTTPException(status_code=413, detail="Ukuran gambar terlalu besar! Maksimal 5MB.")
try:
nparr = np.frombuffer(contents, np.uint8)
img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
if img is None:
raise HTTPException(status_code=400, detail="Gambar rusak atau format tidak didukung.")
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img_batch = preprocess_image_consistent(img)
predictions = model.predict(img_batch)
predicted_class_index = int(np.argmax(predictions[0]))
confidence = float(predictions[0][predicted_class_index])
kategori_hasil = LABEL_MAP.get(predicted_class_index, "Tidak diketahui")
rekomendasi_budaya = [item for item in DATA_BUDAYA if item.get("Kategori") == kategori_hasil]
return JSONResponse(content={
"status": "success",
"kategori_tebakan_ai": kategori_hasil,
"confidence_percentage": round(confidence * 100, 2),
"jumlah_data_ditemukan": len(rekomendasi_budaya),
"daftar_rekomendasi": rekomendasi_budaya
})
except Exception as e:
import traceback
traceback.print_exc() # Perintah ini akan mencetak tulisan merah error aslinya ke Colab
raise HTTPException(status_code=500, detail=f"Terjadi kesalahan pemrosesan: {str(e)}")
from pyngrok import ngrok
import nest_asyncio
import uvicorn
# 1. SETUP TOKEN NGROK (HAPUS TULISAN DI BAWAH DAN GANTI DENGAN TOKEN MAS)
ngrok.set_auth_token("3ETJl4pAvTJnNSngeLUElXEJK0N_6H1mGVSiY3gvKKrNHCDKy")
# 2. MENGIZINKAN ASYNC DI COLAB
nest_asyncio.apply()
# 3. MEMBUAT TUNNEL NGROK
public_url = ngrok.connect(8000)
print("==================================================================")
print(f"BERHASIL! PUBLIC URL API: {public_url.public_url}")
print("==================================================================")
# 4. MENJALANKAN SERVER (Menggunakan variabel 'app' dari Cell 2)
config = uvicorn.Config(
app,
host="0.0.0.0",
port=8000
)
server = uvicorn.Server(config)
await server.serve()
from google.colab import files
# 1. Teks isi dari requirements.txt
isi_requirements = """fastapi
uvicorn
python-multipart
numpy
tensorflow-cpu
opencv-python-headless
"""
# 2. Membuat file requirements.txt di dalam Colab
with open("requirements.txt", "w") as f:
f.write(isi_requirements)
print("File requirements.txt berhasil dibuat!")
# 3. Memicu download otomatis ke laptop
files.download("requirements.txt")
print("Sedang mendownload ke laptop, silakan cek folder Downloads mas...")
from google.colab import files
# 1. Teks instruksi untuk Railway
isi_procfile = "web: uvicorn main:app --host 0.0.0.0 --port $PORT"
# 2. Membuat file bernama Procfile (tanpa ekstensi apapun)
with open("Procfile", "w") as f:
f.write(isi_procfile)
print("File Procfile berhasil dibuat!")
# 3. Memicu download otomatis ke laptop
files.download("Procfile")
print("Sedang mendownload ke laptop, silakan cek folder Downloads...")