Skip to content

Commit

Permalink
Fix model loading and prediction logic in various APIs; improve error…
Browse files Browse the repository at this point in the history
… handling and update dependencies
  • Loading branch information
vishalnadarge committed Nov 2, 2024
1 parent 168f8c7 commit 5b74354
Show file tree
Hide file tree
Showing 24 changed files with 338 additions and 329 deletions.
10 changes: 5 additions & 5 deletions agro-quiz-app/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/app/globals.css",
"config": "./tailwind.config.js",
"css": "./src/app/globals.css",
"baseColor": "slate",
"cssVariables": true,
"prefix": ""
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils"
"@components": "./src/components",
"@utils": "./src/lib/utils"
}
}
}
16 changes: 13 additions & 3 deletions agro-quiz-app/next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}

module.exports = nextConfig
const nextConfig = {
reactStrictMode: true, // Enables React strict mode
swcMinify: true, // Enables SWC-based minification for faster builds and smaller bundle sizes
images: {
domains: ['example.com'], // Allow images from specific domains
},
experimental: {
appDir: true, // Enables the new Next.js app directory (for Next.js 13+)
},
};

module.exports = nextConfig;

22 changes: 11 additions & 11 deletions agro-quiz-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,23 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"lucide-react": "^0.303.0",
"next": "14.0.4",
"react": "^18",
"react-dom": "^18",
"next": "^14.0.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.12.0",
"react-toastify": "^9.1.3",
"tailwind-merge": "^2.2.0",
"tailwindcss-animate": "^1.0.7"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"eslint": "^8",
"eslint-config-next": "14.0.4",
"postcss": "^8",
"@types/node": "^20.0.0",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"autoprefixer": "^10.4.0",
"eslint": "^8.50.0",
"eslint-config-next": "^14.0.4",
"postcss": "^8.4.0",
"tailwindcss": "^3.3.0",
"typescript": "^5"
"typescript": "^5.0.0"
}
}
4 changes: 3 additions & 1 deletion agro-quiz-app/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
plugins: {
// Tailwind CSS integration
tailwindcss: {},
// Adds vendor prefixes for cross-browser compatibility
autoprefixer: {},
},
}
};
3 changes: 1 addition & 2 deletions agro-quiz-app/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ module.exports = {
'./app/**/*.{ts,tsx}',
'./src/**/*.{ts,tsx}',
],
prefix: "",
theme: {
container: {
center: true,
Expand Down Expand Up @@ -74,4 +73,4 @@ module.exports = {
},
},
plugins: [require("tailwindcss-animate")],
}
};
1 change: 1 addition & 0 deletions agro-quiz-app/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ const config: Config = {
plugins: [],
}
export default config

