File size: 7,378 Bytes
72b9a21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# Python API untuk Klasifikasi Bibit Kelapa Sawit

API server Python ini menggunakan model Hybrid DenseNet-SVM untuk mengklasifikasikan umur bibit kelapa sawit (3 Bulan, 6 Bulan, 9 Bulan).

## πŸ“‹ Struktur File

```
python-api/
β”œβ”€β”€ app.py                          # Main Flask application
β”œβ”€β”€ requirements.txt                # Python dependencies
β”œβ”€β”€ Dockerfile                      # Docker configuration
β”œβ”€β”€ .dockerignore                  # Docker ignore rules
└── models/                         # Folder untuk model files
    β”œβ”€β”€ svm_densenet201_rbf.joblib # Model SVM (ANDA LETAKKAN DI SINI)
    β”œβ”€β”€ metadata.json              # Model metadata (ANDA LETAKKAN DI SINI)
    └── metadata.json.example      # Contoh format metadata
```

## πŸ”§ Persiapan

### 1. Letakkan File Model Anda

Setelah training model Anda di Google Colab, letakkan file-file berikut ke folder `models/`:

**File yang diperlukan:**
- `svm_densenet201_rbf.joblib` - File model SVM hasil training
- `metadata.json` - File metadata dengan format:

```json
{
  "class_names": ["3 Bulan", "6 Bulan", "9 Bulan"],
  "img_size": 224,
  "model_type": "DenseNet201 + SVM",
  "description": "Klasifikasi perkembangan bibit kelapa sawit berdasarkan umur"
}
```

### 2. Setup Koneksi Supabase (Optional tapi Recommended)

Python API bisa menyimpan hasil prediksi langsung ke database.

**Set environment variables:**
```env
SUPABASE_URL=https://xyddxrfiacdcnipdclas.supabase.co
SUPABASE_ANON_KEY=your-anon-key
```

πŸ“– **Detail lengkap:** Lihat `SUPABASE_SETUP.md`

### 3. Verifikasi File

Pastikan struktur folder seperti ini:
```
python-api/
β”œβ”€β”€ app.py
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ .env (optional untuk local)
└── models/
    β”œβ”€β”€ svm_densenet201_rbf.joblib  ← File model Anda
    └── metadata.json                ← Metadata Anda
```

## πŸš€ Cara Deploy

### Opsi 1: Deploy ke Hugging Face Spaces (RECOMMENDED - Gratis)

1. **Buat Account di Hugging Face**
   - Daftar di https://huggingface.co/join
   - Buat Space baru (New Space)
   - Pilih Docker sebagai SDK

2. **Upload Files**
   - Upload semua file dari folder `python-api/`
   - Pastikan file model sudah ada di folder `models/`

3. **Setting Environment Variables**
   - Go to Settings β†’ Variables and secrets
   - Add secrets:
     - `SUPABASE_URL`
     - `SUPABASE_ANON_KEY`

4. **Dapatkan URL API**
   - Setelah deploy, Anda akan mendapat URL seperti: `https://username-spacename.hf.space`

### Opsi 2: Deploy ke Railway.app

1. **Install Railway CLI**
   ```bash
   npm install -g @railway/cli
   ```

2. **Login ke Railway**
   ```bash
   railway login
   ```

3. **Deploy dari folder python-api**
   ```bash
   cd python-api
   railway init
   railway up
   ```

4. **Set Environment Variables**
   ```bash
   railway variables set SUPABASE_URL=https://xyddxrfiacdcnipdclas.supabase.co
   railway variables set SUPABASE_ANON_KEY=your-key
   ```

5. **Generate Domain**
   ```bash
   railway domain
   ```

### Opsi 3: Deploy ke Google Cloud Run

1. **Install Google Cloud SDK**

2. **Build dan Push Docker Image**
   ```bash
   cd python-api

   # Build image
   gcloud builds submit --tag gcr.io/PROJECT_ID/palm-classifier

   # Deploy to Cloud Run
   gcloud run deploy palm-classifier \
     --image gcr.io/PROJECT_ID/palm-classifier \
     --platform managed \
     --region asia-southeast2 \
     --allow-unauthenticated \
     --set-env-vars SUPABASE_URL=https://xyddxrfiacdcnipdclas.supabase.co,SUPABASE_ANON_KEY=your-key
   ```

### Opsi 4: Local Testing (Development)

