from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel import uuid import time app = FastAPI(title="NoobAI RAM Storage") # WAJIB: Buka CORS agar UI HTML kamu bisa nge-fetch API ini app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # ========================================== # 🧠 IN-MEMORY STORAGE (PURE RAM) # Struktur: { "image_id": {"base64": "...", "timestamp": 12345} } # ========================================== memory_db = {} # Proteksi RAM: Asumsi 1 gambar Base64 = ~1.5MB. # 5000 gambar = ~7.5GB RAM. Sangat aman untuk RAM 16/18GB. MAX_IMAGES = 5000 class ImagePayload(BaseModel): image_base64: str @app.get("/") def read_root(): """Health check endpoint""" return { "status": "Online", "ram_images_count": len(memory_db), "max_capacity": MAX_IMAGES } @app.post("/save") def save_image(payload: ImagePayload): """Simpan gambar ke RAM""" # Jika RAM penuh, hapus gambar paling lama (FIFO) if len(memory_db) >= MAX_IMAGES: oldest_id = min(memory_db, key=lambda k: memory_db[k]["timestamp"]) del memory_db[oldest_id] img_id = str(uuid.uuid4()) memory_db[img_id] = { "base64": payload.image_base64, "timestamp": time.time() } return {"status": "success", "image_id": img_id} @app.get("/images") def get_all_images(): """Ambil daftar ID gambar (hanya ID dan waktu, bukan base64 nya agar enteng)""" return { "images": [ {"id": k, "timestamp": v["timestamp"]} for k, v in sorted(memory_db.items(), key=lambda item: item[1]["timestamp"], reverse=True) ] } @app.get("/image/{img_id}") def get_image(img_id: str): """Ambil Base64 dari gambar spesifik berdasarkan ID""" if img_id not in memory_db: raise HTTPException(status_code=404, detail="Image not found in RAM or expired") return {"image_id": img_id, "base64": memory_db[img_id]["base64"]} @app.delete("/image/{img_id}") def delete_image(img_id: str): """Hapus gambar secara manual dari RAM""" if img_id in memory_db: del memory_db[img_id] return {"status": "deleted"} return {"status": "not_found"}