ShahzadAli44 commited on
Commit
f3f9af9
·
1 Parent(s): 8ae36de
Files changed (5) hide show
  1. Dockerfile +13 -0
  2. LICENSE +21 -0
  3. app/main.py +119 -0
  4. requirements.txt +7 -0
  5. vercel.json +14 -0
Dockerfile ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Set working directory
4
+ WORKDIR /app
5
+
6
+ # Copy files
7
+ COPY requirements.txt .
8
+ RUN pip install --no-cache-dir -r requirements.txt
9
+
10
+ COPY app ./app
11
+
12
+ # Run the FastAPI server using Uvicorn
13
+ CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860"]
LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Shahzad Ali
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ provided to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
app/main.py ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from tensorflow import keras
2
+ from fastapi import FastAPI, File, UploadFile
3
+ from fastapi.middleware.cors import CORSMiddleware
4
+ import numpy as np
5
+ from io import BytesIO
6
+ from PIL import Image
7
+ import logging
8
+ from huggingface_hub import hf_hub_download
9
+ logging.basicConfig(level=logging.DEBUG)
10
+
11
+ app = FastAPI()
12
+
13
+
14
+ app.add_middleware(
15
+ CORSMiddleware,
16
+ allow_origins=["*"],
17
+ allow_credentials=True,
18
+ allow_methods=["*"],
19
+ allow_headers=["*"],
20
+ )
21
+
22
+ model_path = hf_hub_download(repo_id="ShahzadAli44/rice_cnn", filename="rice_cnn_model.keras")
23
+
24
+
25
+ try:
26
+ MODEL = keras.saving.load_model(model_path)
27
+ logging.info("Model loaded successfully.")
28
+ except Exception as e:
29
+ logging.error(f"Error loading model: {e}")
30
+ MODEL = None
31
+
32
+ CLASS_NAMES = [
33
+ "bacterial_leaf_blight", "brown_spot", "healthy", "leaf_blast",
34
+ "leaf_scald", "narrow_brown_spot", "rice_hispa", "sheath_blight", "tungro"
35
+ ]
36
+
37
+ DISEASE_DETAILS = {
38
+ "bacterial_leaf_blight": {
39
+ "symptoms": "Leaves turn yellow with wet-looking spots that spread and dry out.",
40
+ "treatment": "Use disease-resistant rice seeds. Spray copper-based fungicides. Apply balanced fertilizers with nitrogen and phosphorus."
41
+ },
42
+ "brown_spot": {
43
+ "symptoms": "Small brown spots appear on leaves, which later turn yellow.",
44
+ "treatment": "Use potassium-rich fertilizers. Spray Mancozeb fungicide. Maintain good drainage to avoid water stress."
45
+ },
46
+ "healthy": {
47
+ "symptoms": "Leaves are green and strong, with no signs of disease.",
48
+ "treatment": "No treatment needed. Keep the soil healthy by using compost and balanced fertilizers."
49
+ },
50
+ "leaf_blast": {
51
+ "symptoms": "Leaves get white or gray spots that spread and kill the leaf.",
52
+ "treatment": "Spray Tricyclazole fungicide. Keep the right water level in the field. Use silica-based fertilizers to strengthen plants."
53
+ },
54
+ "leaf_scald": {
55
+ "symptoms": "Leaf edges turn yellow or brown, and the leaf dries up.",
56
+ "treatment": "Use resistant rice varieties. Avoid too much nitrogen fertilizer. Spray Propiconazole fungicide if needed."
57
+ },
58
+ "narrow_brown_spot": {
59
+ "symptoms": "Thin, dark brown streaks appear on leaves.",
60
+ "treatment": "Reduce plant overcrowding. Spray Propiconazole fungicide. Use potassium and phosphorus fertilizers to improve plant health."
61
+ },
62
+ "rice_hispa": {
63
+ "symptoms": "Leaves get white scars and small holes due to insect feeding.",
64
+ "treatment": "Remove infected leaves. Spray Chlorpyrifos insecticide. Keep fields clean to reduce insect attacks."
65
+ },
66
+ "sheath_blight": {
67
+ "symptoms": "White or gray patches appear on the lower part of the plant, leading to weak stems.",
68
+ "treatment": "Keep enough space between plants. Apply Azoxystrobin fungicide. Use compost and phosphorus-rich fertilizers."
69
+ },
70
+ "tungro": {
71
+ "symptoms": "Plants grow slowly, and leaves turn yellow or orange.",
72
+ "treatment": "Use virus-free seedlings. Spray insecticides like Imidacloprid to control pests. Apply nitrogen fertilizers to strengthen plants."
73
+ }
74
+ }
75
+
76
+
77
+ def read_file_as_image(data) -> np.ndarray:
78
+ try:
79
+ image = Image.open(BytesIO(data)).convert("RGB")
80
+ logging.debug(f"Image size: {image.size}")
81
+ return np.array(image)
82
+ except Exception as e:
83
+ logging.error("Error reading image file: %s", str(e))
84
+ raise ValueError("Invalid image data")
85
+
86
+
87
+ @app.get("/")
88
+ def home():
89
+ return {"message": "Agrico API is live!"}
90
+
91
+ @app.post("/predict")
92
+ async def predict(file: UploadFile = File(...)):
93
+ if MODEL is None:
94
+ return {"error": "Model is not loaded properly."}
95
+
96
+ try:
97
+ image_data = await file.read()
98
+ image = read_file_as_image(image_data)
99
+ img_batch = np.expand_dims(image, 0)
100
+ logging.debug(f"Image batch shape: {img_batch.shape}")
101
+
102
+ predictions = MODEL.predict(img_batch)
103
+ logging.debug(f"Predictions: {predictions}")
104
+
105
+ predicted_class = CLASS_NAMES[np.argmax(predictions[0])]
106
+ confidence = np.max(predictions[0])
107
+ if confidence < 0.5:
108
+ return {"error": "The uploaded image does not appear to be a rice crop leaf."}
109
+ disease_details = DISEASE_DETAILS.get(predicted_class, {})
110
+
111
+ return {
112
+ 'class': predicted_class,
113
+ 'confidence': float(confidence),
114
+ 'symptoms': disease_details.get("symptoms", "No symptoms available."),
115
+ 'treatment': disease_details.get("treatment", "No treatment information available.")
116
+ }
117
+ except Exception as e:
118
+ logging.error("Error during prediction: %s", str(e))
119
+ return {"error": "An error occurred while processing the image."}
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ numpy
4
+ pillow
5
+ tensorflow-cpu
6
+ huggingface_hub
7
+ python-multipart
vercel.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "builds": [
3
+ {
4
+ "src": "main.py",
5
+ "use": "@vercel/python"
6
+ }
7
+ ],
8
+ "routes": [
9
+ {
10
+ "src": "/(.*)",
11
+ "dest": "main.py"
12
+ }
13
+ ]
14
+ }