```bash
cd python-api

# Install dependencies
pip install -r requirements.txt

# Run server
python app.py
```

Server akan berjalan di `http://localhost:5000`

## πŸ”— Integrasi dengan Aplikasi Web

Setelah API ter-deploy, tambahkan URL API ke Supabase Edge Function:

### Via Supabase Dashboard:

1. Buka Supabase Dashboard
2. Pilih Project Anda
3. Pergi ke **Edge Functions** β†’ **classify-seedling**
4. Klik **Secrets/Environment Variables**
5. Tambahkan secret baru:
   - Name: `PYTHON_API_URL`
   - Value: `https://your-api-url.com` (URL API yang sudah di-deploy)

### Via CLI (jika menggunakan Supabase CLI):

```bash
supabase secrets set PYTHON_API_URL=https://your-api-url.com
```

## πŸ“‘ API Endpoints

### 1. Health Check
```bash
GET /health
```

Response:
```json
{
  "status": "healthy",
  "model_loaded": true,
  "device": "cpu",
  "classes": ["3 Bulan", "6 Bulan", "9 Bulan"]
}
```

### 2. Classify Image
```bash
POST /classify
Content-Type: application/json

{
  "image": "data:image/jpeg;base64,/9j/4AAQ..."
}
```

Response:
```json
{
  "predicted_class": "6 Bulan",
  "confidence": 0.8543,
  "probabilities": {
    "3 Bulan": 0.0812,
    "6 Bulan": 0.8543,
    "9 Bulan": 0.0645
  },
  "mode": "real",
  "saved_to_db": true,
  "id": "uuid-here"
}
```

### 3. Reload Model
```bash
POST /reload-model
```

Digunakan jika Anda mengupdate model tanpa restart server.

## πŸ§ͺ Testing API

### Test dengan cURL:

```bash
# Health check
curl https://your-api-url.com/health

# Classify (dengan base64 image)
curl -X POST https://your-api-url.com/classify \
  -H "Content-Type: application/json" \
  -d '{"image": "data:image/jpeg;base64,YOUR_BASE64_IMAGE_HERE"}'
```

### Test dengan Python:

```python
import requests
import base64

# Read image
with open('bibit.jpg', 'rb') as f:
    img_data = base64.b64encode(f.read()).decode()

# Send request
response = requests.post(
    'https://your-api-url.com/classify',
    json={'image': f'data:image/jpeg;base64,{img_data}'}
)

print(response.json())
```

## πŸ› Troubleshooting

### Model tidak ditemukan
```
⚠ Model file not found at models/svm_densenet201_rbf.joblib
Using simulation mode until model is uploaded
```

**Solusi:** Pastikan file `svm_densenet201_rbf.joblib` ada di folder `models/`

### Error saat load model
```
Error loading model: ...
```

**Solusi:**
- Pastikan versi scikit-learn sama dengan yang digunakan saat training
- Cek apakah file model tidak corrupt
- Pastikan format file adalah `.joblib`

### API timeout
**Solusi:**
- Tingkatkan timeout di Dockerfile (sudah diset 120 detik)
- Untuk Cloud Run, set `--timeout 300`

### Memory error
**Solusi:**
- Upgrade instance ke memory lebih besar
- Untuk Cloud Run: `--memory 2Gi`
- Untuk Hugging Face: Upgrade ke Space berbayar

## πŸ“Š Mode Operasi

API memiliki 2 mode:

1. **Real Mode** - Menggunakan model asli Anda
   - Response: `"mode": "real"`
   - Memerlukan file model di folder `models/`

2. **Simulation Mode** - Menggunakan random prediction
   - Response: `"mode": "simulation"`
   - Aktif jika model belum diupload
   - Berguna untuk testing integrasi

## πŸ” Security Notes

- API ini tidak memerlukan authentication (sesuai design untuk demo)
- Jika ingin menambah security, tambahkan API key di header
- Untuk production, pertimbangkan rate limiting

## πŸ’‘ Tips

1. **Monitoring**: Cek logs untuk melihat performa model
2. **Update Model**: Upload model baru dan panggil `/reload-model`
3. **Scaling**: Gunakan multiple workers di gunicorn untuk handle traffic tinggi
4. **Caching**: Pertimbangkan caching untuk request yang sama

## πŸ“ž Support

Jika ada masalah, cek:
1. Logs dari platform deployment Anda
2. Response dari `/health` endpoint
3. Pastikan semua dependencies terinstall dengan benar