ShadowGard3n commited on
Commit
9037654
·
1 Parent(s): db023ce

Changes in deployment++

Browse files
Files changed (3) hide show
  1. main.py +1 -0
  2. routes/predictions.py +3 -2
  3. services/market_services.py +10 -12
main.py CHANGED
@@ -12,6 +12,7 @@ origins = [
12
  "http://localhost:5501",
13
  "http://127.0.0.1:5500",
14
  "http://localhost:5500",
 
15
  ]
16
 
17
  app.add_middleware(
 
12
  "http://localhost:5501",
13
  "http://127.0.0.1:5500",
14
  "http://localhost:5500",
15
+ "https://agro-vision-frontend.vercel.app"
16
  ]
17
 
18
  app.add_middleware(
routes/predictions.py CHANGED
@@ -264,7 +264,8 @@ def predict_commodity_price(commodity: str):
264
 
265
  if not test_df.empty:
266
  FEATURES = [col for col in test_df.columns if col != 'modal_price']
267
- # FIX: Use DataFrame with columns for XGBoost
 
268
  X_input = pd.DataFrame(test_df[FEATURES].values, columns=FEATURES, index=test_df.index)
269
 
270
  predictions = model.predict(X_input)
@@ -286,7 +287,7 @@ def predict_commodity_price(commodity: str):
286
  for date, row in daily_forecast_df.iterrows():
287
  price = row['forecast']
288
 
289
- # --- CRITICAL FIX: Handle NaN values to prevent JSON crash ---
290
  if pd.isna(price) or np.isnan(price):
291
  final_price = None
292
  else:
 
264
 
265
  if not test_df.empty:
266
  FEATURES = [col for col in test_df.columns if col != 'modal_price']
267
+
268
+ # FIX: Ensure DataFrame format for XGBoost
269
  X_input = pd.DataFrame(test_df[FEATURES].values, columns=FEATURES, index=test_df.index)
270
 
271
  predictions = model.predict(X_input)
 
287
  for date, row in daily_forecast_df.iterrows():
288
  price = row['forecast']
289
 
290
+ # --- CRITICAL FIX: Handle NaN values safely ---
291
  if pd.isna(price) or np.isnan(price):
292
  final_price = None
293
  else:
services/market_services.py CHANGED
@@ -13,7 +13,7 @@ models = {}
13
  if os.path.exists(MODELS_DIR):
14
  for model_file in os.listdir(MODELS_DIR):
15
  if model_file.endswith('.pkl'):
16
- # Normalize filename to commodity name (handle slash replacement if needed)
17
  commodity_name = model_file.replace('.pkl', '').replace('_', '/')
18
  try:
19
  models[commodity_name] = joblib.load(os.path.join(MODELS_DIR, model_file))
@@ -48,8 +48,8 @@ def _create_features(df):
48
  df['rolling_mean_30'] = df['modal_price'].shift(1).rolling(window=30).mean()
49
  df['rolling_std_30'] = df['modal_price'].shift(1).rolling(window=30).std()
50
 
51
- # Return features. Note: We do NOT dropna here because we need to generate
52
- # features for the future row even if it has NaNs initially.
53
  return df
54
 
55
  def get_market_prediction(model, df_full, commodity, last_known_date):
@@ -69,8 +69,7 @@ def get_market_prediction(model, df_full, commodity, last_known_date):
69
  # 3. Combine history and future placeholder
70
  df_extended = pd.concat([df_daily, future_df])
71
 
72
- # 4. Get the correct list of features from a valid sample
73
- # We take the last 50 valid days to determine feature columns
74
  valid_sample = _create_features(df_daily.tail(50)).dropna()
75
  FEATURES = [col for col in valid_sample.columns if col != 'modal_price']
76
 
@@ -81,25 +80,24 @@ def get_market_prediction(model, df_full, commodity, last_known_date):
81
  # Safety check: ensure we have enough data for 30-day rolling window
82
  if len(subset) < 35: continue
83
 
84
- # Generate features for this specific date
85
  featured_subset = _create_features(subset)
86
 
87
- # Extract the row for the current prediction date
88
  if date not in featured_subset.index: continue
89
  featured_row = featured_subset.loc[[date]]
90
 
91
- # --- CRITICAL FIX START ---
92
- # XGBoost requires a DataFrame with specific column names.
93
- # We explicitly recreate the DataFrame to ensure headers are present.
94
  try:
 
95
  X_input = pd.DataFrame(featured_row[FEATURES].values, columns=FEATURES, index=featured_row.index)
 
96
  prediction = model.predict(X_input)[0]
97
  df_extended.loc[date, 'modal_price'] = prediction
98
  except Exception as e:
99
- # Log error but don't crash the loop immediately
100
  print(f"Prediction error for {date}: {e}")
101
  break
102
- # --- CRITICAL FIX END ---
103
 
104
  daily_forecast_df = df_extended.loc[future_dates].copy()
105
  daily_forecast_df.rename(columns={'modal_price': 'forecast'}, inplace=True)
 
13
  if os.path.exists(MODELS_DIR):
14
  for model_file in os.listdir(MODELS_DIR):
15
  if model_file.endswith('.pkl'):
16
+ # Normalize filename to commodity name
17
  commodity_name = model_file.replace('.pkl', '').replace('_', '/')
18
  try:
19
  models[commodity_name] = joblib.load(os.path.join(MODELS_DIR, model_file))
 
48
  df['rolling_mean_30'] = df['modal_price'].shift(1).rolling(window=30).mean()
49
  df['rolling_std_30'] = df['modal_price'].shift(1).rolling(window=30).std()
50
 
51
+ # CRITICAL: Do NOT dropna() here. We need the future row (which has NaNs) to survive
52
+ # so we can predict it.
53
  return df
54
 
55
  def get_market_prediction(model, df_full, commodity, last_known_date):
 
69
  # 3. Combine history and future placeholder
70
  df_extended = pd.concat([df_daily, future_df])
71
 
72
+ # 4. Determine feature columns from a valid historical sample
 
73
  valid_sample = _create_features(df_daily.tail(50)).dropna()
74
  FEATURES = [col for col in valid_sample.columns if col != 'modal_price']
75
 
 
80
  # Safety check: ensure we have enough data for 30-day rolling window
81
  if len(subset) < 35: continue
82
 
83
+ # Generate features
84
  featured_subset = _create_features(subset)
85
 
86
+ # Get the row for the prediction date
87
  if date not in featured_subset.index: continue
88
  featured_row = featured_subset.loc[[date]]
89
 
90
+ # --- FIX: Ensure strict DataFrame format for XGBoost ---
 
 
91
  try:
92
+ # Reconstruct DataFrame with explicit columns to satisfy XGBoost
93
  X_input = pd.DataFrame(featured_row[FEATURES].values, columns=FEATURES, index=featured_row.index)
94
+
95
  prediction = model.predict(X_input)[0]
96
  df_extended.loc[date, 'modal_price'] = prediction
97
  except Exception as e:
98
+ # If prediction fails, we break. The NaNs will remain and be handled by the route.
99
  print(f"Prediction error for {date}: {e}")
100
  break
 
101
 
102
  daily_forecast_df = df_extended.loc[future_dates].copy()
103
  daily_forecast_df.rename(columns={'modal_price': 'forecast'}, inplace=True)