tirta16 commited on
Commit
181924b
·
verified ·
1 Parent(s): 60f63d9

3 API BUAH FRESHLY

Browse files
.gitattributes CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ freshly_saved_model_banana/variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
37
+ freshly_saved_model_mango/variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
38
+ freshly_saved_model_orange/variables/variables.data-00000-of-00001 filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Menggunakan image Python 3.9
2
+ FROM python:3.9
3
+
4
+ # Mengatur direktori kerja
5
+ WORKDIR /code
6
+
7
+ # Menyalin requirements dan menginstalnya
8
+ COPY ./requirements.txt /code/requirements.txt
9
+ RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
10
+
11
+ # Hugging Face Spaces menyarankan untuk membuat user non-root
12
+ RUN useradd -m -u 1000 user
13
+ USER user
14
+ ENV HOME=/home/user \
15
+ PATH=/home/user/.local/bin:$PATH
16
+
17
+ # Pindah ke direktori home user
18
+ WORKDIR $HOME/app
19
+ COPY --chown=user . $HOME/app
20
+
21
+ # Hugging Face Spaces MEWAJIBKAN aplikasi berjalan di port 7860
22
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
freshly_saved_model_banana/keras_metadata.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:be4d385a196ee895a8f75e57d26b7c753d785efd1f562390af025ead2425bd1e
3
+ size 48687
freshly_saved_model_banana/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8a98ab46180a5ff2bec82b47914468f1efcd8a1c760b4037c5c98bf60e52dc93
3
+ size 477488
freshly_saved_model_banana/variables/variables.data-00000-of-00001 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b7a878cee0fe1e50768d947816566eebec30c02b254ac28312612c77972e8232
3
+ size 6147460
freshly_saved_model_banana/variables/variables.index ADDED
Binary file (6.85 kB). View file
 
freshly_saved_model_mango/keras_metadata.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9a8b482b679df62df5a07acbc3c0760a61a9e03a93dd2ac3e5f023db2235a217
3
+ size 48597
freshly_saved_model_mango/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4e2cf97675a1f9ad633f3976de18b2fc355abdb19379a9d9bb43ff1aca39bca9
3
+ size 478335
freshly_saved_model_mango/variables/variables.data-00000-of-00001 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3bbccdfe41a861c5f7ef7cde942bfc9c14901cba82a09ff1e8d89908d655444d
3
+ size 6147420
freshly_saved_model_mango/variables/variables.index ADDED
Binary file (6.85 kB). View file
 
freshly_saved_model_orange/keras_metadata.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4b57fe9ad6f00eb7f3afd29b0dce8a9fa50416a656c7aedd8dcc72f3fd3e2d08
3
+ size 48600
freshly_saved_model_orange/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:021a3bb64a6559007abbc0ddbaf466b6b634a6bfca787822532b8d9775bd2cd7
3
+ size 479457
freshly_saved_model_orange/variables/variables.data-00000-of-00001 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e785bb1c07cf7b2b637cc3de1d7315b46f6c2934286900b3564eb72267e53661
3
+ size 6147420
freshly_saved_model_orange/variables/variables.index ADDED
Binary file (6.85 kB). View file
 
