|
|
||
|---|---|---|
| .. | ||
| __pycache__ | ||
| app | ||
| models | ||
| scripts | ||
| tests | ||
| .env.example | ||
| README.md | ||
| SCRAPING.md | ||
| harga_cabai_merah_keriting_jemberkab_2021-11-01_2025-11-01.csv | ||
| harga_cabai_rawit_jemberkab_2021-11-01_2025-11-01.csv | ||
| harga_cabe_merah_besar_jemberkab_2021-11-01_2025-11-01.csv | ||
| main.py | ||
| requirements.txt | ||
| restart_backend.ps1 | ||
README.md
API Prediksi Harga Cabai
API ini menggunakan Flask, application factory, dan Blueprint pada prefix /api/v1. Model LSTM tidak dilatih ulang dan artifact di models/ hanya dimuat satu kali saat startup.
Menjalankan di Windows
Dari folder api dengan environment Python proyek:
pip install -r requirements.txt
python main.py
Untuk menghentikan proses backend lama dan menjalankannya kembali dengan auto-reloader:
cd C:\PrediksiHargaCabe\api
powershell -ExecutionPolicy Bypass -File .\restart_backend.ps1
Skrip tersebut menghentikan proses backend proyek pada port 8000, lalu menjalankan Flask dengan
FLASK_DEBUG=1. Perubahan file Python akan dimuat otomatis selama proses tetap berjalan.
Environment yang tersedia:
MODELS_DIR: lokasi folder model, defaultapi/models.DATA_DIR: lokasi data CSV historis, default folderapikarena file aktual berada di sana.DATA_SOURCE: sumber data aktif,mysql(default) ataucsv.MYSQL_HOST,MYSQL_PORT,MYSQL_DATABASE,MYSQL_USER,MYSQL_PASSWORD: koneksi database MySQL melalui PyMySQL.MYSQL_CONNECT_TIMEOUT: batas waktu koneksi database dalam detik.PRICE_UNIT_SCALE: pengali nilai CSV ke Rupiah penuh, default1000; sumber CSV penelitian menyimpan12.000sebagai 12 ribu Rupiah.CORS_ORIGINS: daftar origin dipisahkan koma; defaulthttp://127.0.0.1:5173,http://localhost:5173untuk development dengan session login.ALLOWED_HORIZONS: default1,3,7.MAX_HORIZON: default7.
Endpoint
GET /api/v1/healthGET /api/v1/commoditiesGET /api/v1/markets?commodity=rawitGET /api/v1/history?commodity=rawit&market=pasar_tanjung&days=90GET /api/v1/predict?commodity=rawit&market=pasar_tanjung&horizon=7GET /api/v1/predict/map?commodity=rawit&horizon=7
Semua error memakai format { "error": { "code": "...", "message": "...", "details": {} } }.
Format data historis
Dengan DATA_SOURCE=mysql, loader membaca tabel price_history dan melakukan join ke commodities serta markets menggunakan slug. Dengan DATA_SOURCE=csv, loader membaca file aktual harga_cabai_rawit_*.csv, harga_cabe_merah_besar_*.csv, dan harga_cabai_merah_keriting_*.csv dari DATA_DIR. Pada mode CSV, kolom tanggal dapat bernama Tanggal, dan kolom pasar memakai nama Pasar_Tanjung, Pasar_Kreongan, Pasar_Tegal_Besar, Pasar_Mangli, serta Pasar_Wirolegi. Harga bernilai 0, N/A, atau kosong diperlakukan sebagai NaN; hanya gap internal sampai dua titik yang diinterpolasi linear.
Menghubungkan ke MySQL phpMyAdmin
- Pastikan service MySQL pada XAMPP/Laragon/WAMP sedang berjalan.
- Pastikan database yang dipakai adalah
prediksicabe. - Pastikan tabel
commodities,markets, danprice_historyada. - Isi data harga ke
price_history; seed SQL hanya mengisi master komoditas dan pasar. - Set environment variable pada terminal; file
.env.examplehanya template dan belum dibaca otomatis oleh aplikasi. - Isi
MYSQL_USERdanMYSQL_PASSWORDsesuai akun MySQL lokal. - Jalankan API dari folder
api.
Untuk membuat akun admin, daftar dahulu melalui endpoint register atau halaman register website, lalu ubah role akun tersebut melalui phpMyAdmin:
UPDATE users
SET role = 'admin'
WHERE email = 'email-admin-anda@example.com';
Password tetap disimpan dalam bentuk hash oleh API; jangan memasukkan password ke query SQL.
Endpoint admin yang sudah tersedia:
GET /api/v1/admin/overviewGET /api/v1/admin/modelsGET /api/v1/admin/scraping/logsGET /api/v1/admin/scraping/logs/<log_id>/recordsPOST /api/v1/admin/scraping/jobsGET /api/v1/admin/scraping/jobs/<job_id>POST /api/v1/admin/preprocessing/jobsdengan{"scraping_log_id": 123}untuk memproses satu riwayat scraping yang dipilih.GET /api/v1/admin/preprocessing/jobs/<job_id>DELETE /api/v1/admin/scraping/historyDELETE /api/v1/admin/scraping/logs/<log_id>POST /api/v1/admin/scraping/refreshGET /api/v1/prices?page=1&limit=25(admin)
Panel admin sekarang memiliki menu dataset dan pembaruan data manual. Endpoint refresh mengambil tabel SISKAPERBAPO, menyimpan observasi baru atau perubahan ke price_history, dan mencatat proses ke scraping_logs. Endpoint records menampilkan tanggal, komoditas, pasar, dan harga dari hasil scraping terakhir. Data baru tidak melatih ulang model; model deployment yang sudah aktif tetap digunakan untuk inference. Scheduler, preprocessing aktif, dan training aktif tetap tidak dijalankan.
Endpoint jobs menerima opsi commodities (array slug), start_date, dan end_date. Jika rentang tanggal dipilih, jumlah observasi dihitung otomatis sebagai hasil tanggal yang tersedia dikalikan pasar yang berhasil dibaca. Proses berjalan di background dan dapat dipantau melalui endpoint status job; panel admin menampilkan progress bar. Penghapusan history menghapus log scraping dan baris price_history dengan source = 'siskaperbapo' saja, sehingga data hasil import CSV tetap aman.
Setiap observasi scraping memiliki scraping_log_id, sehingga tombol trash pada baris log menghapus hanya log tersebut dan data yang dihasilkan proses itu. Jika database lama digunakan, application factory otomatis menambahkan kolom dan mengaitkan observasi SISKAPERBAPO lama ke log terakhir.
Konfigurasi scraper:
$env:SISKAPERBAPO_URL="https://siskaperbapo.jatimprov.go.id/harga-komoditas"
$env:SISKAPERBAPO_COMMODITY_PARAM="komoditas"
$env:SISKAPERBAPO_TIMEOUT="30"
$env:SISKAPERBAPO_COMMODITIES="rawit"
Tahap awal scraper dibatasi ke rawit agar tidak mengisi komoditas lain dengan data yang salah apabila halaman sumber mengabaikan parameter komoditas. Tambahkan slug lain setelah URL/parameter sumber sudah diverifikasi. Jika struktur halaman SISKAPERBAPO berubah atau parameter komoditas berbeda, endpoint akan mengembalikan error dan mencatat detailnya sebagai scraping gagal; sistem tidak membuat data sukses palsu.
Untuk mengisi tabel price_history dari CSV penelitian secara manual satu kali:
cd C:\PrediksiHargaCabe\api
C:/Users/alfia/anaconda3/envs/tf_gpu39/python.exe scripts/import_csv_to_mysql.py
Script ini hanya melakukan import manual dan tidak membuat scheduler atau auto-scraping. Jika dijalankan lagi, constraint unik tanggal/komoditas/pasar mencegah duplikat dan nilai akan diperbarui.
Contoh PowerShell:
cd C:\PrediksiHargaCabe\api
$env:DATA_SOURCE="mysql"
$env:MYSQL_DATABASE="prediksicabe"
$env:MYSQL_USER="root"
$env:MYSQL_PASSWORD=""
python main.py
Uji koneksi melalui endpoint:
http://127.0.0.1:8000/api/v1/history?commodity=rawit&market=pasar_tanjung&days=30
Jika response menyatakan tidak ada data, koneksi berhasil tetapi baris harga belum ada untuk kombinasi tersebut. Jika muncul Gagal membaca database MySQL, periksa service MySQL, port, username, password, dan nama database.
Asumsi dan keterbatasan
- Koordinat pada
app/data/markets.jsonberasal dari spesifikasi dan perlu diverifikasi manual sebelum dipakai sebagai titik final peta. keritingmemakaitime_step=14. Config dan H5 yang tersedia untuk Kreongan, Mangli, dan Wirolegi sekarang sudah memiliki input 14 langkah dan dapat dipakai oleh registry.- Folder model Keriting untuk Tanjung dan Tegal Besar tidak lengkap dan dilaporkan pada
/api/v1/health. - Evaluasi model yang tersedia adalah satu hari ke depan. Prediksi 7, 24, dan 30 hari memakai recursive forecasting, sehingga error dapat menumpuk dan tidak boleh dianggap memiliki akurasi satu hari.
- Harga API adalah Rupiah penuh. Scaler/model yang dilatih dalam ribuan Rupiah harus disesuaikan saat artifact inference divalidasi; CSV historis juga harus mengikuti unit yang sama dengan proses training.
- Semua nilai positif yang disimpan ke
price_historymenggunakan Rupiah penuh. Scraper menormalkan nilai sumber yang masih dalam ribuan sebelum menyimpannya; nilai0diperlakukan sebagai data kosong.