SIH-Crop-Yield-API / src /test_api.py
AshrafGalibSk's picture
Upload folder using huggingface_hub
bbd5f9c verified
Raw
History Blame Contribute Delete
4.16 kB
#!/usr/bin/env python3
"""
Test FastAPI for crop yield prediction
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import Optional
import json
import subprocess
import tempfile
import os
from datetime import datetime
app = FastAPI(
title="Crop Yield Prediction API",
description="API for predicting crop yields using Random Forest model",
version="1.0.0"
)
class CropPredictionRequest(BaseModel):
year: int = Field(..., description="Crop year (e.g., 2024)", example=2024)
state: str = Field(..., description="State name", example="Punjab")
crop: str = Field(..., description="Crop name", example="Rice")
season: str = Field(..., description="Season", example="Kharif")
area: float = Field(..., description="Area in hectares", example=10.0)
production: float = Field(..., description="Production in tons", example=25.0)
rainfall: Optional[float] = Field(1000.0, description="Annual rainfall in mm", example=1200)
fertilizer: Optional[float] = Field(50.0, description="Fertilizer usage in kg", example=75)
pesticide: Optional[float] = Field(5.0, description="Pesticide usage in kg", example=8)
class CropPredictionResponse(BaseModel):
model: str = Field(..., description="Model used for prediction", example="Random Forest")
predicted_yield: str = Field(..., description="Predicted yield with units", example="2017.7 kg/hectare")
total_expected_production: str = Field(..., description="Total expected production with units", example="20.18 tons")
assessment: str = Field(..., description="Yield assessment", example="Good yield expected")
@app.get("/")
async def root():
return {
"message": "Crop Yield Prediction API. Use /docs for interactive API documentation.",
"version": "1.0.0",
"endpoints": {
"predict": "/predict",
"health": "/health",
"docs": "/docs"
}
}
@app.get("/health")
async def health_check():
# Check if model files exist
model_files_exist = (
os.path.exists("trained_models/preprocessor.pkl") and
os.path.exists("trained_models/random_forest_model.pkl")
)
return {
"status": "healthy",
"timestamp": datetime.now().isoformat(),
"model_loaded": model_files_exist
}
@app.post("/predict", response_model=CropPredictionResponse)
async def predict_yield(request: CropPredictionRequest):
"""
Predict crop yield using the existing CLI tool
"""
try:
# Create input JSON
input_data = {
"year": request.year,
"state": request.state,
"crop": request.crop,
"season": request.season,
"area": request.area,
"production": request.production,
"rainfall": request.rainfall,
"fertilizer": request.fertilizer,
"pesticide": request.pesticide
}
# Use the existing JSON CLI tool
process = subprocess.Popen(
["python3", "crop_yield_predictor.py", "json"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
stdout, stderr = process.communicate(json.dumps(input_data))
if process.returncode != 0:
raise HTTPException(status_code=500, detail=f"Prediction failed: {stderr}")
try:
result = json.loads(stdout)
if "error" in result:
raise HTTPException(status_code=400, detail=result["error"])
return CropPredictionResponse(**result)
except json.JSONDecodeError:
raise HTTPException(status_code=500, detail=f"Invalid response from predictor: {stdout}")
except Exception as e:
raise HTTPException(status_code=500, detail=f"Prediction failed: {str(e)}")
if __name__ == "__main__":
import uvicorn
import os
port = int(os.environ.get("PORT", 8000))
print(f"Starting server on port: {port}")
uvicorn.run(app, host="0.0.0.0", port=port)