Skip to content

Commit d2ff566

Browse files
committed
Fix Rate Limiter initialization using lifespan
1 parent 30ed179 commit d2ff566

1 file changed

Lines changed: 38 additions & 48 deletions

File tree

app/main.py

Lines changed: 38 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,47 @@
1-
import os
2-
from fastapi import FastAPI, Depends, HTTPException, Request
3-
from sqlalchemy.orm import Session
4-
from slowapi import _rate_limit_exceeded_handler
5-
from slowapi.errors import RateLimitExceeded
6-
from app.mqtt.client import start_mqtt
1+
from fastapi import FastAPI
2+
from contextlib import asynccontextmanager
3+
import redis.asyncio as redis
4+
from fastapi_limiter import FastAPILimiter
75

8-
# Import Module Kita
9-
from app.core.database import engine, get_db, Base
10-
from app.models.device import Device
6+
# Import komponen buatan kita
117
from app.mqtt.client import start_mqtt
12-
from app.api.v1.devices import router as device_router
13-
from app.core.limiter import limiter
14-
from app.api.v1 import logs
8+
from app.api import logs
9+
10+
# --- SETTING LIFESPAN (Cara Modern Handle Startup/Shutdown) ---
11+
@asynccontextmanager
12+
async def lifespan(app: FastAPI):
13+
# ==========================
14+
# 1. LOGIKA SAAT STARTUP
15+
# ==========================
16+
print("🚀 System Starting Up...")
17+
18+
# A. Nyalakan MQTT
19+
start_mqtt()
20+
print("✅ MQTT Listener Berjalan!")
1521

16-
# --- INIT DATABASE ---
17-
Base.metadata.create_all(bind=engine)
22+
# B. Konek Redis & Init Rate Limiter
23+
try:
24+
# Gunakan "redis" karena itu nama service di docker-compose
25+
redis_connection = redis.from_url("redis://redis:6379", encoding="utf-8", decode_responses=True)
26+
await FastAPILimiter.init(redis_connection)
27+
print("🛡️ Rate Limiter Activated!")
28+
except Exception as e:
29+
print(f"⚠️ Gagal Konek Redis: {e}")
1830

19-
# --- SETUP APP ---
20-
app = FastAPI(title="IoT Backend API")
31+
yield # <--- Di sini aplikasi berjalan melayani user
2132

22-
# 1. Pasang State Limiter (Wajib di main.py)
23-
app.state.limiter = limiter
24-
app.add_exception_handler(RateLimitExceeded, _rate_limit_exceeded_handler)
33+
# ==========================
34+
# 2. LOGIKA SAAT SHUTDOWN
35+
# ==========================
36+
print("🛑 System Shutting Down...")
37+
await redis_connection.close()
2538

26-
# 2. Register Router
27-
app.include_router(device_router, prefix="/api/v1", tags=["Devices"])
28-
app.include_router(logs.router, prefix="/api/logs", tags=["Sensor Logs"])
39+
# --- INISIALISASI APP DENGAN LIFESPAN ---
40+
app = FastAPI(title="PCB Backend API", lifespan=lifespan)
2941

30-
# --- STARTUP EVENTS ---
31-
@app.on_event("startup")
32-
async def startup_event():
33-
print("🚀 Menyalakan Mesin MQTT...")
34-
print("🚀 APLIKASI UPDATE DARI GITHUB ACTION BERHASIL!")
35-
start_mqtt()
42+
# --- DAFTARKAN ROUTER ---
43+
app.include_router(logs.router, prefix="/api/logs", tags=["Sensor Logs"])
3644

37-
# --- ROOT ENDPOINT (Contoh penggunaan di main.py) ---
3845
@app.get("/")
39-
@limiter.limit("5/minute") # Contoh: IP yg sama cuma boleh refresh halaman ini 5x semenit
40-
def read_root(request: Request): # <--- JANGAN LUPA request: Request
41-
return {
42-
"status": "Backend is Running",
43-
"service": "IoT Platform",
44-
"docs_url": "/docs"
45-
}
46-
47-
# --- ENDPOINT TEST DUMMY (Boleh dihapus nanti kalau production) ---
48-
@app.post("/test-create-device")
49-
def create_dummy_device(device_id: str, pin: str, db: Session = Depends(get_db)):
50-
existing_device = db.query(Device).filter(Device.device_id == device_id).first()
51-
if existing_device:
52-
raise HTTPException(status_code=400, detail="Device ID sudah ada bro!")
53-
new_device = Device(device_id=device_id, pin_code=pin)
54-
db.add(new_device)
55-
db.commit()
56-
db.refresh(new_device)
57-
return {"message": "Sukses nambah alat!", "data": new_device}
46+
def read_root():
47+
return {"message": "PCB Backend is Running & Protected!"}

0 commit comments

Comments
 (0)