main.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import io
2
+ import numpy as np
3
+ import tensorflow as tf
4
+ from fastapi import FastAPI, File, UploadFile, HTTPException
5
+ from PIL import Image
6
+
7
+ app = FastAPI(
8
+ title="Freshly Universal API",
9
+ description="API untuk mendeteksi kematangan berbagai jenis buah dan sayur",
10
+ version="2.0.0"
11
+ )
12
+
13
+ # 1. Konfigurasi Model & Kelasnya
14
+ # Pastikan nama kelas sesuai dengan urutan saat Anda melatih masing-masing model
15
+ CONFIG = {
16
+ "banana": ['banana_ripe', 'banana_rotten', 'banana_unripe'],
17
+ "mango": ['mango_ripe', 'mango_rotten', 'mango_unripe'],
18
+ "orange": ['orange_ripe', 'orange_rotten', 'orange_unripe'],
19
+ #"chili": ['chili_ripe', 'chili_rotten', 'chili_unripe'],
20
+ #"paprika": ['paprika_ripe', 'paprika_rotten', 'paprika_unripe'],
21
+ #"tomato": ['tomato_ripe', 'tomato_rotten', 'tomato_unripe']
22
+ }
23
+
24
+ IMG_SIZE = (224, 224)
25
+ MEAN = np.array([0.485, 0.456, 0.406])
26
+ STD = np.array([0.229, 0.224, 0.225])
27
+
28
+ # 2. Dictionary untuk menyimpan semua model di RAM
29
+ models = {}
30
+
31
+ # Memuat semua model secara otomatis saat server menyala
32
+ print("Memulai proses pemuatan semua model...")
33
+ for fruit_type in CONFIG.keys():
34
+ model_folder = f"freshly_saved_model_{fruit_type}"
35
+ try:
36
+ print(f" -> Memuat model {fruit_type.upper()} dari {model_folder}...")
37
+ models[fruit_type] = tf.keras.models.load_model(model_folder)
38
+ except Exception as e:
39
+ print(f" [X] Gagal memuat model {fruit_type}: Pastikan folder {model_folder} ada!")
40
+
41
+ print("\nSemua model yang tersedia siap digunakan!")
42
+
43
+ # 3. Fungsi Preprocessing (Bisa dipakai untuk semua model karena format inputnya sama)
44
+ def preprocess_image(image_bytes):
45
+ try:
46
+ img = Image.open(io.BytesIO(image_bytes)).convert('RGB')
47
+ img = img.resize(IMG_SIZE)
48
+ img_array = tf.keras.utils.img_to_array(img)
49
+ img_array = img_array / 255.0
50
+ img_array = (img_array - MEAN) / STD
51
+ img_array = np.expand_dims(img_array, axis=0)
52
+ return img_array
53
+ except Exception as e:
54
+ raise ValueError(f"Gagal memproses gambar: {str(e)}")
55
+
56
+ # 4. Endpoint Dinamis (Menerima parameter jenis buah di URL)
57
+ @app.post("/predict/{fruit_type}")
58
+ async def predict_fruit(fruit_type: str, file: UploadFile = File(...)):
59
+ # Cek apakah jenis buah yang diminta (misal: "apple") ada di daftar kita
60
+ fruit_type = fruit_type.lower()
61
+ if fruit_type not in models:
62
+ raise HTTPException(
63
+ status_code=404,
64
+ detail=f"Model untuk '{fruit_type}' tidak ditemukan. Tersedia: {list(models.keys())}"
65
+ )
66
+
67
+ if not file.content_type.startswith('image/'):
68
+ raise HTTPException(status_code=400, detail="File harus berupa gambar.")
69
+
70
+ try:
71
+ contents = await file.read()
72
+ img_tensor = preprocess_image(contents)
73
+
74
+ # Prediksi menggunakan model yang Sesuai dengan URL
75
+ active_model = models[fruit_type]
76
+ class_names = CONFIG[fruit_type]
77
+
78
+ predictions = active_model.predict(img_tensor)
79
+ pred_index = np.argmax(predictions[0])
80
+ confidence = float(predictions[0][pred_index])
81
+
82
+ return {
83
+ "fruit_type": fruit_type,
84
+ "filename": file.filename,
85
+ "predicted_class": class_names[pred_index],
86
+ "confidence": round(confidence * 100, 2),
87
+ "all_probabilities": {
88
+ class_names[i]: round(float(predictions[0][i]) * 100, 2) for i in range(len(class_names))
89
+ }
90
+ }
91
+ except Exception as e:
92
+ raise HTTPException(status_code=500, detail=str(e))
requirements.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn==0.24.0
3
+ tensorflow-cpu==2.10.0
4
+ Pillow==10.1.0
5
+ python-multipart==0.0.6
6
+ numpy==1.26.2