3 changes: 2 additions & 1 deletion agro-quiz-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@
"name": "next"
}
],
"baseUrl": "./",
"paths": {
"@/*": ["./src/*"]
"@/*": ["src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
Expand Down
43 changes: 14 additions & 29 deletions agrotech-ai-apis/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,32 @@
soil_lab_prompt = (
"As an expert in location-based services and geospatial data, your task is to provide a precise and accurate list of nearby soil testing labs "
"for the specified location. Please return the response in a well-structured JSON format. "
"Each entry should include the lab's name, latitude, longitude, and a direct Google Maps link for easy navigation. "
"Each entry should include the lab's name, latitude, longitude, and a direct Google Maps link for easy navigation."
)

ee_shop_prompt = (
"As an expert in location-based services and geospatial data, your task is to provide a precise and accurate list of nearby electrical and electronics shops "
"for the specified location. Please return the response in a well-structured JSON format. "
"Each entry should include the shop's name, latitude, longitude, and a direct Google Maps link for easy navigation. "
"Each entry should include the shop's name, latitude, longitude, and a direct Google Maps link for easy navigation."
)

# Initialize Flask app
app = Flask(__name__)
CORS(app)

# Function to load Gemini Pro model and get responses
# Load Gemini Pro model
model = genai.GenerativeModel("gemini-pro")
chat = model.start_chat(history=[])

def extract_json(text):
json_pattern = r'\{.*\}|\[.*\]'
match = re.search(json_pattern, text, re.DOTALL)
if match:
return match.group(0)
return None
return match.group(0) if match else None

def get_gemini_response(location, prompt):
full_prompt = prompt + location
full_prompt = f"{prompt} {location}"
response = chat.send_message(full_prompt, stream=True)
response_text = ""
for chunk in response:
response_text += chunk.text
return response_text
return ''.join(chunk.text for chunk in response)

# API route to get soil testing labs based on location
@app.route('/find_soil_labs', methods=['POST'])
Expand All @@ -68,8 +63,7 @@ def find_soil_labs():
return jsonify(soil_labs), 200
except json.JSONDecodeError:
return jsonify({"error": "Error decoding the JSON data."}), 500
else:
return jsonify({"error": "No valid JSON found in the response."}), 500
return jsonify({"error": "No valid JSON found in the response."}), 500

# API route to get nearby electrical and electronics shops based on location
@app.route('/find_ee_shops', methods=['POST'])
Expand All @@ -88,8 +82,7 @@ def find_ee_shops():
return jsonify(ee_shops), 200
except json.JSONDecodeError:
return jsonify({"error": "Error decoding the JSON data."}), 500
else:
return jsonify({"error": "No valid JSON found in the response."}), 500
return jsonify({"error": "No valid JSON found in the response."}), 500

# API route to check mushroom edibility
@app.route("/mushroom_edibility", methods=["POST"])
Expand All @@ -98,32 +91,29 @@ def mushroom_edibility():

# API route to recommend crops based on soil and previous crop information
@app.route('/crop_recommendation', methods=['POST'])
def crop_recommendation():
def crop_recommendation_route():
data = request.json
if not data:
return jsonify({'error': 'No data provided'}), 400

try:
data = request.json
print("Received data:", data) # Debugging: Log received data

# Call the crop recommendation function
result = recommend_crop(data)
return jsonify(result), 200

except Exception as e:
return jsonify({'error': str(e)}), 500

# API route for seed quality prediction
@app.route('/predict_seed_quality', methods=['POST'])
def predict_seed_quality_route():
"""API endpoint for predicting seed quality."""
if 'file' not in request.files:
return jsonify({'error': 'No file provided'}), 400

file = request.files['file']

if not file:
return jsonify({'error': 'No file provided'}), 400

try:
# Call the seed quality prediction function
result = predict_seed_quality(file)
return jsonify(result), 200
except Exception as e:
Expand All @@ -136,7 +126,6 @@ def predict():
return jsonify({"error": "No image part in the request"}), 400

file = request.files['image']

if file.filename == '':
return jsonify({"error": "No image selected for uploading"}), 400

Expand All @@ -148,11 +137,7 @@ def predict():
return jsonify({"error": "Prediction failed"}), 500

class_name = get_class_name(result_index)
if class_name:
return jsonify({"prediction": class_name}), 200
else:
return jsonify({"error": "Invalid class index returned."}), 500

return jsonify({"prediction": class_name}), 200 if class_name else jsonify({"error": "Invalid class index returned."}), 500
except Exception as e:
print(f"Error in /predict: {e}")
return jsonify({"error": "An error occurred during prediction"}), 500
Expand Down
10 changes: 4 additions & 6 deletions agrotech-ai-apis/crop_recommendation.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def recommend_crop(data):

# Prepare data for prediction
input_data = pd.DataFrame([{
"Previous Crop": previous_crop_mapping.get(previous_crop, -1), # Map to integer
"Soil Type": soil_type_mapping.get(soil_type, -1), # Map to integer
"Previous Crop": previous_crop_mapping.get(previous_crop, -1), # Map to integer or -1 if not found
"Soil Type": soil_type_mapping.get(soil_type, -1), # Map to integer or -1 if not found
"Moisture Level": moisture_level,
"Nitrogen (N)": nitrogen,
"Phosphorus (P)": phosphorus,
Expand All @@ -56,10 +56,8 @@ def recommend_crop(data):
# Make prediction
prediction = crop_model.predict(input_data)

if prediction[0] in crop_mapping:
recommended_crop = crop_mapping[prediction[0]]
else:
return {'Recommended Crop': 'No prediction available'}
# Map prediction to crop name
recommended_crop = crop_mapping.get(prediction[0], 'No prediction available')

return {'Recommended Crop': str(recommended_crop)}

Expand Down
10 changes: 6 additions & 4 deletions agrotech-ai-apis/mushroom_edibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,35 +31,37 @@ def check_mushroom_edibility():
}

data_dict = {}

for key, mapping in mappings.items():
value = request.form.get(key)
if value:
mapped_value = mapping.get(value)
data_dict[key] = [mapped_value if mapped_value is not None else None]
else:
raise ValueError(f"Missing value in column: {key} with value {value}")
data_dict[key] = [None]

df = pd.DataFrame(data_dict)

# Load encoders
with open('./models/encoders.pkl', 'rb') as f:
encoders = pickle.load(f)

# Transform using encoders
for col in df.columns:
if col in encoders:
if df[col].isnull().any():
raise ValueError(f"Missing value in column: {col}")
df[col] = encoders[col].transform(df[col])

return jsonify({"edibility": edibility_check(df)})
# Get edibility prediction
edibility_result = edibility_check(df)
return jsonify({"edibility": edibility_result})

except Exception as e:
return jsonify({"error": str(e)})


def edibility_check(df):
with open("./models/model.pkl", "rb") as f:
model = pickle.load(f)

prediction = model.predict(df)
return "Edible" if prediction[0] == 1 else "Poisonous"
18 changes: 13 additions & 5 deletions agrotech-ai-apis/paddy_prediction.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@
model = load_model('models/rice_model.h5', compile=False)

# Class labels for the paddy diseases
modified_class_label = ['Bacterial Leaf Blight', 'Bacterial Leaf Streak', 'Bacterial Panicle Blight', 'Blast',
'Brown Spot', 'Dead Heart', 'Downy Mildew', 'Hispa', 'Normal', 'Tungro']
modified_class_label = [
'Bacterial Leaf Blight', 'Bacterial Leaf Streak', 'Bacterial Panicle Blight', 'Blast',
'Brown Spot', 'Dead Heart', 'Downy Mildew', 'Hispa', 'Normal', 'Tungro'
]

LABEL_DESCRIPTION = [
{
Expand Down Expand Up @@ -87,25 +89,31 @@
]

def preprocess_image(image_path, target_size=(256, 256)):
"""Load and preprocess the image for prediction."""
img = load_img(image_path, target_size=target_size)
img_array = img_to_array(img)
img_array = np.expand_dims(img_array, axis=0)
img_array = tf.cast(img_array / 255.0, tf.float32)
return img_array

def predict_paddy(filepath):
predictions = model.predict(preprocess_image(filepath))
def predict_paddy(image_path):
"""Predict the class of the paddy image."""
processed_image = preprocess_image(image_path)
predictions = model.predict(processed_image)
predicted_class = np.argmax(predictions, axis=1)
return predicted_class[0] # Return the class index

def paddy_prediction(image_path):
"""Main function to handle the prediction logic."""
try:
label_index = predict_paddy(image_path)
label = modified_class_label[label_index]
details = LABEL_DESCRIPTION[label_index]

os.remove(image_path) # Clean up the image after prediction
return {
'prediction': label,
'details': LABEL_DESCRIPTION[label_index]
'details': details
}
except Exception as e:
return {"error": str(e)}
7 changes: 4 additions & 3 deletions agrotech-ai-apis/plant_disease_detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ def model_prediction(image_bytes):
# Load and preprocess the image
image = Image.open(io.BytesIO(image_bytes)).convert('RGB')
image = image.resize((224, 224))
input_arr = np.array(image)
input_arr = np.expand_dims(input_arr, axis=0).astype(np.float32) / 255.0
input_arr = np.array(image, dtype=np.float32) / 255.0 # Normalize the image
input_arr = np.expand_dims(input_arr, axis=0) # Add batch dimension

# Set the tensor for the input
interpreter.set_tensor(input_details[0]['index'], input_arr)
Expand All @@ -47,6 +47,7 @@ def model_prediction(image_bytes):
# Get the output tensor and return the index of the max element
output_data = interpreter.get_tensor(output_details[0]['index'])
return int(np.argmax(output_data))

except Exception as e:
print(f"Error in model_prediction: {e}")
return None
Expand All @@ -55,4 +56,4 @@ def get_class_name(index):
"""Function to get the class name based on the index."""
if index is not None and 0 <= index < len(CLASS_NAMES):
return CLASS_NAMES[index]
return None
return "Unknown Class" # Improved handling for invalid index
Loading

0 comments on commit 5b74354

Please sign in to comment.