Jain-Mayukh commited on
Commit
72a463e
·
0 Parent(s):

Initial commit with large models

Browse files
.gitattributes ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ *.h5 filter=lfs diff=lfs merge=lfs -text
2
+ *.pkl filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Python 3.9
2
+ FROM python:3.9
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Copy requirements and install
8
+ COPY requirements.txt .
9
+ RUN pip install --no-cache-dir -r requirements.txt
10
+
11
+ # Copy the rest of the application
12
+ COPY . .
13
+
14
+ # Create a non-root user (Security requirement for HF Spaces)
15
+ RUN useradd -m -u 1000 user
16
+ USER user
17
+ ENV HOME=/home/user \
18
+ PATH=/home/user/.local/bin:$PATH
19
+
20
+ # Expose the port (Hugging Face expects port 7860)
21
+ EXPOSE 7860
22
+
23
+ # Command to run the app
24
+ CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "7860"]
main.py ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import uvicorn
4
+ import joblib
5
+ import numpy as np
6
+ import pandas as pd
7
+ import tensorflow as tf
8
+ import google.generativeai as genai
9
+ from io import BytesIO
10
+ from PIL import Image
11
+ from fastapi import FastAPI, File, UploadFile
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from pydantic import BaseModel
14
+ from dotenv import load_dotenv
15
+
16
+ # --- CONFIGURATION & SETUP ---
17
+ load_dotenv() # Loads environment variables from .env file
18
+
19
+ app = FastAPI()
20
+
21
+ # CORS Setup
22
+ origins = [
23
+ "http://localhost:3000",
24
+ "https://LeafCompass.onrender.com"
25
+ ]
26
+
27
+ app.add_middleware(
28
+ CORSMiddleware,
29
+ allow_origins=origins,
30
+ allow_credentials=True,
31
+ allow_methods=["*"],
32
+ allow_headers=["*"],
33
+ )
34
+
35
+ # --- LOAD MODELS ---
36
+ print("--- Starting Server & Loading Models ---")
37
+
38
+ # Global variables for models
39
+ disease_model = None
40
+ yield_model = None
41
+ crop_model = None
42
+ fertilizer_model = None
43
+ class_names = {}
44
+
45
+ # 1. Load Plant Disease Model
46
+ try:
47
+ disease_model = tf.keras.models.load_model("./models/plant_disease_prediction_model.h5")
48
+ with open("./models/class_indices.json", "r") as f:
49
+ class_indices = json.load(f)
50
+ # Map indices to names
51
+ class_names = {int(k): v for k, v in class_indices.items()}
52
+ print("✅ Disease Model Loaded.")
53
+ except Exception as e:
54
+ print(f"❌ Error loading disease model: {e}")
55
+
56
+ # 2. Load Yield Prediction Model
57
+ try:
58
+ yield_model = joblib.load("./models/yield_prediction_model.pkl")
59
+ print("✅ Yield Model Loaded.")
60
+ except Exception as e:
61
+ print(f"❌ Error loading yield model: {e}")
62
+
63
+ # 3. Load Crop Recommendation Model
64
+ try:
65
+ crop_model = joblib.load("./models/crop_recommendation_model.pkl")
66
+ print("✅ Crop Model Loaded.")
67
+ except Exception as e:
68
+ print(f"❌ Error loading crop model: {e}")
69
+
70
+ # 4. Load Fertilizer Recommendation Model
71
+ try:
72
+ fertilizer_model = joblib.load("./models/fertilizer_recommendation_model.pkl")
73
+ print("✅ Fertilizer Model Loaded.")
74
+ except Exception as e:
75
+ print(f"❌ Error loading fertilizer model: {e}")
76
+
77
+ # 5. Configure Gemini AI
78
+ GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
79
+
80
+ if GEMINI_API_KEY:
81
+ genai.configure(api_key=GEMINI_API_KEY)
82
+ try:
83
+ # Using standard flash model
84
+ model = genai.GenerativeModel(
85
+ model_name="gemini-1.5-flash",
86
+ system_instruction="""
87
+ You are AgroBot, an intelligent agricultural assistant integrated into the 'AgroAI' web application.
88
+ Your capabilities:
89
+ 1. Diagnose plant diseases based on symptoms described by the user.
90
+ 2. Explain crop yield predictions.
91
+ 3. Recommend fertilizers for specific soil types.
92
+ 4. Suggest crops based on NPK values and climate.
93
+ Guidelines:
94
+ - Keep answers concise (under 3-4 sentences).
95
+ - Use emojis (🌾, 🚜, 🍃).
96
+ - If asked about app features, guide them: Disease -> 'Disease' tab, Yield -> 'Yield' tab.
97
+ """
98
+ )
99
+ chat_session = model.start_chat(history=[])
100
+ print("✅ Gemini AI Connected.")
101
+ except Exception as e:
102
+ print(f"❌ Error configuring Gemini: {e}")
103
+ chat_session = None
104
+ else:
105
+ print("⚠️ Warning: GEMINI_API_KEY not found in .env file.")
106
+ chat_session = None
107
+
108
+
109
+ # --- DATA STRUCTURES (Pydantic Models) ---
110
+
111
+ class YieldInput(BaseModel):
112
+ Rainfall_mm: float
113
+ Temperature_Celsius: float
114
+ Days_to_Harvest: int
115
+ Region: str
116
+ Soil_Type: str
117
+ Crop: str
118
+ Weather_Condition: str
119
+ Fertilizer_Used: bool
120
+ Irrigation_Used: bool
121
+
122
+ class CropInput(BaseModel):
123
+ N: float
124
+ P: float
125
+ K: float
126
+ temperature: float
127
+ humidity: float
128
+ ph: float
129
+ rainfall: float
130
+ state: str
131
+
132
+ class FertilizerInput(BaseModel):
133
+ Temperature: float
134
+ Humidity: float
135
+ Moisture: float
136
+ Soil_Type: str
137
+ Crop_Type: str
138
+ Nitrogen: float
139
+ Potassium: float
140
+ Phosphorous: float
141
+
142
+ class ChatInput(BaseModel):
143
+ message: str
144
+
145
+
146
+ # --- ENDPOINTS ---
147
+
148
+ @app.get("/")
149
+ def ping():
150
+ return {"message": "AgroAI Server is running 🚀"}
151
+
152
+ @app.post("/predict-disease")
153
+ async def predict_disease(file: UploadFile = File(...)):
154
+ if not disease_model:
155
+ return {"error": "Disease model is not loaded."}
156
+
157
+ try:
158
+ # Process Image
159
+ image_data = await file.read()
160
+ image = Image.open(BytesIO(image_data))
161
+ image = image.resize((224, 224))
162
+ image = np.array(image).astype('float32') / 255.0
163
+ img_batch = np.expand_dims(image, 0)
164
+
165
+ # Predict
166
+ predictions = disease_model.predict(img_batch)
167
+ predicted_index = np.argmax(predictions[0])
168
+ confidence = float(np.max(predictions[0]))
169
+
170
+ return {
171
+ "class": class_names.get(predicted_index, "Unknown"),
172
+ "confidence": confidence
173
+ }
174
+ except Exception as e:
175
+ return {"error": str(e)}
176
+
177
+ @app.post("/predict-yield")
178
+ def predict_yield(data: YieldInput):
179
+ if not yield_model:
180
+ return {"error": "Yield model is not loaded."}
181
+
182
+ input_data = pd.DataFrame([data.dict()])
183
+
184
+ # Ensure categorical variables (Region, Soil, Crop) are handled
185
+ # if your model pipeline expects them encoded, ensure input_data is processed here.
186
+
187
+ prediction = yield_model.predict(input_data)
188
+ return {"predicted_yield": float(prediction[0])}
189
+
190
+ @app.post("/recommend-crop")
191
+ def recommend_crop(data: CropInput):
192
+ if not crop_model:
193
+ return {"error": "Crop model is not loaded."}
194
+
195
+ # Note: Ensure 'data.state' is encoded if your model expects a number!
196
+ features = pd.DataFrame([[
197
+ data.N, data.P, data.K,
198
+ data.temperature, data.humidity, data.ph,
199
+ data.rainfall, data.state
200
+ ]], columns=['N_SOIL', 'P_SOIL', 'K_SOIL', 'TEMPERATURE', 'HUMIDITY', 'ph', 'RAINFALL', 'STATE'])
201
+
202
+ prediction = crop_model.predict(features)
203
+ return {"recommended_crop": prediction[0]}
204
+
205
+ @app.post("/recommend-fertilizer")
206
+ def recommend_fertilizer(data: FertilizerInput):
207
+ if not fertilizer_model:
208
+ return {"error": "Fertilizer model is not loaded."}
209
+
210
+ input_df = pd.DataFrame([[
211
+ data.Temperature, data.Humidity, data.Moisture,
212
+ data.Soil_Type, data.Crop_Type,
213
+ data.Nitrogen, data.Potassium, data.Phosphorous
214
+ ]], columns=[
215
+ 'Temperature', 'Humidity', 'Moisture', 'Soil_Type',
216
+ 'Crop_Type', 'Nitrogen', 'Potassium', 'Phosphorous'
217
+ ])
218
+
219
+ prediction = fertilizer_model.predict(input_df)
220
+ return {"recommended_fertilizer": prediction[0]}
221
+
222
+ @app.post("/chat")
223
+ def chat_endpoint(data: ChatInput):
224
+ if not chat_session:
225
+ return {"response": "AI service is currently unavailable. Check API Key."}
226
+
227
+ try:
228
+ response = chat_session.send_message(data.message)
229
+ return {"response": response.text}
230
+ except Exception as e:
231
+ print(f"Gemini Error: {e}")
232
+ return {"response": "I'm having trouble connecting to the network. 📡 Try again later!"}
233
+
234
+ if __name__ == "__main__":
235
+ uvicorn.run(app, host="localhost", port=8000)
models/class_indices.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "0": "Apple___Apple_scab",
3
+ "1": "Apple___Black_rot",
4
+ "2": "Apple___Cedar_apple_rust",
5
+ "3": "Apple___healthy",
6
+ "4": "Blueberry___healthy",
7
+ "5": "Cherry_(including_sour)___Powdery_mildew",
8
+ "6": "Cherry_(including_sour)___healthy",
9
+ "7": "Corn_(maize)___Cercospora_leaf_spot Gray_leaf_spot",
10
+ "8": "Corn_(maize)___Common_rust_",
11
+ "9": "Corn_(maize)___Northern_Leaf_Blight",
12
+ "10": "Corn_(maize)___healthy",
13
+ "11": "Grape___Black_rot",
14
+ "12": "Grape___Esca_(Black_Measles)",
15
+ "13": "Grape___Leaf_blight_(Isariopsis_Leaf_Spot)",
16
+ "14": "Grape___healthy",
17
+ "15": "Orange___Haunglongbing_(Citrus_greening)",
18
+ "16": "Peach___Bacterial_spot",
19
+ "17": "Peach___healthy",
20
+ "18": "Pepper,_bell___Bacterial_spot",
21
+ "19": "Pepper,_bell___healthy",
22
+ "20": "Potato___Early_blight",
23
+ "21": "Potato___Late_blight",
24
+ "22": "Potato___healthy",
25
+ "23": "Raspberry___healthy",
26
+ "24": "Soybean___healthy",
27
+ "25": "Squash___Powdery_mildew",
28
+ "26": "Strawberry___Leaf_scorch",
29
+ "27": "Strawberry___healthy",
30
+ "28": "Tomato___Bacterial_spot",
31
+ "29": "Tomato___Early_blight",
32
+ "30": "Tomato___Late_blight",
33
+ "31": "Tomato___Leaf_Mold",
34
+ "32": "Tomato___Septoria_leaf_spot",
35
+ "33": "Tomato___Spider_mites Two-spotted_spider_mite",
36
+ "34": "Tomato___Target_Spot",
37
+ "35": "Tomato___Tomato_Yellow_Leaf_Curl_Virus",
38
+ "36": "Tomato___Tomato_mosaic_virus",
39
+ "37": "Tomato___healthy"
40
+ }
models/crop_recommendation_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d3443bd71057465e5c3f5e5fd2d80fabba589fe595a41a8eb822fa679c6acc66
3
+ size 4005122
models/fertilizer_recommendation_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a1d55618b485c6a98b0e5e69abd59f9f6d7a4a305567b3c148a96d1f18e271d9
3
+ size 1455442
models/plant_disease_prediction_model.h5 ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bc931f8b2c783adde26ab96f3ab2aea620bf6020794562642a6afcf0d52fdb0d
3
+ size 573701104
models/yield_prediction_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4ac881356666d9ffa79857b79b2b0be767c16d662a2f2ab779060f4de224ff71
3
+ size 418501402
requirements.txt ADDED
Binary file (354 Bytes). View file