import gradio as gr from fastapi import FastAPI from pydantic import BaseModel from huggingface_hub import hf_hub_download, HfApi import joblib import os from datetime import datetime, timedelta import pandas as pd REPO_ID = "GodfreyOwino/NPK_needs_mode2" FILENAME = "npk_needs_model.joblib" UPDATE_FREQUENCY = timedelta(days=1) class InputData(BaseModel): crop_name: str target_yield: float field_size: float ph: float organic_carbon: float nitrogen: float phosphorus: float potassium: float soil_moisture: float def get_latest_model(): try: api = HfApi() remote_info = api.model_info(repo_id=REPO_ID) remote_mtime = remote_info.lastModified cached_path = hf_hub_download(repo_id=REPO_ID, filename=FILENAME) if os.path.exists(cached_path): local_mtime = datetime.fromtimestamp(os.path.getmtime(cached_path)) if datetime.now() - local_mtime < UPDATE_FREQUENCY: print("Using cached model (checked recently)") return joblib.load(cached_path) if remote_mtime > local_mtime: print("Downloading updated model") cached_path = hf_hub_download(repo_id=REPO_ID, filename=FILENAME, force_download=True) else: print("Cached model is up-to-date") else: print("Downloading model for the first time") cached_path = hf_hub_download(repo_id=REPO_ID, filename=FILENAME) except Exception as e: print(f"Error checking/downloading model: {e}") print(f"Error type: {type(e)}") print(f"Error details: {str(e)}") raise Exception("Unable to download or find the model.") return joblib.load(cached_path) def predict(crop_name, target_yield, field_size, ph, organic_carbon, nitrogen, phosphorus, potassium, soil_moisture): try: model = get_latest_model() input_data = { 'crop_name': [crop_name], 'target_yield': [target_yield], 'field_size': [field_size], 'ph': [ph], 'organic_carbon': [organic_carbon], 'nitrogen': [nitrogen], 'phosphorus': [phosphorus], 'potassium': [potassium], 'soil_moisture': [soil_moisture] } input_df = pd.DataFrame(input_data) prediction = model.predict(input_df) results = { 'nitrogen_need': float(prediction[0][0]), 'phosphorus_need': float(prediction[0][1]), 'potassium_need': float(prediction[0][2]), 'organic_matter_need': float(prediction[0][3]), 'lime_need': float(prediction[0][4]) } return results except Exception as e: return {"error": str(e)} iface = gr.Interface( fn=predict, inputs=[ gr.Textbox(label="Crop Name"), gr.Number(label="Target Yield"), gr.Number(label="Field Size"), gr.Number(label="pH"), gr.Number(label="Organic Carbon"), gr.Number(label="Nitrogen"), gr.Number(label="Phosphorus"), gr.Number(label="Potassium"), gr.Number(label="Soil Moisture") ], outputs=gr.JSON(label="Prediction Results"), title="NPK Needs Prediction", description="Enter soil and crop details to predict NPK needs." ) iface.launch()