| import warnings
|
| import io
|
| from fastapi import FastAPI, UploadFile, File, HTTPException
|
| from pydantic import BaseModel
|
| from PIL import Image
|
| from fastai.learner import load_learner
|
| import joblib
|
|
|
| from models_download import download_models
|
|
|
| app = FastAPI()
|
|
|
| learn = None
|
|
|
| def read_imagefile(data):
|
| return Image.open(io.BytesIO(data))
|
|
|
|
|
| def load_model_safely():
|
| """Load the FastAI model with proper warning handling"""
|
| try:
|
| with warnings.catch_warnings():
|
| warnings.filterwarnings("ignore", category=UserWarning, message=".*load_learner.*")
|
| learn = load_learner("crop_disease_model.pkl")
|
| return learn
|
| except FileNotFoundError:
|
| print("Warning: Model file 'crop_disease_model.pkl' not found. Please ensure the model file exists.")
|
| return None
|
| except Exception as e:
|
| print(f"Error loading model: {e}")
|
| return None
|
|
|
| disease_info = {
|
| "Wheat__Healthy": {
|
| "crop": "Wheat",
|
| "description": "Healthy wheat plant without any visible disease symptoms.",
|
| "symptoms": [],
|
| "treatment": [],
|
| "prevention": [
|
| "Maintain balanced soil fertility",
|
| "Ensure proper irrigation",
|
| "Use certified disease-free seeds"
|
| ]
|
| },
|
| "Wheat__Brown_Rust": {
|
| "crop": "Wheat",
|
| "description": "Brown rust is caused by Puccinia triticina, a major foliar disease of wheat.",
|
| "symptoms": [
|
| "Small, circular to oval brown pustules on leaves",
|
| "Yellowing around lesions",
|
| "Reduced grain yield and quality"
|
| ],
|
| "treatment": [
|
| "Apply fungicides such as Propiconazole or Tebuconazole",
|
| "Early spray during initial infection"
|
| ],
|
| "prevention": [
|
| "Plant resistant wheat varieties",
|
| "Destroy volunteer wheat plants (green bridge)",
|
| "Rotate crops to break pathogen cycle"
|
| ]
|
| },
|
|
|
| "Rice__Healthy": {
|
| "crop": "Rice",
|
| "description": "Healthy rice plant with no disease or insect damage.",
|
| "symptoms": [],
|
| "treatment": [],
|
| "prevention": [
|
| "Use disease-free seeds",
|
| "Ensure balanced fertilizer application",
|
| "Maintain proper water management"
|
| ]
|
| },
|
| "Rice__Leaf_Blast": {
|
| "crop": "Rice",
|
| "description": "Leaf blast caused by Magnaporthe oryzae affects rice leaves.",
|
| "symptoms": [
|
| "Diamond-shaped lesions on leaves",
|
| "Grayish centers with brown borders",
|
| "Rapid drying of leaves in severe cases"
|
| ],
|
| "treatment": [
|
| "Apply fungicides such as Tricyclazole or Isoprothiolane",
|
| "Remove infected plants to reduce spread"
|
| ],
|
| "prevention": [
|
| "Grow resistant rice varieties",
|
| "Avoid excess nitrogen fertilizer",
|
| "Ensure proper spacing to reduce humidity"
|
| ]
|
| },
|
| "Rice__Neck_Blast": {
|
| "crop": "Rice",
|
| "description": "Neck blast affects the panicle neck, caused by Magnaporthe oryzae.",
|
| "symptoms": [
|
| "Blackening and rotting at panicle neck",
|
| "Panicles dry prematurely",
|
| "Grain filling is reduced or absent"
|
| ],
|
| "treatment": [
|
| "Spray fungicides at heading stage (Tricyclazole, Carbendazim)",
|
| "Destroy infected residues"
|
| ],
|
| "prevention": [
|
| "Cultivate resistant varieties",
|
| "Balanced fertilizer use",
|
| "Crop rotation with non-host crops"
|
| ]
|
| },
|
|
|
| "Potato__Healthy": {
|
| "crop": "Potato",
|
| "description": "Healthy potato leaf without disease or pest damage.",
|
| "symptoms": [],
|
| "treatment": [],
|
| "prevention": [
|
| "Plant certified seed potatoes",
|
| "Follow crop rotation",
|
| "Maintain field hygiene"
|
| ]
|
| },
|
| "Potato__Late_Blight": {
|
| "crop": "Potato",
|
| "description": "Late blight, caused by Phytophthora infestans, is a devastating potato disease.",
|
| "symptoms": [
|
| "Dark brown to black lesions on leaves with pale green halos",
|
| "White fungal growth under moist conditions",
|
| "Tuber rot in severe cases"
|
| ],
|
| "treatment": [
|
| "Apply fungicides such as Mancozeb or Metalaxyl",
|
| "Remove and destroy infected plants"
|
| ],
|
| "prevention": [
|
| "Plant resistant potato varieties",
|
| "Avoid overhead irrigation",
|
| "Ensure proper crop rotation"
|
| ]
|
| },
|
| "Potato__Early_Blight": {
|
| "crop": "Potato",
|
| "description": "Early blight, caused by Alternaria solani, is a common fungal disease of potato.",
|
| "symptoms": [
|
| "Small dark brown spots with concentric rings on leaves",
|
| "Premature leaf drop",
|
| "Reduced tuber yield"
|
| ],
|
| "treatment": [
|
| "Apply fungicides like Chlorothalonil or Copper-based sprays",
|
| "Remove infected leaves early"
|
| ],
|
| "prevention": [
|
| "Use resistant varieties",
|
| "Practice crop rotation",
|
| "Avoid excessive nitrogen fertilizer"
|
| ]
|
| }
|
| }
|
|
|
|
|
| @app.on_event("startup")
|
| def startup_event():
|
| global learn
|
| download_models()
|
| learn = load_model_safely()
|
|
|
|
|
| @app.get("/")
|
| def read_root():
|
| return {
|
| "message": "Welcome to AgroAI - Crop Disease Detection API",
|
| "status": "running",
|
| "model_loaded": learn is not None
|
| }
|
|
|
|
|
| @app.post("/predict/")
|
| async def predict(file: UploadFile = File(...)):
|
| if learn is None:
|
| raise HTTPException(
|
| status_code=503,
|
| detail="Model not available. Please check server configuration."
|
| )
|
|
|
| if not file.content_type or not file.content_type.startswith("image/"):
|
| raise HTTPException(
|
| status_code=400,
|
| detail="File must be an image"
|
| )
|
|
|
| try:
|
|
|
| image_data = await file.read()
|
| img = read_imagefile(image_data)
|
|
|
|
|
| pred, pred_idx, probs = learn.predict(img)
|
| pred_str = str(pred)
|
|
|
| info = disease_info.get(pred_str, {
|
| "crop": "",
|
| "description": "",
|
| "symptoms": [pred, pred_idx],
|
| "treatment": [],
|
| "prevention": []
|
| })
|
| 0
|
| return {
|
| "prediction": pred_str,
|
| "confidence": float(probs[pred_idx]),
|
| "filename": file.filename,
|
| **info
|
| }
|
|
|
| except Exception as e:
|
| raise HTTPException(
|
| status_code=500,
|
| detail=f"Error processing image: {str(e)}"
|
| )
|
|
|