Spaces:
Sleeping
Sleeping
| # from fastapi import APIRouter, HTTPException, Query | |
| # from typing import List | |
| # from schemas.prediction_schemas import CropPredictionRequest, FertilizerPredictionRequest | |
| # from services.prediction_services import get_crop_prediction, get_fertilizer_prediction | |
| # from services.market_services import get_market_prediction, _create_features | |
| # from services.marketTracking_services import fetch_market_data | |
| # from schemas.marketTracker_schemas import MarketPriceRequest, MarketPriceData | |
| # from schemas.weather_schemas import WeatherResponse, ForecastResponse, DayForecast | |
| # from services.weather_service import get_weather_data_for_city, AIR_QUALITY_MAP, get_weather_forecast_for_city | |
| # import os | |
| # import joblib | |
| # import pandas as pd | |
| # router = APIRouter() | |
| # MODELS_DIR = 'models' | |
| # models = {} | |
| # # Ensure models dir exists | |
| # if os.path.exists(MODELS_DIR): | |
| # for model_file in os.listdir(MODELS_DIR): | |
| # if model_file.endswith('.pkl'): | |
| # commodity_name = model_file.replace('.pkl', '').replace('_', '/') | |
| # models[commodity_name] = joblib.load(os.path.join(MODELS_DIR, model_file)) | |
| # print(f"✅ Model loaded for: {commodity_name}") | |
| # try: | |
| # # Ensure your CSV is accessible | |
| # DF_FULL = pd.read_csv('final_output.csv', parse_dates=['created_at'], index_col='created_at') | |
| # print("✅ Dataset loaded.") | |
| # except FileNotFoundError: | |
| # print("❌ 'final_output.csv' not found. Predictions will fail.") | |
| # DF_FULL = None | |
| # @router.post("/api/predict_crop") | |
| # def predict_crop(request: CropPredictionRequest): | |
| # return get_crop_prediction(request) | |
| # @router.post("/api/predict_fertilizer") | |
| # def predict_fertilizer(request: FertilizerPredictionRequest): | |
| # return get_fertilizer_prediction(request) | |
| # @router.get("/api/predict/{commodity}") | |
| # def predict_commodity_price(commodity: str): | |
| # # result = get_market_prediction(commodity) | |
| # # if "error" in result: | |
| # # raise HTTPException(status_code=404, detail=result["error"]) | |
| # # return result | |
| # if DF_FULL is None: | |
| # raise HTTPException(status_code=500, detail="Server Error: Dataset not loaded.") | |
| # # 2. Check if Model exists (Normalize to Upper Case) | |
| # target_commodity = commodity.upper() | |
| # if target_commodity not in models: | |
| # raise HTTPException(status_code=404, detail=f"Model for '{commodity}' not found.") | |
| # model = models[target_commodity] | |
| # # 3. Check if we have history for this commodity | |
| # df_commodity = DF_FULL[DF_FULL['commodity'].str.upper() == target_commodity] | |
| # if df_commodity.empty: | |
| # raise HTTPException(status_code=404, detail="No historical data found for commodity") | |
| # # 4. Get the last known date | |
| # df_daily = df_commodity.groupby(df_commodity.index).agg({'modal_price': 'mean'}) | |
| # last_known_date = df_daily.index.max() | |
| # # 5. Generate Recent History (for comparison chart) | |
| # # Get last 90 days of actual data | |
| # start_context_date = last_known_date - pd.Timedelta(days=90) | |
| # df_featured = _create_features(df_daily) | |
| # test_df = df_featured.loc[df_featured.index >= start_context_date] | |
| # recent_data = [] | |
| # if not test_df.empty: | |
| # FEATURES = [col for col in test_df.columns if col != 'modal_price'] | |
| # try: | |
| # predictions = model.predict(test_df[FEATURES]) | |
| # for date, actual, pred in zip(test_df.index, test_df['modal_price'], predictions): | |
| # recent_data.append({ | |
| # "date": date.strftime('%Y-%m-%d'), | |
| # "actual_price": float(actual), | |
| # "predicted_price": float(pred) | |
| # }) | |
| # except Exception as e: | |
| # print(f"Warning: Could not generate history validation: {e}") | |
| # # 6. Generate Future Forecast (Calling the helper function correctly!) | |
| # try: | |
| # # HERE IS THE FIX: We pass all 4 arguments required by the helper | |
| # daily_forecast_df = get_market_prediction(model, DF_FULL, target_commodity, last_known_date) | |
| # future_data = [] | |
| # for date, row in daily_forecast_df.iterrows(): | |
| # future_data.append({ | |
| # "date": date.strftime('%Y-%m-%d'), | |
| # "forecast_price": float(row['forecast']) | |
| # }) | |
| # except Exception as e: | |
| # print(f"Forecast Error: {e}") | |
| # raise HTTPException(status_code=500, detail=f"Prediction failed: {str(e)}") | |
| # return { | |
| # "commodity": commodity, | |
| # "recent_data": recent_data, | |
| # "forecast_data": future_data | |
| # } | |
| # @router.post( | |
| # "/api/marketPrice", | |
| # response_model=List[MarketPriceData], | |
| # summary="Fetch Agricultural Market Prices", | |
| # description="Retrieves daily market price data for a specific commodity, state, and APMC over the last 7 days." | |
| # ) | |
| # async def get_market_price(request: MarketPriceRequest): | |
| # market_data = await fetch_market_data(request) | |
| # return market_data | |
| # @router.get("/weather/{city}", response_model=WeatherResponse) | |
| # async def get_current_weather(city: str): | |
| # try: | |
| # weather_data = await get_weather_data_for_city(city) | |
| # current_data = weather_data.get("current", {}) | |
| # location_data = weather_data.get("location", {}) | |
| # air_quality_data = current_data.get("air_quality", {}) | |
| # aqi_index = air_quality_data.get("us-epa-index") | |
| # air_quality_description = AIR_QUALITY_MAP.get(aqi_index, "Unknown") | |
| # response_data = WeatherResponse( | |
| # location_name=location_data.get("name", "N/A"), | |
| # temperature_c=current_data.get("temp_c"), | |
| # condition=current_data.get("condition", {}).get("text", "N/A"), | |
| # humidity=current_data.get("humidity"), | |
| # wind_kph=current_data.get("wind_kph"), | |
| # cloud=current_data.get("cloud"), | |
| # is_day=current_data.get("is_day"), | |
| # air_quality=air_quality_description | |
| # ) | |
| # return response_data | |
| # except HTTPException as e: | |
| # raise e | |
| # except Exception as e: | |
| # raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") | |
| # @router.get("/weather/forecast/{city}", response_model=ForecastResponse, summary="Get Weather Forecast") | |
| # async def get_weather_forecast(city: str, days: int = Query(default=1, ge=1, le=14, description="Number of days to forecast (between 1 and 14).")): | |
| # """ | |
| # Retrieves the weather forecast for a specific city for a given number of days. | |
| # """ | |
| # try: | |
| # forecast_data = await get_weather_forecast_for_city(city, days) | |
| # location_data = forecast_data.get("location", {}) | |
| # forecast_days_raw = forecast_data.get("forecast", {}).get("forecastday", []) | |
| # processed_forecast_days = [] | |
| # for day_data in forecast_days_raw: | |
| # day_details = day_data.get("day", {}) | |
| # processed_day = DayForecast( | |
| # date=day_data.get("date"), | |
| # maxtemp_c=day_details.get("maxtemp_c"), | |
| # mintemp_c=day_details.get("mintemp_c"), | |
| # avgtemp_c=day_details.get("avgtemp_c"), | |
| # condition=day_details.get("condition", {}).get("text", "N/A"), | |
| # daily_chance_of_rain=day_details.get("daily_chance_of_rain", 0), | |
| # avghumidity=day_details.get("avghumidity", 0), | |
| # maxwind_kph=day_details.get("maxwind_kph", 0.0), | |
| # ) | |
| # processed_forecast_days.append(processed_day) | |
| # response_data = ForecastResponse( | |
| # location_name=location_data.get("name", "N/A"), | |
| # forecast_days=processed_forecast_days | |
| # ) | |
| # return response_data | |
| # except HTTPException as e: | |
| # raise e | |
| # except Exception as e: | |
| # raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") | |
| from fastapi import APIRouter, HTTPException, Query, UploadFile, File | |
| from typing import List | |
| from fastapi.responses import RedirectResponse | |
| from schemas.prediction_schemas import CropPredictionRequest, FertilizerPredictionRequest | |
| from services.prediction_services import get_crop_prediction, get_fertilizer_prediction | |
| from services.market_services import get_market_prediction, _create_features | |
| from services.marketTracking_services import fetch_market_data, fetch_historical_market_data | |
| from schemas.marketTracker_schemas import MarketPriceRequest, MarketPriceData | |
| from schemas.weather_schemas import WeatherResponse, ForecastResponse, DayForecast | |
| from services.weather_service import get_weather_data_for_city, AIR_QUALITY_MAP, get_weather_forecast_for_city | |
| from services.disease_service import get_tomato_disease_prediction | |
| import os | |
| import joblib | |
| import pandas as pd | |
| router = APIRouter() | |
| MODELS_DIR = 'models' | |
| models = {} | |
| # Ensure models dir exists | |
| if os.path.exists(MODELS_DIR): | |
| for model_file in os.listdir(MODELS_DIR): | |
| if model_file.endswith('.pkl'): | |
| commodity_name = model_file.replace('.pkl', '').replace('_', '/') | |
| models[commodity_name] = joblib.load(os.path.join(MODELS_DIR, model_file)) | |
| print(f"✅ Model loaded for: {commodity_name}") | |
| try: | |
| # Ensure your CSV is accessible | |
| DF_FULL = pd.read_csv('final_output.csv', parse_dates=['created_at'], index_col='created_at') | |
| print("✅ Dataset loaded.") | |
| except FileNotFoundError: | |
| print("❌ 'final_output.csv' not found. Predictions will fail.") | |
| DF_FULL = None | |
| def root(): | |
| """ | |
| Redirects the root URL to the deployed frontend. | |
| """ | |
| return RedirectResponse(url="https://agro-vision-frontend.vercel.app/") | |
| def predict_crop(request: CropPredictionRequest): | |
| return get_crop_prediction(request) | |
| def predict_fertilizer(request: FertilizerPredictionRequest): | |
| return get_fertilizer_prediction(request) | |
| # @router.get("/api/predict/{commodity}") | |
| # def predict_commodity_price(commodity: str): | |
| # if DF_FULL is None: | |
| # raise HTTPException(status_code=500, detail="Server Error: Dataset not loaded.") | |
| # # 2. Check if Model exists (Normalize to Upper Case) | |
| # target_commodity = commodity.upper() | |
| # if target_commodity not in models: | |
| # raise HTTPException(status_code=404, detail=f"Model for '{commodity}' not found.") | |
| # model = models[target_commodity] | |
| # # 3. Check if we have history for this commodity | |
| # df_commodity = DF_FULL[DF_FULL['commodity'].str.upper() == target_commodity] | |
| # if df_commodity.empty: | |
| # raise HTTPException(status_code=404, detail="No historical data found for commodity") | |
| # # 4. Get the last known date | |
| # df_daily = df_commodity.groupby(df_commodity.index).agg({'modal_price': 'mean'}) | |
| # last_known_date = df_daily.index.max() | |
| # # 5. Generate Recent History (for comparison chart) | |
| # start_context_date = last_known_date - pd.Timedelta(days=90) | |
| # df_featured = _create_features(df_daily) | |
| # test_df = df_featured.loc[df_featured.index >= start_context_date] | |
| # recent_data = [] | |
| # if not test_df.empty: | |
| # FEATURES = [col for col in test_df.columns if col != 'modal_price'] | |
| # try: | |
| # # We try to disable feature check here too just in case | |
| # try: | |
| # model.get_booster().feature_names = None | |
| # except: | |
| # pass | |
| # # Use values here as well to be safe | |
| # input_values = test_df[FEATURES].values | |
| # predictions = model.predict(input_values) | |
| # for date, actual, pred in zip(test_df.index, test_df['modal_price'], predictions): | |
| # recent_data.append({ | |
| # "date": date.strftime('%Y-%m-%d'), | |
| # "actual_price": float(actual), | |
| # "predicted_price": float(pred) | |
| # }) | |
| # except Exception as e: | |
| # print(f"Warning: Could not generate history validation: {e}") | |
| # # 6. Generate Future Forecast | |
| # try: | |
| # # Calls the helper which now correctly returns a DataFrame | |
| # daily_forecast_df = get_market_prediction(model, DF_FULL, target_commodity, last_known_date) | |
| # future_data = [] | |
| # # YOUR ORIGINAL LOOP NOW WORKS BECAUSE IT'S A DATAFRAME AGAIN | |
| # for date, row in daily_forecast_df.iterrows(): | |
| # future_data.append({ | |
| # "date": date.strftime('%Y-%m-%d'), | |
| # "forecast_price": float(row['forecast']) | |
| # }) | |
| # except Exception as e: | |
| # print(f"Forecast Error: {e}") | |
| # raise HTTPException(status_code=500, detail=f"Prediction failed: {str(e)}") | |
| # # Returns the exact structure your frontend expects | |
| # return { | |
| # "commodity": commodity, | |
| # "recent_data": recent_data, | |
| # "forecast_data": future_data | |
| # } | |
| def predict_commodity_price(commodity: str): | |
| # result = get_market_prediction(commodity) | |
| # if "error" in result: | |
| # raise HTTPException(status_code=404, detail=result["error"]) | |
| # return result | |
| if DF_FULL is None: | |
| raise HTTPException(status_code=500, detail="Server Error: Dataset not loaded.") | |
| # 2. Check if Model exists (Normalize to Upper Case) | |
| target_commodity = commodity.upper() | |
| if target_commodity not in models: | |
| raise HTTPException(status_code=404, detail=f"Model for '{commodity}' not found.") | |
| model = models[target_commodity] | |
| # 3. Check if we have history for this commodity | |
| df_commodity = DF_FULL[DF_FULL['commodity'].str.upper() == target_commodity] | |
| if df_commodity.empty: | |
| raise HTTPException(status_code=404, detail="No historical data found for commodity") | |
| # 4. Get the last known date | |
| df_daily = df_commodity.groupby(df_commodity.index).agg({'modal_price': 'mean'}) | |
| last_known_date = df_daily.index.max() | |
| # 5. Generate Recent History (for comparison chart) | |
| # Get last 90 days of actual data | |
| start_context_date = last_known_date - pd.Timedelta(days=90) | |
| df_featured = _create_features(df_daily) | |
| test_df = df_featured.loc[df_featured.index >= start_context_date] | |
| recent_data = [] | |
| if not test_df.empty: | |
| FEATURES = [col for col in test_df.columns if col != 'modal_price'] | |
| try: | |
| predictions = model.predict(test_df[FEATURES]) | |
| for date, actual, pred in zip(test_df.index, test_df['modal_price'], predictions): | |
| recent_data.append({ | |
| "date": date.strftime('%Y-%m-%d'), | |
| "actual_price": float(actual), | |
| "predicted_price": float(pred) | |
| }) | |
| except Exception as e: | |
| print(f"Warning: Could not generate history validation: {e}") | |
| # 6. Generate Future Forecast (Calling the helper function correctly!) | |
| try: | |
| # HERE IS THE FIX: We pass all 4 arguments required by the helper | |
| print(model, DF_FULL, target_commodity, last_known_date) | |
| daily_forecast_df = get_market_prediction(model, DF_FULL, target_commodity, last_known_date) | |
| print(daily_forecast_df) | |
| future_data = [] | |
| for date, row in daily_forecast_df.iterrows(): | |
| future_data.append({ | |
| "date": date.strftime('%Y-%m-%d'), | |
| "forecast_price": float(row['forecast']) | |
| }) | |
| except Exception as e: | |
| print(f"Forecast Error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Prediction failed: {str(e)}") | |
| return { | |
| "commodity": commodity, | |
| "recent_data": recent_data, | |
| "forecast_data": future_data | |
| } | |
| async def get_market_price(request: MarketPriceRequest): | |
| market_data = await fetch_market_data(request) | |
| return market_data | |
| async def get_current_weather(city: str): | |
| try: | |
| weather_data = await get_weather_data_for_city(city) | |
| current_data = weather_data.get("current", {}) | |
| location_data = weather_data.get("location", {}) | |
| air_quality_data = current_data.get("air_quality", {}) | |
| aqi_index = air_quality_data.get("us-epa-index") | |
| air_quality_description = AIR_QUALITY_MAP.get(aqi_index, "Unknown") | |
| response_data = WeatherResponse( | |
| location_name=location_data.get("name", "N/A"), | |
| temperature_c=current_data.get("temp_c"), | |
| condition=current_data.get("condition", {}).get("text", "N/A"), | |
| humidity=current_data.get("humidity"), | |
| wind_kph=current_data.get("wind_kph"), | |
| cloud=current_data.get("cloud"), | |
| is_day=current_data.get("is_day"), | |
| air_quality=air_quality_description | |
| ) | |
| return response_data | |
| except HTTPException as e: | |
| raise e | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") | |
| async def get_weather_forecast(city: str, days: int = Query(default=1, ge=1, le=14, description="Number of days to forecast (between 1 and 14).")): | |
| """ | |
| Retrieves the weather forecast for a specific city for a given number of days. | |
| """ | |
| try: | |
| forecast_data = await get_weather_forecast_for_city(city, days) | |
| location_data = forecast_data.get("location", {}) | |
| forecast_days_raw = forecast_data.get("forecast", {}).get("forecastday", []) | |
| processed_forecast_days = [] | |
| for day_data in forecast_days_raw: | |
| day_details = day_data.get("day", {}) | |
| processed_day = DayForecast( | |
| date=day_data.get("date"), | |
| maxtemp_c=day_details.get("maxtemp_c"), | |
| mintemp_c=day_details.get("mintemp_c"), | |
| avgtemp_c=day_details.get("avgtemp_c"), | |
| condition=day_details.get("condition", {}).get("text", "N/A"), | |
| daily_chance_of_rain=day_details.get("daily_chance_of_rain", 0), | |
| avghumidity=day_details.get("avghumidity", 0), | |
| maxwind_kph=day_details.get("maxwind_kph", 0.0), | |
| ) | |
| processed_forecast_days.append(processed_day) | |
| response_data = ForecastResponse( | |
| location_name=location_data.get("name", "N/A"), | |
| forecast_days=processed_forecast_days | |
| ) | |
| return response_data | |
| except HTTPException as e: | |
| raise e | |
| except Exception as e: | |
| raise HTTPException(status_code=500, detail=f"An unexpected error occurred: {str(e)}") | |
| async def predict_tomato_disease(file: UploadFile = File(...)): | |
| """ | |
| Accepts an image upload and returns bounding boxes and classifications | |
| for tomato leaf diseases. | |
| """ | |
| if not file.content_type.startswith("image/"): | |
| raise HTTPException(status_code=400, detail="Uploaded file must be an image.") | |
| try: | |
| image_bytes = await file.read() | |
| prediction_result = get_tomato_disease_prediction(image_bytes) | |
| return prediction_result | |
| except RuntimeError as re: | |
| raise HTTPException(status_code=503, detail=str(re)) | |
| except Exception as e: | |
| print(f"Disease Prediction Error: {e}") | |
| raise HTTPException(status_code=500, detail=f"Prediction failed: {str(e)}") | |
| async def get_historical_market_price(request: MarketPriceRequest): | |
| market_data = await fetch_historical_market_data(request) | |
| if not market_data: | |
| raise HTTPException(status_code=404, detail="No historical market data found for the given parameters.") | |
| return market_data |