plantdisease / app.py
AIcoder35235's picture
Update app.py
b3b5b6a verified
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from fastapi.middleware.cors import CORSMiddleware
from transformers import pipeline
from PIL import Image
import base64
import io
import requests
app = FastAPI(title="STOA Plant Disease API")
# --- CORS ---
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# --- MODEL LOADING ---
print("Booting Agricultural Node. Loading MobileNetV2 Plant model...")
# THE FIX: Explicitly borrow the Google MobileNetV2 image processor
pipe = pipeline(
"image-classification",
model="linkanjarad/mobilenet_v2_1.0_224-plant-disease-identification",
image_processor="google/mobilenet_v2_1.0_224"
)
print("Agent Ready!")
# --- REQUEST SCHEMA ---
class PredictRequest(BaseModel):
image: str | None = None
image_url: str | None = None
# --- ENDPOINTS ---
@app.get("/health")
def health_check():
return {"status": "ok"}
@app.post("/predict")
def predict(req: PredictRequest):
try:
img = None
# 1. Handle URL Input (with Super-Human headers)
if req.image_url:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
"Accept": "image/avif,image/webp,image/apng,image/*,*/*;q=0.8",
"Referer": "https://google.com"
}
response = requests.get(req.image_url, stream=True, headers=headers, timeout=10)
if response.status_code != 200:
raise Exception(f"External site blocked us with error: {response.status_code}.")
img = Image.open(response.raw).convert("RGB")
# 2. Handle Base64 Input
elif req.image:
b64_data = req.image
if "," in b64_data:
b64_data = b64_data.split(",")[1]
image_bytes = base64.b64decode(b64_data)
img = Image.open(io.BytesIO(image_bytes)).convert("RGB")
else:
raise HTTPException(status_code=400, detail="Must provide 'image' (base64) or 'image_url'.")
# 3. Execute AI Math
results = pipe(img, top_k=3)
# 4. Format Output for the STOA Marketplace
top_3_list = [{"disease": res["label"], "confidence": round(res["score"], 4)} for res in results]
return {
"prediction": results[0]["label"],
"confidence": round(results[0]["score"], 4),
"top_3": top_3_list
}
except Exception as e:
raise HTTPException(status_code=400, detail=f"Failed to process leaf: {str(e)}")